1. 程式人生 > 其它 >k8s-Pod狀態和探針

k8s-Pod狀態和探針

Pod狀態

第一階段:

Pending:
#正在建立Pod但是Pod中的容器還沒有全部被建立完成,處於此狀態的Pod應該檢查Pod依賴的儲存是否有許可權掛載、映象是否可以下載、排程是否正常等。

Failed
#Pod中有容器啟動失敗而導致pod工作異常。檢查事件

Unknown
#由於某種原因無法獲得pod的當前狀態,通常是由於與pod所在的node節點通訊錯誤。

Succeeded
#Pod中的所有容器都被成功終止即pod裡所有的containers均已terminated。

第二階段:

Unschedulable:
#Pod不能被排程,kube-scheduler沒有匹配到合適的node節點

PodScheduled
#pod正處於排程中,在kube-scheduler剛開始排程的時候,還沒有將pod分配到指定的node,在篩選出合適的
節點後就會更新etcd資料,將pod分配到指定的node

Initialized
#所有pod中的初始化容器已經完成了

ImagePullBackOff:
#Pod所在的node節點下載映象失敗

Running
#Pod內部的容器已經被建立並且啟動。

Ready
#表示pod中的容器已經可以提供訪問服務

範例:其他狀態

Error: #pod 啟動過程中發生錯誤
NodeLost: #Pod 所在節點失聯
Unkown: #Pod 所在節點失聯或其它未知異常
Waiting: #Pod 等待啟動
Pending: #Pod 等待被排程
Terminating: #Pod 正在被銷燬
CrashLoopBackOff:#pod,但是kubelet正在將它重啟
InvalidImageName:#node節點無法解析映象名稱導致的映象無法下載
ImageInspectError:#無法校驗映象,映象不完整導致
ErrImageNeverPull:#策略禁止拉取映象,映象中心許可權是私有等
ImagePullBackOff:#映象拉取失敗,但是正在重新拉取
RegistryUnavailable:#映象伺服器不可用,網路原因或harbor宕機
ErrImagePull:#映象拉取出錯,超時或下載被強制終止
CreateContainerConfigError:#不能建立kubelet使用的容器配置
CreateContainerError:#建立容器失敗
PreStartContainer: #執行preStart hook報錯,Pod hook(鉤子)是由 Kubernetes 管理的 kubelet 發
起的,當容器中的程序啟動前或者容器中的程序終止之前執行,比如容器建立完成後裡面的服務啟動之前可以檢查一下
依賴的其它服務是否啟動,或者容器退出之前可以把容器中的服務先通過命令停止。
PostStartHookError:#執行 postStart hook 報錯
RunContainerError:#pod執行失敗,容器中沒有初始化PID為1的守護程序等
ContainersNotInitialized:#pod沒有初始化完畢
ContainersNotReady:#pod沒有準備完畢
ContainerCreating:#pod正在建立中
PodInitializing:#pod正在初始化中
DockerDaemonNotReady:#node節點docker服務沒有啟動
NetworkPluginNotReady:#網路外掛還沒有完全啟動

探針(保證k8s中服務的可用性)

探針 是由 kubelet 對容器執行的定期診斷,以保證Pod的狀態始終處於執行狀態,要執行診斷,kubelet 呼叫由容

兩種都是檢查通過就什麼都不做

器實現的Handler(處理程式),有三種類型的處理程式:

ExecAction
#在容器內執行指定命令,如果命令退出時返回碼為0則認為診斷成功。

TCPSocketAction
#對指定埠上的容器的IP地址進行TCP檢查,如果埠開啟,則診斷被認為是成功的。

HTTPGetAction
#對指定的埠和路徑上的容器的IP地址執行HTTPGet請求,如果響應的狀態碼大於等於200且小於 400,則診斷被認為是成功的。

每次探測都將獲得以下三種結果之一:

成功:容器通過了診斷。
失敗:容器未通過診斷。
未知:診斷失敗,因此不會採取任何行動。

