Kubernetes中pod詳解

1、Namespace

1)Namespace概述
Namespace是對一組資源和對象的抽象集合,好比能夠用來將系統內部的對象劃分爲不一樣的項目組或用戶組。常見的pods, services, replication controllers和deployments等都是屬於某一個namespace的(默認是default),而node, persistentVolumes等則不屬於任何namespace。node

Namespace經常使用來隔離不一樣的用戶,好比Kubernetes自帶的服務通常運行在kube-system namespace中。linux

Kubernetes中的名稱空間與docker中的名稱空間不一樣。K8s中的名稱空間只是作了一個邏輯上的隔離web

2)Namespace經常使用的命令
查詢:docker

[root@master ~]# kubectl  get  namespaces   //查看k8s存在的名稱空間
NAME              STATUS   AGE
default           Active   5d4h
kube-node-lease   Active   5d4h
kube-public       Active   5d4h
kube-system       Active   5d4h
[root@master ~]# kubectl  describe namespaces default   //查看名稱空間詳細信息
[root@master ~]# kubectl get pod --namespace=default 
[root@master ~]# kubectl get pod -n default 
//查看default名稱空間中的pod資源(二者均可以)
[root@master ~]# kubectl get pod
//若是不指定,則默認也是查看default名稱空間中的資源

建立、刪除:vim

[root@master ~]# kubectl create namespace beijing
//建立一個名稱空間,名稱爲beijing
//建立完成後,能夠經過「kubectl get namespaces」命令查看到
[root@master ~]# kubectl  get namespaces     //查看剛建立的一個名稱空間,名稱爲beijing
NAME              STATUS   AGE
beijing           Active   6s
default           Active   5d4h
kube-node-lease   Active   5d4h
kube-public       Active   5d4h
kube-system       Active   5d4h

[root@master ~]# kubectl delete namespace beijing
//刪除新建立的名稱空間

經過使用yaml文件建立名稱空間:api

[root@master ~]# vim namespace.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: test
[root@master ~]# kubectl apply -f namespace.yaml  //生成一個名稱空間
[root@master ~]# kubectl get   namespaces     //查看剛建立的一個名稱空間,名稱爲test
NAME              STATUS   AGE
default           Active   5d4h
kube-node-lease   Active   5d4h
kube-public       Active   5d4h
kube-system       Active   5d4h
test              Active   9s

[root@master ~]# kubectl delete -f namespace.yaml   //刪除名稱空間

注意:
(1)刪除一個名稱空間時會自動刪除全部屬於該namespace的資源;
(2)default和kube-system名稱空間不能夠被刪除;
(3)namespace資源對象僅用於資源對象的隔離,並不能隔毫不同名稱空間的Pod之間的通訊。若是須要隔離Pod之間的通訊可使用網絡策略資源這項功能;網絡

2、Pod詳解

1)什麼是Pod?
在Kubernetes中,最小的管理元素不是一個個獨立的容器,而是Pod,Pod是管理,建立,計劃的最小單元.app

一個Pod就至關於一個共享context的配置組,在同一個context下,應用可能還會有獨立的cgroup隔離機制,一個Pod是一個容器環境下的「邏輯主機」,它可能包含一個或者多個緊密相連的應用,這些應用多是在同一個物理主機或虛擬機上。curl

**Pod 的context能夠理解成多個linux命名空間的聯合**:

* PID 命名空間(同一個Pod中應用能夠看到其它進程);
* 網絡 命名空間(同一個Pod的中的應用對相同的IP地址和端口有權限);
* IPC 命名空間(同一個Pod中的應用能夠經過VPC或者POSIX進行通訊);
* UTS 命名空間(同一個Pod中的應用共享一個主機名稱);

Pod和相互獨立的容器同樣,Pod是一種相對短暫的存在,而不是持久存在的,正如咱們在Pod的生命週期中提到的,Pod被安排到節點上,而且保持在這個節點上直到被終止(根據重啓的設定)或者被刪除,當一個節點死掉以後,節點上運行的全部Pod均會被刪除。ide

