我想在Kubernetes Pod中实现正常关闭 . 我知道我需要监听SIGTERM,它表示关机程序的开始 . 但是当我收到它时,我到底该怎么办?
至少我必须等待所有正在运行的请求完成才能退出 . 但收到SIGTERM后,pod仍然可以收到新的请求吗? (它使用服务公开 . )我找不到任何关于此的明确文档 .
The docs州:
Pod将从 endpoints 列表中删除以进行维护,并且不再被视为复制控制器的运行pod集的一部分 . 缓慢关闭的窗格可以继续为流量提供服务,因为负载 balancer 器(如服务代理)将它们从旋转中移除 .
所以这似乎意味着新请求仍然可以进入 . 那么在优雅终止之前我应该继续期待新请求多长时间?我是否只是忽略SIGTERM,继续像往常一样处理请求并等待最终的SIGKILL?
我想确保未来的准备情况检查失败,然后等待的时间超过它们发生之前的时间可能会有效吗?
我正在使用Kubernetes 1.2.5,如果这有什么不同,我正在谈论特别是滚动更新,而且通常还会缩小复制控制器 .
3 回答
我做了一些实验,以确切了解发生了什么 .
在启动关闭后,pod将短暂地(<1s)继续接收请求,因此您需要捕获SIGTERM或安装preStop挂钩,以便您可以等待它们(并完成当前请求的服务) .
但是,一旦启动关闭,准备探测不再重要,您无需更改其状态以停止接收请求 . (但在此之前,失败的准备情况调查将导致您的pod不再接收流量 . )
如果要在关闭吊舱之前干净地排空流量,则应使用preStop hook和livenessProbe health check .
理想情况下,您将拥有一个preStop挂钩,它会强制将pod置于不 Health 的livenessProbe检查中,以便将pod从负载均衡器中移除,然后正常关闭 .
这不是很漂亮,但这个例子在我的简单测试中有效 .
在此示例中,livenessProbe查找/usr/share/nginx/html/50x.html文件 . 只要该文件存在,该pod就是 Health 的 . 当pod将要关闭时,将触发preStop挂钩,删除该文件 . 这应该会在下一次 Health 检查(1秒)时触发从外部负载 balancer 器中移除吊舱 . 然后preStop命令休眠2秒(以确保触发下一个运行状况检查)并告诉nginx正常停止
-s quiet
. preStop命令应该在pod被强制终止之前30秒内完成(SIGTERM),但这应该给nginx足够的时间来消耗连接 .我最近遇到了类似的问题,我使用了简单的preStop钩子,它在终止开始和接收SIGTERM到底层进程之间引入了一些延迟(休眠)
这种延迟有助于
负载均衡器删除(同步)正在终止的Pod
有机会终止pod以完成终止前收到的请求
在终止和负载均衡器更新(同步)之间完成终止pod接收的请求
使用不可预测的服务时间,可以使PreStop更加智能化