Kubernetes 多容器 Pod 终止过程



我在 k8s 中有一个多容器 pod,我们称它们为 A 和 B。停止 Pod 时,A 必须在 B 之前停止,因为 A 需要 B 直到它关闭。

为此,我在 A 上注册了一个preStop钩,以便 A 可以在 B 之前优雅地停止。

但是,我不确定这是否是一个好的解决方案,因为我错过了一些在 k8s 文档中找不到的信息:

多容器 Pod 停止时会发生什么情况?

  • 所有容器preStop钩子都被调用,然后当它们全部覆盖时,所有容器都会收到SIGTERM,或者
  • 同时,所有容器如果有一个,则直接接收preStop,如果没有,则直接SIGTERM

在第二种情况下,preStop对我想做的事情毫无用处,因为 B 会立即被杀死。

通常,在删除 Pod 期间,容器运行时会向每个容器中的主进程发送 TERM 信号。

根据官方文件:

  1. 如果 Pod 的一个容器定义了preStop钩子, 库贝莱特在容器内运行那个钩子。

  2. kubelet 触发容器运行时向每个容器内的进程 1 发送 TERM 信号。

这个数字可能会混淆 - 看起来 TERM 信号只有在钩子完成后才会发送preStop。 我决定用下面的一个简单的例子来检查工作顺序。

apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
restartPolicy: Never
volumes:
- name: config
configMap:
name: nginx-conf
containers:
- name: container-1
image: nginx
lifecycle:
preStop:
exec:
command: ["/bin/sleep","15"]
ports:
- containerPort: 80
- name: container-2
image: nginx
ports:
- containerPort: 81
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
terminationGracePeriodSeconds: 30

容器-1preStop钩子延迟 15 秒。 我已经连接到两个容器以查看 pod 删除期间的行为。

结果

删除容器后:

  1. 容器-1 工作了 15 秒,然后连接丢失

  2. 容器-2 立即失去连接

结论

如果容器有一个preStop钩子,它将尝试执行它。只有这样,它才会收到 TERM 信号。在这种情况下的主要条件:宽限期尚未过期。

如果容器没有preStop钩子,它将在命令删除 Pod 后立即收到 TERM 信号。因此,当preStop钩子将针对另一个容器执行时,它不会等待。

注意:Pod 中的容器以不同的时间和任意顺序接收 TERM 信号。如果停机顺序 问题,请考虑使用preStop挂钩进行同步。

最新更新