2)Pod資源的共享及通訊
Pod中的應用均使用相同的網絡命稱空間及端口,而且能夠經過localhost發現並溝通其餘應用,每一個Pod都有一個扁平化的網絡命稱空間下IP地址,它是Pod能夠和其餘的物理機及其餘的容器進行無障礙通訊的關鍵。

除了定義了在Pod中運行的應用以外,Pod還定義了一系列的共享磁盤,磁盤讓這些數據在容器重啓的時候不會丟失而且能夠將這些數據在Pod中的應用進行共享。

3)Pod的管理
Pod經過提供一個高層次抽象而不是底層的接口簡化了應用的部署及管理,Pod 做爲最小的部署及管理單位,位置管理,拷貝複製,資源共享,依賴關係都是自動處理的。

4)爲何不直接在一個容器上運行全部的程序

1)透明:Pod中的容器對基礎設施可見,使得基礎設施能夠給容器提供服務,例如線程管理和資源監控,這爲用戶提供不少便利;
2)解耦:解除軟件依賴關係,獨立的容器能夠獨立的進行重建和從新發布,Kubernetes 甚至會在未來支持獨立容器的實時更新;
3)易用:用戶不須要運行本身的線程管理器,也不須要關心程序的信號以及異常結束碼等;
4)高效:由於基礎設施承載了更多的責任,因此容器能夠更加高效;

總之就是一句話:若是說運行多個服務,其中一個服務出現問題,那麼就需重啓整個Pod,與docker這種容器化的初衷是違背的!

注:實驗操做以前先簡單搭建個registry私有倉庫

[root@master ~]#  docker pull registry:2
[root@master ~]# docker run -itd --name registry --restart=always  -p 5000:5000 -v /registry:/var/lib/registry registry:2
[root@master ~]# docker pull httpd
[root@master ~]# docker tag  httpd 192.168.45.129:5000/httpd:v1   //更改鏡像的名稱作一個簡單的區別
[root@master ~]# docker tag  httpd 192.168.45.129:5000/httpd:v2
[root@master ~]# docker tag  httpd 192.168.45.129:5000/httpd:v3
[root@master ~]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd    --insecure-registry 192.168.45.129:5000  
[root@master ~]# systemctl  daemon-reload 
[root@master ~]# systemctl  restart  docker.service  
[root@master ~]# docker push 192.168.45.129:5000/httpd:v1
[root@master ~]# docker push 192.168.45.129:5000/httpd:v2
[root@master ~]# docker push 192.168.45.129:5000/httpd:v3

5)手動建立Pod(不使用控制器)

**建立pod時鏡像獲取策略:**
* Always: 鏡像標籤爲"latest"或鏡像標籤不存在時,老是從指定的倉庫中獲取鏡像。
* IfNotPresent:僅當本地鏡像不存在時才從目標倉庫中下載。也就意味着,若是本地存在,直接使用本地鏡像,無需再聯網下載。
* Never: 禁止從倉庫中下載鏡像,即只使用本地鏡像。

三種狀態,在建立時能夠任意指定!

[root@master ~]# kubectl create namespace test
//建立一個名爲test的名稱空間(不是必須的)

[root@master ~]# vim pod.yaml
kind: Pod
apiVersion: v1
metadata:
  name: test-pod
  namespace: test             //指定其所在的名稱空間
spec:
  containers:
  - name: test-app
    image: 192.168.45.129:5000/httpd:v1  //指定選用的鏡像

[root@master ~]# kubectl apply -f pod.yaml  //根據yaml文件生成所需的Pod
[root@master ~]# kubectl  get  pod -n test
NAME       READY   STATUS    RESTARTS   AGE
test-pod   1/1     Running   0          13s
//須要指定名稱空間進行查看(不然默認狀況下在default名稱空間下查找)

注意:對於標籤爲latest或者不存在時,其默認的下載策略爲Always,而對於其餘標籤的鏡像,默認策略爲IfNotPresent。

//將上述Pod資源的鏡像下載策略改成IfNotPresent.

[root@master ~]# vim pod.yaml 
kind: Pod
apiVersion: v1
metadata:
  name: test-pod
  namespace: test
  labels:
    name: test-web
