一 Pod生命周期管理 1.1 Pod生命周期 Pod在整個生命周期過程中被系統定義瞭如下各種狀態。 狀態值 描述 Pending API Server已經創建該Pod,且Pod內還有一個或多個容器的鏡像沒有創建,包括正在下載鏡像的過程。 Running Pod內所有容器均已創建,且至少有一個容器處 ...
一 Pod生命周期管理
1.1 Pod生命周期
Pod在整個生命周期過程中被系統定義瞭如下各種狀態。1.2 Pod重啟策略
Pod重啟策略(RestartPolicy)應用於Pod內的所有容器,並且僅在Pod所處的Node上由kubelet進行判斷和重啟操作。當某個容器異常退出或者健康檢查失敗時,kubelet將根據RestartPolicy的設置來進行相應操作。Pod的重啟策略包括Always、OnFailure和Never,預設值為Always。- Always:當容器失效時,由kubelet自動重啟該容器;
- OnFailure:當容器終止運行且退出碼不為0時,由kubelet自動重啟該容器;
- Never:不論容器運行狀態如何,kubelet都不會重啟該容器。
kubelet重啟失效容器的時間間隔以sync-frequency乘以2n來計算,例如1/2/4/8倍等,最長延時5min,並且在成功重啟後的10min後重置該時間。
Pod的重啟策略與控制方式關聯,當前可用於管理Pod的控制器包括ReplicationController、Job、DaemonSet及直接管理kubelet管理(靜態Pod)。 不同控制器的重啟策略限制如下:- RC和DaemonSet:必須設置為Always,需要保證該容器持續運行;
- Job:OnFailure或Never,確保容器執行完成後不再重啟;
- kubelet:在Pod失效時重啟,不論將RestartPolicy設置為何值,也不會對Pod進行健康檢查。
1.3 Pod健康檢查
對Pod的健康檢查可以通過兩類探針來檢查:LivenessProbe和ReadinessProbe。 LivenessProbe探針:用於判斷容器是否存活(running狀態),如果LivenessProbe探針探測到容器不健康,則kubelet將殺掉該容器,並根據容器的重啟策略做相應處理。若一個容器不包含LivenessProbe探針,kubelet認為該容器的LivenessProbe探針返回值用於是“Success”。 ReadineeProbe探針:用於判斷容器是否啟動完成(ready狀態)。如果ReadinessProbe探針探測到失敗,則Pod的狀態將被修改。Endpoint Controller將從Service的Endpoint中刪除包含該容器所在Pod的Eenpoint。 kubelet定期執行LivenessProbe探針來診斷容器的健康狀態,通常有以下三種方式:- ExecAction:在容器內執行一個命令,若返回碼為0,則表明容器健康。
1 [root@uk8s-m-01 study]# vi dapi-liveness.yaml 2 apiVersion: v1 3 kind: Pod 4 metadata: 5 name: dapi-liveness-pod 6 labels: 7 test: liveness-exec 8 spec: 9 containers: 10 - name: dapi-liveness 11 image: busybox 12 args: 13 - /bin/sh 14 - -c 15 - echo ok > /tmp/health; sleep 10; rm -rf /tmp/health; sleep 600 16 livenessProbe: 17 exec: 18 command: 19 - cat 20 - /tmp/health 21 22 [root@uk8s-m-01 study]# kubectl describe pod dapi-liveness-pod
- TCPSocketAction:通過容器的IP地址和埠號執行TCP檢查,若能建立TCP連接,則表明容器健康。
1 [root@uk8s-m-01 study]# vi dapi-tcpsocket.yaml 2 apiVersion: v1 3 kind: Pod 4 metadata: 5 name: dapi-healthcheck-tcp 6 spec: 7 containers: 8 - name: nginx 9 image: nginx 10 ports: 11 - containerPort: 80 12 livenessProbe: 13 tcpSocket: 14 port: 80 15 initialDelaySeconds: 30 16 timeoutSeconds: 1 17 18 [root@uk8s-m-01 study]# kubectl create -f dapi-tcpsocket.yaml提示:對於每種探測方式,都需要設置如下兩個參數,其包含的含義如下: initialDelaySeconds:啟動容器後進行首次健康檢查的等待時間,單位為s; timeoutSeconds:健康檢查發送請求後等待響應的超時時間,單位為s,當超時發生時,kubelet會認為容器已經無法提供服務,將會重啟該容器。
二 Pod調度
Kubernetes中,Pod通常是容器的載體,一般需要通過Deployment、DaemonSet、RC、Job等對象來完成一組Pod的調度與自動控制功能。2.1 Depolyment/RC自動調度
Deployment或RC的主要功能之一就是自動部署一個容器應用的多份副本,以及持續監控副本的數量,在集群內始終維持用戶指定的副本數量。 示例:1 [root@uk8s-m-01 study]# vi nginx-deployment.yaml 2 apiVersion: apps/v1beta1 3 kind: Deployment 4 metadata: 5 name: nginx-deployment-01 6 spec: 7 replicas: 3 8 template: 9 metadata: 10 labels: 11 app: nginx 12 spec: 13 containers: 14 - name: nginx 15 image: nginx:1.7.9 16 ports: 17 - containerPort: 80 18 19 [root@uk8s-m-01 study]# kubectl get deployments 20 NAME READY UP-TO-DATE AVAILABLE AGE 21 nginx-deployment-01 3/3 3 3 30s 22 [root@uk8s-m-01 study]# kubectl get rs 23 NAME DESIRED CURRENT READY AGE 24 nginx-deployment-01-5754944d6c 3 3 3 75s 25 [root@uk8s-m-01 study]# kubectl get pod | grep nginx 26 nginx-deployment-01-5754944d6c-hmcpg 1/1 Running 0 84s 27 nginx-deployment-01-5754944d6c-mcj8q 1/1 Running 0 84s 28 nginx-deployment-01-5754944d6c-p42mh 1/1 Running 0 84s
2.2 NodeSelector定向調度
當需要手動指定將Pod調度到特定Node上,可以通過Node的標簽(Label)和Pod的nodeSelector屬性相匹配。 # kubectl label nodes <node-name> <label-key>=<label-value> node節點創建對應的label後,可通過在定義Pod的時候加上nodeSelector的設置實現指定的調度。 示例:1 [root@uk8s-m-01 study]# kubectl label nodes 172.24.9.14 speed=io 2 node/172.24.9.14 labeled 3 [root@uk8s-m-01 study]# vi nginx-master-controller.yaml 4 kind: ReplicationController 5 metadata: 6 name: nginx-master 7 labels: 8 name: nginx-master 9 spec: 10 replicas: 1 11 selector: 12 name: nginx-master 13 template: 14 metadata: 15 labels: 16 name: nginx-master 17 spec: 18 containers: 19 - name: master 20 image: nginx:1.7.9 21 ports: 22 - containerPort: 80 23 nodeSelector: 24 speed: io 25 26 [root@uk8s-m-01 study]# kubectl create -f nginx-master-controller.yaml 27 [root@uk8s-m-01 study]# kubectl get pods -o wide 28 NAME READY STATUS RESTARTS AGE IP NODE 29 nginx-master-7fjgj 1/1 Running 0 82s 172.24.9.71 172.24.9.14提示:可以將集群中具有不同特點的Node貼上不同的標簽,實現在部署時就可以根據應用的需求設置NodeSelector來進行指定Node範圍的調度。 註意:若在定義Pod中指定了NodeSelector條件,但集群中不存在符合該標簽的Node,即使集群有其他可供使用的Node,Pod也無法被成功調度。
2.3 NodeAffinity親和性調度
親和性調度機制極大的擴展了Pod的調度能力,主要增強功能如下:- 更具表達力,即更精細的力度控制;
- 可以使用軟限制、優先採用等限制方式,即調度器在無法滿足優先需求的情況下,會使用其他次條件進行滿足;
- 可以依據節點上正在運行的其他Pod的標簽來進行限制,而非節點本身的標簽,從而實現Pod之間的親和或互斥關係。
1 [root@uk8s-m-01 study]# vi nodeaffinity-pod.yaml 2 apiVersion: v1 3 kind: Pod 4 metadata: 5 name: with-node-affinity 6 spec: 7 affinity: 8 nodeAffinity: 9 requiredDuringSchedulingIgnoredDuringExecution: 10 nodeSelectorTerms: 11 - matchExpressions: 12 - key: kubernetes.io/arch 13 operator: In 14 values: 15 - amd64 16 preferredDuringSchedulingIgnoredDuringExecution: 17 - weight: 1 18 preference: 19 matchExpressions: 20 - key: disk-type 21 operator: In 22 values: 23 - ssd 24 containers: 25 - name: with-node-affinity 26 image: gcr.azk8s.cn/google_containers/pause:2.0NodeAffinity操作語法;In、NotIn、Exists、DoesNotExist、Gt、Lt。NotIn和DoesNotExist可以實現互斥功能。 NodeAffinity規則設置註意事項:
- 若同時定義nodeSelector和nodeAffinity,則必須兩個條件都滿足,Pod才能最終運行指定在Node上;;
- 若nodeAffinity指定多個nodeSelectorTerms,則只需要其中一個能夠匹配成功即可;
- 若nodeSelectorTerms中有多個matchExpressions,則一個節點必須滿足所有matchExpressions才能運行該Pod。
2.4 PodAffinity親和性調度
PodAffinity根據節點上正在運行的Pod標簽而不是Node標簽來判斷和調度,要求對節點和Pod兩個條件進行匹配。 規則描述為:若在具有標簽X的Node上運行了一個或多個符合條件Y的Pod,則Pod應該(或者不應該)運行在這個Node上。 X通常為Node節點的機架、區域等概念,Pod是屬於某個命名空間,所以條件Y表達的是一個或全部命名空間中的一個Label Selector。 Pod親和性定義與PodSpec的affinity欄位下的podAffinity欄位里,互斥性定義於同一層次的podAntiAffinity子欄位中。 舉例:1 [root@uk8s-m-01 study]# vi nginx-flag.yaml #創建名為pod-flag,帶有兩個標簽的Pod 2 apiVersion: v1 3 kind: Pod 4 metadata: 5 name: pod-affinity 6 spec: 7 affinity: 8 podAffinity: 9 requiredDuringSchedulingIgnoredDuringExecution: 10 - labelSelector: 11 matchExpressions: 12 - key: security 13 operator: In 14 values: 15 - S1 16 topologyKey: kubernetes.io/hostname 17 containers: 18 - name: with-pod-affinity 19 image: gcr.azk8s.cn/google_containers/pause:2.0
1 [root@uk8s-m-01 study]# vi nginx-affinity-in.yaml #創建定義標簽security=S1,對應如上Pod “Pod-flag”。 2 apiVersion: v1 3 kind: Pod 4 metadata: 5 name: pod-affinity 6 spec: 7 affinity: 8 podAffinity: 9 requiredDuringSchedulingIgnoredDuringExecution: 10 - labelSelector: 11 matchExpressions: 12 - key: security 13 operator: In 14 values: 15 - S1 16 topologyKey: kubernetes.io/hostname 17 containers: 18 - name: with-pod-affinity 19 image: gcr.azk8s.cn/google_containers/pause:2.0 20 21 [root@uk8s-m-01 study]# kubectl create -f nginx-affinity-in.yaml 22 [root@uk8s-m-01 study]# kubectl get pods -o wide提示:由上Pod親和力可知,兩個Pod處於同一個Node上。
1 [root@uk8s-m-01 study]# vi nginx-affinity-out.yaml #創建不能與參照目標Pod運行在同一個Node上的調度策略 2 apiVersion: v1 3 kind: Pod 4 metadata: 5 name: anti-affinity 6 spec: 7 affinity: 8 podAffinity: 9 requiredDuringSchedulingIgnoredDuringExecution: 10 - labelSelector: 11 matchExpressions: 12 - key: security 13 operator: In 14 values: 15 - S1 16 topologyKey: failure-domain.beta.kubernetes.io/zone 17 podAntiAffinity: 18 requiredDuringSchedulingIgnoredDuringExecution: 19 - labelSelector: 20 matchExpressions: 21 - key: security 22 operator: In 23 values: 24 - nginx 25 topologyKey: kubernetes.io/hostname 26 containers: 27 - name: anti-affinity 28 image: gcr.azk8s.cn/google_containers/pause:2.0 29 30 [root@uk8s-m-01 study]# kubectl get pods -o wide #驗證
2.5 Taints和Tolerations(污點和容忍)
Taint:使Node拒絕特定Pod運行; Toleration:為Pod的屬性,表示Pod能容忍(運行)標註了Taint的Node。 Taint語法:$ kubectl taint node node1 key=value:NoSchedule 解釋:為node1加上一個Taint,該Taint的鍵為key,值為value,Taint的效果為NoSchedule。即除非特定聲明可以容忍此Taint,否則不會調度至node1上。 Toleration示例:1 tolerations: 2 - key: "key" 3 operator: "Equal" 4 value: "value" 5 effect: "NoSchedule"或
1 tolerations: 2 - key: "key" 3 operator: "Exists" 4 effect: "NoSchedule"註意:Pod的Toleration聲明中的key和effect需要與Taint的設置保持一致,並且滿足以下條件:
- operator的值是Exists(無須指定value);
- operator的值是Equal並且value相等;
- 空的key配合Exists操作符能夠匹配所有的鍵和值;
- 空的effect匹配所有的effect。
1 $ kubectl taint node node1 key=value1:NoSchedule 2 $ kubectl taint node node1 key=value1:NoExecute 3 $ kubectl taint node node1 key=value2:NoSchedule 4 tolerations: 5 - key: "key1" 6 operator: "Equal" 7 value: "value" 8 effect: "NoSchedule" 9 tolerations: 10 - key: "key1" 11 operator: "Equal" 12 value: "value1" 13 effect: "NoExecute"釋義:此Pod聲明瞭兩個容忍,且能匹配Node1的taint,但是由於沒有能匹配第三個taint的toleration,因此此Pod依舊不能調度至此Node。若該Pod已經在node1上運行了,那麼在運行時設置了第3個taint,它還能繼續在node1上運行,這是因為Pod可以容忍前兩個taint。 通常,若node加上effect=NoExecute的taint,那麼該Node上正在運行的所有無對應toleration的Pod都會被立刻驅逐,而具有相應toleration的Pod則永遠不會被驅逐。同時,系統可以給具有NoExecute效果的toleration加入一個可選的tolerationSeconds欄位,表明Pod可以在taint添加到Node之後還能在此Node運行多久。
1 tolerations: 2 - key: "key1" 3 operator: "Equal" 4 value: "value" 5 effect: "NoSchedule" 6 tolerationSeconds: 3600釋義:若Pod正在運行,所在節點被加入一個匹配的taint,則這個pod會持續在該節點運行3600s後被驅逐。若在此期限內,taint被移除,則不會觸發驅逐事件。 Taints和Tolerations常用場景:
- 獨占節點:
- 具有特殊硬體設備的節點