上一章咱们讲了,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: v1kind: Podmetadata:  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-2814848d9dffspec:  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-lzpd4status:  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就绪,开始服务流量。