Pod 狀態管理

在容器內獲取Pod信息(Downward API)

Downward API有提供了兩種方式來實現從容器內部獲取POD信息的方法:

  • 環境變量的方式
  • Downward API 卷文件掛載

通過這兩種方式,可以將pod的標籤信息,資源信息,狀態信息傳遞到Pod內部。

環境變量方式-將Pod信息注入爲環境變量

參考鏈接

1、使用pod參數方式

使用如下文件:

apiVersion: v1
kind: Pod
metadata:
  name: envars-pod
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "sh", "-c"]
      args:
      - while true; do
          echo -en '\n';
          printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
          printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
          sleep 10;
        done;
      env:
        - name: MY_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: MY_POD_SERVICE_ACCOUNT
          valueFrom:
            fieldRef:
              fieldPath: spec.serviceAccountName
  restartPolicy: Never

創建pod之後,通過logs查看:

# kubectl logs envars-pod

10.0.0.3
envars-pod
default
10.2.6.23
default

登錄pod,可以直接查看,發現環境變量中已經加載了這些參數:

kubectl exec -it  envars-pod -- sh

/ # env
MY_POD_SERVICE_ACCOUNT=default
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.1.0.1:443
HOSTNAME=envars-pod
SHLVL=1
HOME=/root
MY_POD_NAMESPACE=default
TERM=xterm
MY_POD_IP=10.2.6.23
KUBERNETES_PORT_443_TCP_ADDR=10.1.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
MY_NODE_NAME=10.0.0.3
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.1.0.1:443
KUBERNETES_SERVICE_HOST=10.1.0.1
PWD=/
MY_POD_NAME=envars-pod

通過yaml文件中指定的valueFrom這種方式的Downward語法獲取相關Pod信息。

2、 使用容器參數方式

如下文件:

apiVersion: v1
kind: Pod
metadata:
  name: envars-con
spec:
  containers:
    - name: test-container
      image: busybox:1.24
      command: [ "sh", "-c"]
      args:
      - while true; do
          echo -en '\n';
          printenv MY_CPU_REQUEST MY_CPU_LIMIT;
          printenv MY_MEM_REQUEST MY_MEM_LIMIT;
          sleep 10;
        done;
      resources:
        requests:
          memory: "32Mi"
          cpu: "125m"
        limits:
          memory: "64Mi"
          cpu: "250m"
      env:
        - name: MY_CPU_REQUEST
          valueFrom:
            resourceFieldRef:
              containerName: test-container
              resource: requests.cpu
        - name: MY_CPU_LIMIT
          valueFrom:
            resourceFieldRef:
              containerName: test-container
              resource: limits.cpu
        - name: MY_MEM_REQUEST
          valueFrom:
            resourceFieldRef:
              containerName: test-container
              resource: requests.memory
        - name: MY_MEM_LIMIT
          valueFrom:
            resourceFieldRef:
              containerName: test-container
              resource: limits.memory
  restartPolicy: Never

運行此pod,查看日誌:

1
1
33554432
67108864

使用volume方式

參考鏈接

1、使用Pod 參數
創建如下文件:

apiVersion: v1
kind: Pod
metadata:
  name: kubernetes-downwardapi-volume-example
  labels:
    zone: us-est-coast
    cluster: test-cluster1
    rack: rack-22
  annotations:
    build: two
    builder: john-doe
spec:
  containers:
    - name: client-container
      image: busybox
      command: ["sh", "-c"]
      args:
      - while true; do
          if [[ -e /etc/podinfo/labels ]]; then
            echo -en '\n\n'; cat /etc/podinfo/labels; fi;
          if [[ -e /etc/podinfo/annotations ]]; then
            echo -en '\n\n'; cat /etc/podinfo/annotations; fi;
          sleep 5;
        done;
      volumeMounts:
        - name: podinfo
          mountPath: /etc/podinfo
          readOnly: false
  volumes:
    - name: podinfo
      downwardAPI:
        items:
          - path: "labels"
            fieldRef:
              fieldPath: metadata.labels
          - path: "annotations"
            fieldRef:
              fieldPath: metadata.annotations

通過downward API的volume方式,將pod的labels中的所有參數和annotations中的所有參數傳遞給了pod內。
在對應的路徑下,有一個隱藏的文件目錄,存放了這兩個文件。

2、通容器參數傳遞資源配額
如下Pod文件:

apiVersion: v1
kind: Pod
metadata:
  name: kubernetes-downwardapi-volume-example-2