探針型別:

livenessProbe(檢查不通過,就重啟;基於映象還原)
#存活探針,檢測容器容器是否正在執行,如果存活探測失敗,則kubelet會殺死容器,並且容器將受到其重啟策略的影響,如果容器不提供存活探針,則預設狀態為 Success,livenessProbe用於控制是否重啟pod。

readinessProbe(檢查不通過,不會新增到ep,反之)
#就緒探針,如果就緒探測失敗,端點控制器將從與Pod匹配的所有Service的端點中刪除該Pod的IP地址,初始延遲之前的就緒狀態預設為Failure(失敗),如果容器不提供就緒探針,則預設狀態為 Success,readinessProbe用於控制pod是否新增至service。

探針有很多配置欄位,可以使用這些欄位精確的控制存活和就緒檢測的行為:

initialDelaySeconds: 120
#初始化延遲時間,告訴kubelet在執行第一次探測前應該等待多少秒,預設是0秒,最小值是0

periodSeconds: 60
#探測週期間隔時間,指定了kubelet應該每多少秒秒執行一次存活探測,預設是 10 秒。最小值是 1

timeoutSeconds: 5
#單次探測超時時間,探測的超時後等待多少秒,預設值是1秒,最小值是1。

successThreshold: 1
#從失敗轉為成功的重試次數,探測器在失敗後,被視為成功的最小連續成功數,預設值是1,存活探測的這個值必須是1,最小值是 1。

failureThreshold: 3
#從成功轉為失敗的重試次數,當Pod啟動了並且探測到失敗,Kubernetes的重試次數,存活探測情況下的放棄就意味著重新啟動容器,就緒探測情況下的放棄Pod 會被打上未就緒的標籤,預設值是3,最小值是1。

HTTP 探測器可以在 httpGet 上配置額外的欄位:

host:
#連線使用的主機名,預設是Pod的 IP,也可以在HTTP頭中設定 “Host” 來代替。
scheme: http
#用於設定連線主機的方式(HTTP 還是 HTTPS),預設是 HTTP。
path: /monitor/index.html
#訪問 HTTP 服務的路徑。
httpHeaders:
#請求中自定義的 HTTP 頭,HTTP 頭欄位允許重複。
port: 80
#訪問容器的埠號或者埠名,如果數字必須在 1 ~ 65535 之間。

livenessProbe和readinessProbe的對比:

配置引數一樣
livenessProbe #連續探測失敗會重啟、重建pod,readinessProbe不會執行重啟或者重建Pod操作

livenessProbe #連續檢測指定次數失敗後會將容器置於(Crash Loop BackOff)且不可用,readinessProbe不會

readinessProbe #連續探測失敗會從service的endpointd中刪除該Pod,livenessProbe不具備此功能,但是會將容器掛起livenessProbe

livenessProbe使用者控制是否重啟pod,readinessProbe用於控制pod是否新增至service

建議:
兩個探針都配置

這裡都是存活探針的案例

HTTP探針示例:(這是正確的)

[root@k8s-server1 case2]# cat case1.yaml 
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels: #rs or deployment
      app: ng-deploy-80
    #matchExpressions:
    # - {key: app, operator: In, values: [ng-deploy-80,ng-rs-81]}
  template:
    metadata:
      labels:
        app: ng-deploy-80
    spec:
      containers:
      - name: ng-deploy-80
        image: harbor.longxuan.net/n520/nginx:1.18.0
        ports:
        - containerPort: 80
        #readinessProbe:
        livenessProbe:
          httpGet:
            #path: /montic/montic.html
            path: /index.html
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 3
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3

---
apiVersion: v1
kind: Service
metadata:
  name: ng-deploy-80
spec:
  ports:
  - name: http
    port: 86
    targetPort: 80
    nodePort: 30025
    protocol: TCP
  type: NodePort
  selector:
    app: ng-deploy-80

執行

