乐趣区

Pod-就地升级4如何判断Pod就地升级完成

上一章咱们讲了,kubelet 如何通过计算容器的 hash 来判断是否须要降级容器。

本文次要讲如何判断 Pod 就地降级实现。

在 ContainerStatus 中不仅有 hash filed。还记录了 ImageID filed。

// 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 的更加具体的讲述,大家能够参考这个系列文章的第一篇。

咱们任意查看一个 Pod 的具体信息:

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:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d

具体的流程如下:

  • 在更新 Pod 的某个 container 镜像之前,获取对应 container 的 ImageID
  • 而后通过 Annotations 的模式将旧的 ImageID 记录下来
  • 更新 spec 当中的镜像
  • 定期去查看 Pod 的 ContainerStatus 中对应的 container 当中的 ImageID 是否和旧的 ImageID 相等。如果相等,这阐明更新没有实现。相同,如果不相等了,那阐明就地更新曾经实现

论断

至此,对于实现就地降级的几个关键点根本曾经讲完。

就地降级的流程大抵如下:

  • 通过 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 就绪,开始服务流量。
退出移动版