k8s 滚动更新,如何避免替换掉正在处理任务的 pod?

2021-06-09 17:38:50 +08:00
 blue7wings
因为 pod 是消耗队列,所以不希望滚动更新的时候,这个 pod 被替换掉,如何保证这个 pod 处理完队列的数据,然后再被自动更新呢? k8s 小白,希望大家能给点建议,谢谢啦
3681 次点击
所在节点    Kubernetes
21 条回复
Tinet
2021-06-09 17:43:36 +08:00
把 pod 的优雅退出时间设置长一点?当然,你的应用要能捕获到退出信息,以便尽快结束当前正在处理的任务
kakach
2021-06-09 17:45:37 +08:00
不知道 k8s 终止一个 pod 前会不会停止处理新请求并等待一段时间,蹲一个大佬的解答
mooyo
2021-06-09 17:47:57 +08:00
这个没法保证,因为要保证 pod 处理完再退出就需要从内向外的控制。但是可以调整你的程序来适配 k8s 的一系列信号来尽量避免这个问题。
首先需要调整退出等待期,调长一点,给程序留一定的周转空间。 然后 k8s 可以给 pod 设置一个退出时执行的命令,通过这个命令告知你的服务赶紧结束掉手上的工作,结束不掉的部分持久化存起来,下一个 pod 拉出来接着做。
thet
2021-06-09 17:53:10 +08:00
差不多就是一楼说的,主要你的程序要能捕获退出信号,然后处理完当前任务就退出。可以根据任务最大执行时间设置一下优雅退出时间,优雅退出时间到了后,不管容器内程序怎么样,容器都会被 kubelet 干掉。
mindsucker
2021-06-09 18:23:51 +08:00
可以看看优雅停机的相关资料,停机前会给 pid 为 1 的进程发送 TERM signal 命令,但是你的任务要有退出处理机制
crclz
2021-06-09 18:29:54 +08:00
换一种思路。一个健壮的程序应当能够完美应对以下情况:

在断电 /断网后,数据库的完整性依然能够保证。

这就要求你在处理任务的时候充分发挥事务和幂等性的作用。
libook
2021-06-09 18:30:33 +08:00
可以设计成可恢复(或回滚重做)的事务,即便不主动杀 pod 也可能会存在程序崩溃的问题,这时候新运行的程序能够继续做完之前没做完的任务就行了。
GopherDaily
2021-06-09 18:38:11 +08:00
graceful shutdown?
jim9606
2021-06-09 18:55:18 +08:00
为了支持 graceful shutdown,你的程序应当捕获 SIGTERM 信号,在捕获该信号后开启 shutdown 工作,停止接受新任务。无论你是不是用容器都应当做到这点。

k8s 默认也是这样的,delete 动作后向容器进程发送 SIGTERM,等待 ShutdownGracePeriod (可适当调大些)后仍未退出就会发送 SIGKILL (不可捕获)杀死进程
defunct9
2021-06-09 19:29:57 +08:00
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 20"]
shiny
2021-06-09 19:34:32 +08:00
哪怕不用 k8s,Docker 容器也需要考虑退出时的信号,但很多 Dockerfile 都没有考虑到这一点,以至于框架不能捕获 SIGTERM 信号做优雅退出
heart4lor
2021-06-09 19:56:11 +08:00
graceful shutdown 是一点,应用尽量做到无状态也很重要,现在其实很少有应用是完全无状态的
NUT
2021-06-09 21:53:46 +08:00
没法保证完全保证。需要做计算与存储分离。
把队列信息放到 zk 或 etcd 或者 redis mysql 上线。然后做一个分布式调度 就行了。
xuzhzzz
2021-06-10 00:26:22 +08:00
这跟 k8s 无关,你的程序跑在哪里都得做到 graceful shutdown 啊
fitmewell
2021-06-10 00:35:47 +08:00
先停掉消费队列,然后监控完成后再调用 stop
vhwwls
2021-06-10 01:42:31 +08:00
楼上说的都对,这点 K8s 自己没有做,只能延长关闭 Pod 的等待期,其他的得从程序层面考量。
Rwing
2021-06-10 09:41:24 +08:00
楼上说的都对,这点 K8s 自己没有做,只能延长关闭 Pod 的等待期,其他的得从程序层面考量。
coderxy
2021-06-10 09:57:35 +08:00
优雅退出,k8s 在关闭某个 pod 前会发出一个 sigterm 的信号,服务接收到这个信号后自行优雅退出,如果发出指定后一段时间(好像默认是 10s ),服务还是在运行就会被 k8s 强制 kill
jingslunt
2021-06-10 10:22:01 +08:00
前面将的 lifecycle 生命周期其实就是 pod hook,滚动的时候加一个钩子,只有钩子执行完成才会执行容器的内容
PiersSoCool
2021-06-10 13:21:35 +08:00
1 、listen term signal
2 、close http server
3 、handle rest data

我们的日志服务就是这么做的,从未丢过数据

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/782462

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX