我想在Kubernetes Pod中实现正常关闭。我知道我需要监听SIGTERM,它表示关机程序的开始。但是当我收到它时,我究竟该怎么做?
至少我必须等待所有正在运行的请求完成才能退出。但收到SIGTERM后,pod仍然可以收到新的请求吗? (它使用服务暴露。)我无法找到任何明确的文档。
The docs州:
Pod已从端点列表中删除以进行维护,并且不再被视为复制控制器的运行pod集的一部分。缓慢关闭的窗格可以继续为流量提供服务,因为负载平衡器(如服务代理)会将它们从旋转中移除。
所以这似乎意味着新请求仍然可以进来。那么在优雅终止之前我应该继续期待新请求多长时间?我是否只是忽略SIGTERM,继续照常提供请求并等待最终的SIGKILL?
我想确保未来的准备情况检查失败,然后等待的时间超过它们发生之前的时间可能会有效吗?
我在Kubernetes 1.2.5上,如果这有什么不同,特别是在讨论滚动更新,而且通常会缩小复制控制器。
答案 0 :(得分:3)
我最近遇到过类似的问题,我使用了简单的preStop钩子,它在终止开始和接收SIGTERM到底层进程之间引入了一些延迟(睡眠)
snakemake --cluster ...
此延迟有帮助,
负载均衡器以移除(同步)正在终止的容器
有机会终止pod以完成终止前收到的请求
在终止和负载均衡器更新(同步)之间完成终止pod接收的请求
使用不可预测的服务时间,可以使PreStop更加智能化
答案 1 :(得分:1)
我进行了一些实验,以确切了解会发生什么。
pod 将短暂地(< 1s)在启动关闭后继续接收请求,因此您需要捕获SIGTERM或安装preStop挂钩以便等待它们(并完成当前服务)请求)。
但是,一旦启动关闭,准备探测不再重要,您无需更改其状态以停止接收请求。 (但在此之前,一个失败的准备情况探测器将导致你的pod不再接收流量。)
答案 2 :(得分:0)
如果您希望在关闭广告连播之前干净地排放流量,则应使用preStop hook和livenessProbe health check。
理想情况下,您将拥有一个preStop挂钩,它会强制将pod置于不健康的livenessProbe检查中,以便将pod从负载均衡器中移除,然后正常关闭。
这不是很好,但这个例子在我的简单测试中起作用。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx
spec:
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
livenessProbe:
exec:
command:
- cat
- /usr/share/nginx/html/50x.html
initialDelaySeconds: 15
timeoutSeconds: 1
ports:
- containerPort: 80
lifecycle:
preStop:
exec:
# SIGTERM triggers a quick exit; fail health check and gracefully terminate instead
command: ["/bin/rm","-f","/usr/share/nginx/html/50x.html",";","sleep","2",";","/usr/sbin/nginx","-s","quit"]
在此示例中,livenessProbe会查找/usr/share/nginx/html/50x.html文件。只要该文件存在,该pod就是健康的。当pod将要关闭时,将触发preStop挂钩,删除该文件。这应该会在下一次健康检查(1秒)时触发从外部负载平衡器中移除吊舱。然后preStop命令休眠2秒(以确保触发下一次运行状况检查)并告诉nginx正常停止-s quiet
。 preStop命令应该在pod被强制终止之前的30秒内完成(SIGTERM)但是这应该给nginx足够的时间来消耗连接。