Pod 就地升級4--如何判斷Pod就地升級完成

上一章咱們講了,kubelet如何經過計算容器的hash來判斷是否須要升級容器。node

本文主要講如何判斷Pod就地升級完成。nginx

在ContainerStatus中不只有hash filed。還記錄了ImageID filed。docker

// Status represents the status of a container.
type Status struct {
    // ID of the container.
    ID ContainerID
    // Name of the container.
    Name string
    // Status of the container.
    State State
    // Creation time of the container.
    CreatedAt time.Time
    // Start time of the container.
    StartedAt time.Time
    // Finish time of the container.
    FinishedAt time.Time
    // Exit code of the container.
    ExitCode int
    // Name of the image, this also includes the tag of the image,
    // the expected form is "NAME:TAG".
    Image string
    // ID of the image.
    ImageID string
    // Hash of the container, used for comparison.
    Hash uint64
    // Number of times that the container has been restarted.
    RestartCount int
    // A string explains why container is in such a status.
    Reason string
    // Message written by the container before exiting (stored in
    // TerminationMessagePath).
    Message string
}

關於ImageID的更加詳細的講述,你們能夠參考這個系列文章的第一篇。api

咱們任意查看一個Pod的具體信息:app

apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubernetes.io/psp: eks.privileged
  creationTimestamp: "2020-07-10T02:33:03Z"
  generateName: nginx-574b87c764-
  labels:
    app: nginx
    pod-template-hash: 574b87c764
  name: nginx-574b87c764-gf4tx
  namespace: default
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicaSet
    name: nginx-574b87c764
    uid: c0a0499b-808e-4aa9-a3c3-2ecdb823a19b
  resourceVersion: "2088142"
  selfLink: /api/v1/namespaces/default/pods/nginx-574b87c764-gf4tx
  uid: a5e4d703-3a01-4712-a64a-2814848d9dff
spec:
  containers:
  - image: nginx:1.14.2
    imagePullPolicy: IfNotPresent
    name: nginx
    ports:
    - containerPort: 80
      protocol: TCP
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-lzpd4
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: ip-172-17-186-211.ap-south-1.compute.internal
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: default-token-lzpd4
    secret:
      defaultMode: 420
      secretName: default-token-lzpd4
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2020-07-10T02:33:03Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2020-07-10T02:33:06Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2020-07-10T02:33:06Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2020-07-10T02:33:03Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://918275efc39411f454b7dd8c7f1e3cbd0e6eba00370b0bcaaac0b1b9a5dd868d
    image: nginx:1.14.2
    imageID: docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
    lastState: {}
    name: nginx
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2020-07-10T02:33:05Z"
  hostIP: 172.17.186.211
  phase: Running
  podIP: 172.17.166.134
  podIPs:
  - ip: 172.17.166.134
  qosClass: BestEffort
  startTime: "2020-07-10T02:33:03Z"

如上 imageID: docker-pullable://nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8dui

具體的流程以下:this

  • 在更新Pod的某個container鏡像以前,獲取對應container的 ImageID
  • 而後經過Annotations的形式將舊的 ImageID 記錄下來
  • 更新spec當中的鏡像
  • 按期去檢查Pod的ContainerStatus中對應的container 當中的ImageID是否和舊的ImageID相等。若是相等,這說明更新沒有完成。相反,若是不相等了,那說明就地更新已經完成

結論

至此,關於實現就地升級的幾個關鍵點基本已經講完。spa

就地升級的流程大體以下:rest

  • 經過Readiness gate,設置其condition 爲false。這樣該Pod便再也不就緒,那麼其的地址會從Endpoints當中剔除,再也不服務流量。
  • 更改Spec.containers[i].image 爲新的鏡像。
  • 並將舊container的ContainerStatus中的ImageID記錄下來。
  • kubectl 經過計算 容器的hash,發現指望container 已經發生變化,便kill該容器,使用新的Image啓動新的容器。
  • 控制器按期檢查Pod新container的ContainerStatus中的ImageID是否和以前記錄的相等,若是不等,則已經成功更新了新的Image。
  • 修改Readiness gate,設置其condition 爲true。若是該容器的readiness probe 也經過,那麼該Pod就緒,開始服務流量。
相關文章
相關標籤/搜索