spec:
  containers:
  - name: test-app
    image: 192.168.45.129:5000/httpd:v1
    imagePullPolicy: IfNotPresent           //指定pod鏡像的策略
    ports:
    - protocol: TCP
      containerPort: 80     //只是一個聲明,沒有任何做用

[root@master ~]# kubectl delete -f pod.yaml          
//須要將本來的刪除不然沒法進行下載          
[root@master ~]# kubectl apply -f pod.yaml 
//從新指定yaml文件進行下載

建立一個service進行關聯

[root@master ~]# vim pod-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: test-svc
  namespace: test
spec:
  selector:
    name: test-web
  ports:
  - port: 80
    targetPort: 80                 //注意這個端口時生效的,即便是錯誤的
[root@master ~]# kubectl apply -f pod-svc.yaml 
[root@master ~]# kubectl get svc -n test
NAME       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
test-svc   ClusterIP   10.108.187.128   <none>        80/TCP    35s
[root@master ~]# curl 10.108.187.128           //訪問測試
bjq

若是訪問不到,

[root@master ~]# kubectl describe svc -n test 
//查看service的詳細信息,找到Endpoints字段便可發現

Kubernetes中pod詳解

6)pod的重啓策略

**Pod的重啓策略:**
* Always: 但凡Pod對象終止就將其重啓,此爲默認設定。
* OnFailure: 僅在Pod對象出現錯誤時纔將其重啓。
* Never: 從不重啓。

三種狀態,在建立時能夠任意指定!

經過一個小案例進行查看:

[root@master ~]# vim cache.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: healcheck
  name:  healcheck
spec:
  restartPolicy: OnFailure                //重啓策略
  containers:
  - name:  healcheck
    image: busybox:latest
    args:                           //啓動pod時執行的命令
    - /bin/sh
    - -c
    - sleep 10; exit 1

[root@master ~]# kubectl apply -f cache.yaml 
//生成pod
[root@master ~]# kubectl  get  pod -w
NAME        READY   STATUS    RESTARTS   AGE
healcheck   1/1     Running   1          18s
healcheck   0/1     Error     1          26s
healcheck   0/1     CrashLoopBackOff   1          40s
healcheck   1/1     Running            2          42s
healcheck   0/1     Error              2          52s
healcheck   0/1     CrashLoopBackOff   2          65s
healcheck   1/1     Running            3          79s
healcheck   0/1     Error              3          89s
//此時能夠看出指定的重啓策略已經生效

3、Pod的健康檢查

1)容器探針
爲了確保容器在部署後確實處於正常運行狀態,Kubernetes提供了兩種探針來探測容器的狀態:

* LivenessProbe: 存活探針,指容器是否正在運行。若是檢測失敗,則kubelet會殺死容器,而且容器會受重啓策略的影響決定是否須要重啓;
* ReadnessProbe: 就緒探針,指容器是否準備就緒,接受服務請求。若是就緒探針失敗,端點控制器將從與Pod匹配的全部service的端點中移除該Pod的IP 地址;

2)LivenessProbe探針配置

[root@master yaml]# cat liveness.yaml 
kind: Pod
apiVersion: v1
metadata:
  name: liveness
  labels:
    test: liveness
spec:
  restartPolicy: OnFailure
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/test; sleep 60; rm -rf /tmp/test; sleep 300
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/test
      initialDelaySeconds: 10
      periodSeconds: 5

[root@master yaml]# kubectl  apply  -f liveness.yaml  
pod/liveness created
[root@master yaml]# kubectl  get  pod -w
NAME       READY   STATUS              RESTARTS   AGE
liveness   0/1     ContainerCreating   0          1s
liveness   1/1     Running             0          17s
liveness   1/1     Running             1          2m18s
//上述yaml文件中針對/tmp/test這個文件進行指定了健康檢查策略爲 livenessProbe,而且指定了重啓策略爲OnFailure。這樣容器能夠正常的運行,可是老是會重啓。

注: Liveness活躍度探測,根據探測某個文件是否存在,來確認某個服務是否正常運行,若是存在則正常,不然,它會根據你設置的Pod的重啓策略操做Pod。