[root@k8s-server1 case2]# kubectl apply -f case1.yaml -n linux66
deployment.apps/nginx-deployment configured
service/ng-deploy-80 unchanged

當開啟不存在的url時,pod將會一直重啟

TCP探針示例

建立(正確的)

[root@k8s-server1 case2]# cat case2.yaml 
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels: #rs or deployment
      app: ng-deploy-80
    #matchExpressions:
    # - {key: app, operator: In, values: [ng-deploy-80,ng-rs-81]}
  template:
    metadata:
      labels:
        app: ng-deploy-80
    spec:
      containers:
      - name: ng-deploy-80
        image: harbor.longxuan.net/n520/nginx:1.18.0
        ports:
        - containerPort: 80
        #readinessProbe:
        livenessProbe:
          tcpSocket:
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 3
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3

---
apiVersion: v1
kind: Service
metadata:
  name: ng-deploy-80
spec:
  ports:
  - name: http
    port: 86
    targetPort: 80
    nodePort: 30026
    protocol: TCP
  type: NodePort
  selector:
    app: ng-deploy-80

執行

[root@k8s-server1 case2]# kubectl apply -f case2.yaml -n linux66
deployment.apps/nginx-deployment created
service/ng-deploy-80 created

當yaml檔案寫錯埠,pod就會被一直重啟,同時服務也訪問不了

[root@k8s-server1 case2]# kubectl get pod -n linux66
NAME                                        READY   STATUS             RESTARTS   AGE
            0          41h
nginx-deployment-69bd984878-nttnp           0/1     CrashLoopBackOff   3          60s

ExecAction探針:

可以基於指定的命令對Pod進行特定的狀態檢查。

# 這是正確的
[root@k8s-server1 case2]# cat case3.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis-deploy-6379
  template:
    metadata:
      labels:
        app: redis-deploy-6379
    spec:
      containers:
      - name: redis-deploy-6379
        image: harbor.longxuan.net/n520/redis:v1
        ports:
        - containerPort: 80
        livenessProbe:
        #readinessProbe:
          exec:
            command:
              #- /app/redis/bin/redis-cli
              - /usr/local/bin/redis-cli
              - quit
          initialDelaySeconds: 5
          periodSeconds: 3
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3

---
apiVersion: v1
kind: Service
metadata:
  name: redis-deploy-6379
spec:
  ports:
  - name: http
    port: 6379
    targetPort: 6379
    nodePort: 30679
    protocol: TCP
  type: NodePort
  selector:
    app: redis-deploy-6379

執行

[root@k8s-server1 case2]# kubectl apply -f case3.yaml -n linux66
deployment.apps/redis-deployment created
service/redis-deploy-6379 created

如果是錯誤的,pod就會重啟三次,但名字不會變,如果埠檢測連續超過指定的三次都沒有通過,則Pod狀態如下:

[root@k8s-server1 case2]# kubectl get pod -n linux66
NAME                                        READY   STATUS             RESTARTS   AGE
redis-deployment-574f795dcd-gx9v4           0/1     CrashLoopBackOff   3          109s

就緒探針

當路徑不存在時,檢視ep(用來記錄一個service對應的所有pod的訪問地址。)是不會新增進去,同時pod是不會重啟

# 這是正確的
[root@k8s-server1 case2]# cat case1.yaml 
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels: #rs or deployment
      app: ng-deploy-80
    #matchExpressions:
    # - {key: app, operator: In, values: [ng-deploy-80,ng-rs-81]}
  template:
    metadata:
      labels:
        app: ng-deploy-80
    spec:
      containers:
      - name: ng-deploy-80
        image: harbor.longxuan.net/n520/nginx:1.18.0
        ports:
        - containerPort: 80
        readinessProbe:
        #livenessProbe:
          httpGet:
            #path: /montic/montic.html
            path: /index.html
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 3
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3

---
apiVersion: v1
kind: Service
metadata:
  name: ng-deploy-80
