1
Tinet 2021-06-09 17:43:36 +08:00
把 pod 的优雅退出时间设置长一点?当然,你的应用要能捕获到退出信息,以便尽快结束当前正在处理的任务
|
2
kakach 2021-06-09 17:45:37 +08:00
不知道 k8s 终止一个 pod 前会不会停止处理新请求并等待一段时间,蹲一个大佬的解答
|
3
mooyo 2021-06-09 17:47:57 +08:00
这个没法保证,因为要保证 pod 处理完再退出就需要从内向外的控制。但是可以调整你的程序来适配 k8s 的一系列信号来尽量避免这个问题。
首先需要调整退出等待期,调长一点,给程序留一定的周转空间。 然后 k8s 可以给 pod 设置一个退出时执行的命令,通过这个命令告知你的服务赶紧结束掉手上的工作,结束不掉的部分持久化存起来,下一个 pod 拉出来接着做。 |
4
thet 2021-06-09 17:53:10 +08:00 via iPhone
差不多就是一楼说的,主要你的程序要能捕获退出信号,然后处理完当前任务就退出。可以根据任务最大执行时间设置一下优雅退出时间,优雅退出时间到了后,不管容器内程序怎么样,容器都会被 kubelet 干掉。
|
5
mindsucker 2021-06-09 18:23:51 +08:00
可以看看优雅停机的相关资料,停机前会给 pid 为 1 的进程发送 TERM signal 命令,但是你的任务要有退出处理机制
|
6
crclz 2021-06-09 18:29:54 +08:00 1
换一种思路。一个健壮的程序应当能够完美应对以下情况:
在断电 /断网后,数据库的完整性依然能够保证。 这就要求你在处理任务的时候充分发挥事务和幂等性的作用。 |
7
libook 2021-06-09 18:30:33 +08:00
可以设计成可恢复(或回滚重做)的事务,即便不主动杀 pod 也可能会存在程序崩溃的问题,这时候新运行的程序能够继续做完之前没做完的任务就行了。
|
8
GopherDaily 2021-06-09 18:38:11 +08:00
graceful shutdown?
|
9
jim9606 2021-06-09 18:55:18 +08:00 5
为了支持 graceful shutdown,你的程序应当捕获 SIGTERM 信号,在捕获该信号后开启 shutdown 工作,停止接受新任务。无论你是不是用容器都应当做到这点。
k8s 默认也是这样的,delete 动作后向容器进程发送 SIGTERM,等待 ShutdownGracePeriod (可适当调大些)后仍未退出就会发送 SIGKILL (不可捕获)杀死进程 |
10
defunct9 2021-06-09 19:29:57 +08:00
lifecycle:
preStop: exec: command: ["/bin/sh", "-c", "sleep 20"] |
11
shiny 2021-06-09 19:34:32 +08:00
哪怕不用 k8s,Docker 容器也需要考虑退出时的信号,但很多 Dockerfile 都没有考虑到这一点,以至于框架不能捕获 SIGTERM 信号做优雅退出
|
12
heart4lor 2021-06-09 19:56:11 +08:00
graceful shutdown 是一点,应用尽量做到无状态也很重要,现在其实很少有应用是完全无状态的
|
13
NUT 2021-06-09 21:53:46 +08:00
没法保证完全保证。需要做计算与存储分离。
把队列信息放到 zk 或 etcd 或者 redis mysql 上线。然后做一个分布式调度 就行了。 |
14
xuzhzzz 2021-06-10 00:26:22 +08:00
这跟 k8s 无关,你的程序跑在哪里都得做到 graceful shutdown 啊
|
15
fitmewell 2021-06-10 00:35:47 +08:00 via Android
先停掉消费队列,然后监控完成后再调用 stop
|
16
vhwwls 2021-06-10 01:42:31 +08:00
楼上说的都对,这点 K8s 自己没有做,只能延长关闭 Pod 的等待期,其他的得从程序层面考量。
|
17
Rwing 2021-06-10 09:41:24 +08:00
楼上说的都对,这点 K8s 自己没有做,只能延长关闭 Pod 的等待期,其他的得从程序层面考量。
|
18
coderxy 2021-06-10 09:57:35 +08:00
优雅退出,k8s 在关闭某个 pod 前会发出一个 sigterm 的信号,服务接收到这个信号后自行优雅退出,如果发出指定后一段时间(好像默认是 10s ),服务还是在运行就会被 k8s 强制 kill
|
19
jingslunt 2021-06-10 10:22:01 +08:00
前面将的 lifecycle 生命周期其实就是 pod hook,滚动的时候加一个钩子,只有钩子执行完成才会执行容器的内容
|
20
PiersSoCool 2021-06-10 13:21:35 +08:00
1 、listen term signal
2 、close http server 3 、handle rest data 我们的日志服务就是这么做的,从未丢过数据 |
21
FingerLiu 2021-06-10 14:33:38 +08:00
|