spec:
  containers:
    - name: client-container
      image: k8s.gcr.io/busybox:1.24
      command: ["sh", "-c"]
      args:
      - while true; do
          echo -en '\n';
          if [[ -e /etc/podinfo/cpu_limit ]]; then
            echo -en '\n'; cat /etc/podinfo/cpu_limit; fi;
          if [[ -e /etc/podinfo/cpu_request ]]; then
            echo -en '\n'; cat /etc/podinfo/cpu_request; fi;
          if [[ -e /etc/podinfo/mem_limit ]]; then
            echo -en '\n'; cat /etc/podinfo/mem_limit; fi;
          if [[ -e /etc/podinfo/mem_request ]]; then
            echo -en '\n'; cat /etc/podinfo/mem_request; fi;
          sleep 5;
        done;
      resources:
        requests:
          memory: "32Mi"
          cpu: "125m"
        limits:
          memory: "64Mi"
          cpu: "250m"
      volumeMounts:
        - name: podinfo
          mountPath: /etc/podinfo
          readOnly: false
  volumes:
    - name: podinfo
      downwardAPI:
        items:
          - path: "cpu_limit"
            resourceFieldRef:
              containerName: client-container
              resource: limits.cpu
          - path: "cpu_request"
            resourceFieldRef:
              containerName: client-container
              resource: requests.cpu
          - path: "mem_limit"
            resourceFieldRef:
              containerName: client-container
              resource: limits.memory
          - path: "mem_request"
            resourceFieldRef:
              containerName: client-container
              resource: requests.memory

通過如下方式,查看pod中傳遞的參數:

kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh
/# cat /etc/podinfo/cpu_limit

Downward API的應用主要是在某些場景中,集羣中的每個節點將需要將自身的標識(ID)及進程綁定IP地址等信息事先寫入配置文件中,進程啓動時讀取這些信息發佈到服務的註冊中心,實現集羣節點的自動發現功能。

Pod生命週期和重啓策略

Pod的常見狀態

當我們執行kubectl describe pod <pod-name>時,會發現Pod都會有一個狀態值,下面列舉了Pod的5中狀態:

  • Pending: API server 已經創建該Pod,但是Pod內還有一個或多個容器鏡像沒有創建,一般是在下載鏡像。
  • Running: Pod內的所有容器均已經創建,且至少有一個容器處於運行狀態、正在啓動或重啓狀態。
  • Succeeded: Pod內所有容器均已經成功執行退出,且不再重啓
  • Failed: Pod內所有容器均已退出,但至少有一個容器退出爲失敗狀態。
  • Unknown: 由於某種原因無法獲取Pod狀態,可能由於網絡通信不暢導致。

Pod重啓策略(RestartPolicy)

Pod的重啓策略應用於Pod中的所有容器,並且僅在Pod所處的Node上由Kubelet進行判斷和重啓操作。
RestartPolicy包含三個設定:

  • Always: 當容器失效時,由kubelet自動重啓該容器。
  • OnFailure: 當容器終止運行且退出碼不爲0時,由Kubelet自動重啓該容器。
  • Never: 不論容器的運行狀態如何,Kubelet都不會重啓該容器。
    當管理Pod的控制包括ReplicationController、Job、DaemonSet以及直接通過Kubelet管理(靜態Pod),對應的控制器對Pod的重啓策略要求如下:
  • RC和DaemonSet,ReplicaSet,Deployment: 必須設置爲Always,需要保證容器的持續運行
  • Job: OnFailure 或Never,確保容器不再執行
  • kubelet: 在Pod失效時自動重啓它,不論將RestartPolicy設置爲什麼值,也不會對Pod進行健康檢查。

Pod健康檢查

對Pod的健康狀態檢查可以通過兩類探針來檢查:LivenessProbe和ReadinessProbe。

  • livenessProbe: 判斷容器是否存活(running),如果檢測到容器不健康,則kubelet將殺掉該容器,並根據容器的重啓策略做相應的處理。如果容器不包含LivenessProbe探針,則返回永遠是Success。
  • readinessProbe: 用於判斷容器是否啓動完成(ready),可以接受請求。如果ReadinessProbe探針檢測到失敗,則Pod的狀態將被修改。Endpoint Controller將從Service的EndPoint中刪除包含該容器所在的Pod的EndPoint。

容器的探針對容器有3中實現方式:

  • ExecAction: 在容器內執行一條命令,如果命令的返回碼爲0,則表示容器健康。
  • TCPSocketAction: 通過容器的端口號和IP地址執行TCP檢測,如果能夠建立TCP連接表示容器健康。
  • HTTPGetAction: 通過容器的IP地址、端口號及路徑調用HTTP Get方法,如果相應的狀態碼大於等於200且小於400,則認爲容器狀態健康。

下面是對應的三個示例,闡述了這3中實現方式:

1、使用ExecAction方式:

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5            # 從容器啓動時,到第一次執行健康探測的時間間隔
      periodSeconds: 5                  # 每隔5s 檢查一次
      timeoutSeconds: 1                 # 健康檢查發送請求後的等待響應時間,默認爲1S,超時無響應,則會認爲無法提供服務,kubelet會重啓該容器。

通過如下命令,可以查看到pod的健康狀態和重啓次數:

kubectl get pod -o wide
kubectl describe pod liveness-exec

2、使用TCPSockAction
如下文件示例:

apiVersion: v1
kind: Pod
metadata:
  name: nginx 
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    readinessProbe:
      tcpSocket:
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 80
      initialDelaySeconds: 15
      periodSeconds: 20

3、使用HTTPGetAction

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: mirrorgooglecontainers/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: X-Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3

readinessProbe 和livenessProbe 用法十分相似,只需要把 readinessProbe替換爲livenessProbe即可。它們可以同時使用在同一個容器上,來確保流量不會流入未準備好的容器,並且讓容器在失敗的時候重新啓動。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章