spec:
  ports:
  - name: http
    port: 86
    targetPort: 80
    nodePort: 30025
    protocol: TCP
  type: NodePort
  selector:
    app: ng-deploy-80

執行

[root@k8s-server1 case2]# kubectl apply -f case1.yaml -n linux66

deployment.apps/nginx-deployment configured
service/ng-deploy-80 unchanged

檢視ep

[root@k8s-server1 case2]# kubectl get ep -n linux66
NAME                    ENDPOINTS                                                   AGE
linux66-nginx-service   10.100.1.14:443,10.100.2.6:443,10.100.1.14:80 + 1 more...   42h
ng-deploy-80            10.100.5.15:80                                              36m
redis-deploy-6379                                                                   16m
不正確的,檢視ep結果如下:
[root@k8s-server1 case2]# kubectl get ep -n linux66
NAME                    ENDPOINTS                                                   AGE
linux66-nginx-service   10.100.1.14:443,10.100.2.6:443,10.100.1.14:80 + 1 more...   42h
ng-deploy-80                                                                        3s
redis-deploy-6379                                                                   18m

組合使用

[root@k8s-server1 case2]# cat case1.yaml 
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels: #rs or deployment
      app: ng-deploy-80
    #matchExpressions:
    # - {key: app, operator: In, values: [ng-deploy-80,ng-rs-81]}
  template:
    metadata:
      labels:
        app: ng-deploy-80
    spec:
      containers:
      - name: ng-deploy-80
        image: harbor.longxuan.net/n520/nginx:1.18.0
        ports:
        - containerPort: 80
        readinessProbe:
          httpGet:
            #path: /montic/montic.html
            path: /index.html
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 3
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3

        livenessProbe:
          httpGet:
            #path: /montic/montic.html
            path: /index.html
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 3
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3

---
apiVersion: v1
kind: Service
metadata:
  name: ng-deploy-80
spec:
  ports:
  - name: http
    port: 86
    targetPort: 80
    nodePort: 30025
    protocol: TCP
  type: NodePort
  selector:
    app: ng-deploy-80

執行

[root@k8s-server1 case2]# kubectl apply -f case1.yaml -n linux66

deployment.apps/nginx-deployment configured
service/ng-deploy-80 unchanged

當路徑不存在時,檢視ep如下資訊

[root@k8s-server1 case2]# kubectl get ep -n linux66
NAME                    ENDPOINTS                                                   AGE
linux66-nginx-service   10.100.1.14:443,10.100.2.6:443,10.100.1.14:80 + 1 more...   42h
ng-deploy-80            10.100.2.14:80                                              8m51s
redis-deploy-6379                                                                   26m

檢視pod時,資訊如下,探測到失敗就已經重啟

[root@k8s-server1 case2]# kubectl get pod -n linux66
nginx-deployment-5454b65b59-nxxjz           1/1     Running            1          2m37s

再檢視ep,如下資訊

[root@k8s-server1 case2]# kubectl get ep -n linux66
NAME                    ENDPOINTS                                                   AGE
linux66-nginx-service   10.100.1.14:443,10.100.2.6:443,10.100.1.14:80 + 1 more...   42h
ng-deploy-80            10.100.2.14:80,10.100.5.17:80                               9m7s
redis-deploy-6379                                                                   27m

Pod重啟策略:

k8s在Pod出現異常的時候會自動將Pod重啟以恢復Pod中的服務。

restartPolicy:
Always:當容器異常時,k8s自動重啟該容器,ReplicationController/Replicaset/Deployment。
OnFailure:當容器失敗時(容器停止執行且退出碼不為0),k8s自動重啟該容器。
Never:不論容器執行狀態如何都不會重啟該容器,Job或CronJob。

映象拉取策略:

imagePullPolicy: IfNotPresent #node節點沒有此映象就去指定的映象倉庫拉取,node有就使用node本地映象。
imagePullPolicy: Always #每次重建pod都會重新拉取映象
imagePullPolicy: Never #從不到映象中心拉取映象,只使用本地映象