原理
通常 Pod 体面终止的过程为:kubelet 先发送一个带有体面超时限期的 TERM(又名 SIGTERM,根据参数terminationGracePeriodSeconds来决定) 信号到每个容器中的主进程,将请求发送到容器运行时来尝试停止 Pod 中的容器。 停止容器的这些请求由容器运行时以异步方式处理。 这些请求的处理顺序无法被保证。许多容器运行时遵循容器镜像内定义的 STOPSIGNAL 值, 如果不同,则发送容器镜像中配置的 STOPSIGNAL,而不是 TERM 信号。 一旦超出了体面终止限期,容器运行时会向所有剩余进程发送 KILL 信号,之后 Pod 就会被从 API 服务器上移除。 如果 kubelet 或者容器运行时的管理服务在等待进程终止期间被重启, 集群会从头开始重试,赋予 Pod 完整的体面终止限期。
通常终止流程按照下面约束进行:
如果 Pod 中的容器之一定义了 preStop 回调 且 Pod 规约中的 terminationGracePeriodSeconds 未设为 0, kubelet 开始在容器内运行该回调逻辑。默认的 terminationGracePeriodSeconds 设置为 30 秒.
如果 Pod 未定义 preStop 回调,根据默认的 terminationGracePeriodSeconds 设置为 30 秒。进行 kill -9(无论terminationGracePeriodSeconds 有没有配置)
如果 preStop 回调在体面期结束后仍在运行,kubelet 将请求短暂的、一次性的体面期延长 2 秒。即 30 + 2 s 后删除Pod。
如果 preStop 回调配置的值大于 > terminationGracePeriodSeconds , 仍按照 terminationGracePeriodSeconds 去执行。
kubelet 向每个容器的 pid = 1的进程发送 SIGTERM。
发送后 Pod 被设置为 Terminating,并关闭Pod流量调度(service 是根据 Running Pod进行调度)。
待Pod自动完成,或者 到达 terminationGracePeriodSeconds + 2 时,将强制退出。
演示
使用的 Dockerfile
|
|
使用的部署清单
|
|
使用的启动脚本
|
|
当发起redeploy,现象立马重启,dumb-init吧信号传递给脚本,脚本没有把信号传递给子进程,父进程退出后容器就退出了。
会被立即杀死
|
|
正常不适用脚本的推出追踪
|
|
如果命令是在脚本中使用,需要增加 trap
|
|
然后测试
|
|