3)ReadinessProbe探針配置
配置幾乎是如出一轍的,只是健康檢測的方式更換一下,以下:

[root@master yaml]# cat readiness.yaml 
kind: Pod
apiVersion: v1
metadata: 
  name: readiness
  labels:
    test: readiness
spec:
  restartPolicy: OnFailure
  containers:
  - name: readiness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/test; sleep 60; rm -rf /tmp/test; sleep 300
    readinessProbe:
      exec:
        command:
        - cat
        - /tmp/test
      initialDelaySeconds: 10
      periodSeconds: 5

[root@master yaml]# kubectl  apply  -f readiness.yaml 
[root@master yaml]# kubectl  get  pod -w
NAME        READY   STATUS              RESTARTS   AGE
readiness   0/1     ContainerCreating   0          4s
readiness   0/1     Running             0          17s
readiness   1/1     Running             0          26s
readiness   0/1     Running             0          91s

注:總結liveness和 readiness兩種探測的區別:

1)liveness和readiness是兩種健康檢查機制,若是不特地配置,k8s將兩種探測採起相同的默認
行爲,即經過判斷容器啓動進程的返回值是否爲零,來判斷探測是否成功。

2)兩種探測配置方法徹底同樣,不一樣之處在於探測失敗後的行爲:liveness探測是根據Pod重啓策
略操做容器,大多數是重啓容器。readiness則是將容器設置爲不可用,不接收Service轉發的請求。

3)兩種探測方法能夠獨立存在,也能夠同時使用。用liveness判斷容器是否須要重啓實現自愈;
用readiness判斷容器是否已經準備好對外提供服務

5)健康檢測的應用
如下主要應用是在scale(擴容、縮容)、更新(升級)過程當中使用。
一)、

[root@master yaml]# cat app.v1.yaml 
//版本1的yaml文件建立10個副本使用busybox鏡像,以下
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 10
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        image: busybox
        args:
        - /bin/sh
        - -c
        - sleep 10; touch /tmp/healthy; sleep 3000
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 10
          periodSeconds: 5

//編寫完成後退出便可

[root@master yaml]# kubectl apply -f app.v1.yaml --record 
//使用yaml文件生成相應的資源,而且記錄歷史版本信息

查看pod信息,如圖:
Kubernetes中pod詳解
二)、

[root@master yaml]# cat app.v2.yaml 
//版本2的yaml文件建立10個副本使用busybox鏡像
//並模擬(代碼中有問題,並進行升級),以下:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
spec:
  strategy:
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 2
  replicas: 10
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        image: busybox
        args:
        - /bin/sh
        - -c
        - sleep 3000
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 10
          periodSeconds: 5

//maxSurge:此參數控制滾動更新過程當中,副本總數超過預期數的值,能夠是整數,也能夠是百分比。默認是1
//maxUnavailable:不可用Pod的值,默認爲1,能夠是整數,也能夠是百分比

[root@master yaml]# kubectl apply -f app.v2.yamll --record

查看pod信息,如圖:
Kubernetes中pod詳解
注:從圖中能夠看出,一共有12個pod,而且有四個pod是不可用的!由於健康檢查機制在檢查到有問題時,就不會更新了剩餘的pod了!
三)、

[root@master yaml]# cat app.v3.yaml 
//版本2的yaml文件建立10個副本使用busybox鏡像
//而且不使用健康檢查機制,以下:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 10
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        image: busybox
        args:
        - /bin/sh
        - -c
        - sleep 3000

[root@master yaml]# kubectl apply -f app.v3.yamll --record

再次查看pod的狀態信息,如圖:
Kubernetes中pod詳解
若是不使用健康檢查機制,就能夠看出及時pod中服務存在問題,也會所有更新!

[root@master yaml]# kubectl rollout history deployment app 
//查看記錄的歷史版本
[root@master yaml]# kubectl rollout undo deployment app --to-revision=1
//回滾到可用的版本

再次查看pod的運行狀態,如圖:
Kubernetes中pod詳解
由此能夠看出pod健康檢查的重要性!

相關文章
相關標籤/搜索