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