<aside> ⏰ 本文介绍了删除 Pod 的完整流程
</aside>
比如现在我有一个更新策略为 Recreate
的应用,然后执行删除命令,如下所示:
➜ kubectl get pods
NAME READY STATUS RESTARTS AGE
minio-875749785-sv5ns 1/1 Running 1 (2m52s ago) 42h
➜ kubectl delete pod minio-875749785-sv5ns
pod "minio-875749785-sv5ns" deleted
在删除之前在另外一个终端观察应用状态:
➜ kubectl get pods -w
NAME READY STATUS RESTARTS AGE
minio-875749785-sv5ns 1/1 Running 1 (2m46s ago) 42h
minio-875749785-sv5ns 1/1 Terminating 1 (2m57s ago) 42h
minio-875749785-h2j2b 0/1 Pending 0 0s
minio-875749785-h2j2b 0/1 Pending 0 0s
minio-875749785-h2j2b 0/1 ContainerCreating 0 0s
minio-875749785-sv5ns 0/1 Terminating 1 (2m59s ago) 42h
minio-875749785-sv5ns 0/1 Terminating 1 (2m59s ago) 42h
minio-875749785-sv5ns 0/1 Terminating 1 (2m59s ago) 42h
minio-875749785-h2j2b 0/1 Running 0 17s
minio-875749785-h2j2b 1/1 Running 0 30s
从上面的过程可以看到当我们执行 kubectl delete
命令后 Pod 变成了 Terminating
状态,然后才消失。接下来我们会从代码角度来介绍下删除 Pod 的整个流程。
我们可以根据 kubectl 操作后看到的状态来进行跟踪,上面的格式化结果是通过代码 **https://github.com/kubernetes/kubernetes/blob/v1.22.8/pkg/printers/internalversion/printers.go#L88-L102** 实现的,如下所示:
对于 Pod 的输出结果是通过 printPod
函数获取的,代码位于:**https://github.com/kubernetes/kubernetes/blob/v1.22.8/pkg/printers/internalversion/printers.go#L756-L840**,其中有一段代码提到了 Terminating
值,是在 pod.DeletionTimestamp != nil
的情况下变成该状态的,如下所示:
也就是说当执行删除操作的时候,会设置 Pod 的 DeletionTimestamp
属性,这个时候就会显示成 Terminating
状态。
当执行删除操作的时候,会向 apiserver 发送一次 DELETE 请求:
I0408 11:25:33.002155 42938 round_trippers.go:435] curl -v -XDELETE -H "Content-Type: application/json" -H "User-Agent: kubectl/v1.22.7 (darwin/amd64) kubernetes/b56e432" -H "Accept: application/json" '<https://192.168.0.111:6443/api/v1/namespaces/default/pods/minio-875749785-sv5ns>'
I0408 11:25:33.037245 42938 round_trippers.go:454] DELETE <https://192.168.0.111:6443/api/v1/namespaces/default/pods/minio-875749785-sv5ns> 200 OK in 35 milliseconds
接收到删除请求的处理器位于代码 **https://github.com/kubernetes/kubernetes/blob/v1.22.8/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go#L986**,如下所示:
在 BeforeDelete
函数中判断是否需要优雅删除,判断的标准是 DeletionGracePeriodSeconds
值是否为 0,不为零则认为是优雅删除,apiserver 不会立即将这个对象从 etcd 中删除,否则直接删除。对于 Pod 而言,默认 DeletionGracePeriodSeconds
为 30 秒,因此这里不会被立刻删除掉,而是将 DeletionTimestamp
设置为当前时间,DeletionGracePeriodSeconds
设置为默认值 30 秒。 代码位于 **https://github.com/kubernetes/kubernetes/blob/v1.22.8/staging/src/k8s.io/apiserver/pkg/registry/rest/delete.go#L93-L159**,在该函数中会设置 DeletionTimestamp
的值,如下所示:
上面的代码验证了当执行删除操作的时候,apiserver 会先设置 Pod 的 DeletionTimestamp
属性为当前时间加上优雅删除宽限时长的时间点,设置了该属性后,我们客户端格式化过后看到的就是 Terminating
状态了。