我构建了一个利用 docker pod 处理数据的服务。所需时间从 15 分钟到 1 小时不等。
我的应用程序捕获 SIGTERM 以确保在 Pod 和节点退役时需求下降时正常关闭。
在每个 docker 映像中,我放置了代码来报告它是否因为完成工作而关闭,以及是否发生 SIGTERM 事件并因此完成其处理并终止。
我的系统使用 EKS 部署在 AWS 中。当需求上升时,我使用 EKS 来管理节点部署,并在需求下降时管理节点。我使用 KEDA 来管理 POD 部署,这有助于触发是否需要额外的节点。在 KEDA 中,我将 cooldownPeriod 定义为 2 小时,这是我期望 pod 占用的最大值,即使它需要的最大值是 1 小时。
在 AWS EKS 中,我还定义了 2 小时的 terminateGracePeriodSeconds。
我在节点缩减期间隔离了这个问题,即当节点被终止时,terminationGracePeriodSeconds 没有得到遵守,并且我的 Pod 在大约 30 分钟内被关闭。由于 Pod 被突然移除,我无法查看他们的日志以了解发生了什么。
我试图通过发出 kubernetes 节点耗尽来模拟这个问题并保持我的 pod 运行
kubectl drain <MY NODE>
我看到 SIGTERM 通过了,我还注意到 pod 仅在 2 小时后才终止,而不是之前。
所以有一分钟我想也许我没有正确配置terminationGracePeriod,所以我检查了:
kubectl get deployment test-mypod -o yaml|grep terminationGracePeriodSeconds
terminationGracePeriodSeconds: 7200
我什至重新部署了配置,但这没有任何区别。
但是,我能够通过修改 Node 组的 desiredSize 来重现该问题。我可以通过这样做在 Python 中以编程方式重现它:
resp = self.eks_client.update_nodegroup_config(clusterName=EKS_CLUSTER_NAME,
nodegroupName=EKS_NODE_GROUP_NAME,
scalingConfig={'desiredSize': configured_desired_size})
或者只需转到 AWS 控制台并在那里修改所需的大小。
我看到 EKS 选择了一个节点,如果碰巧有一个 pod 处理数据需要大约一个小时,那么该 pod 有时会过早终止。
我已经登录到那个正在缩减的节点,并且在日志中没有发现过早终止 Pod 的证据。
我曾经能够捕获此信息
kubectl get events | grep test-mypod-b8dfc4665-zp87t
54m Normal Pulling pod/test-mypod-b8dfc4665-zp87t Pulling image ...
54m Normal Pulled pod/test-mypod-b8dfc4665-zp87t Successfully pulled image ...
54m Normal Created pod/test-mypod-b8dfc4665-zp87t Created container mypod
54m Normal Started pod/test-mypod-b8dfc4665-zp87t Started container mypod
23m Normal ScaleDown pod/test-mypod-b8dfc4665-zp87t deleting pod for node scale down
23m Normal Killing pod/test-mypod-b8dfc4665-zp87t Stopping container mypod
13m Warning FailedKillPod pod/test-po-b8dfc4665-zp87t error killing pod: failed to "KillContainer" for "mypod" with KillContainerError: "rpc error: code = Unknown desc = operation timeout: context deadline exceeded"
我曾经在禁用 scaledown 时看到无缘无故移除了一个 pod,但它决定移除我的 pod:
kubectl get events | grep test-mypod-b8dfc4665-vxqhv
45m Normal Pulling pod/test-mypod-b8dfc4665-vxqhv Pulling image ...
45m Normal Pulled pod/test-mypod-b8dfc4665-vxqhv Successfully pulled image ...
45m Normal Created pod/test-mypod-b8dfc4665-vxqhv Created container mypod
45m Normal Started pod/test-mypod-b8dfc4665-vxqhv Started container mypod
40m Normal Killing pod/test-mypod-b8dfc4665-vxqhv Stopping container mypod
这是我拥有的 kuberenets 版本
Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.0" GitCommit:"9e991415386e4cf155a24b1da15becaa390438d8", GitTreeState:"clean", BuildDate:"2020-03-25T14:58:59Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"18+", GitVersion:"v1.18.20-eks-8c49e2", GitCommit:"8c49e2efc3cfbb7788a58025e679787daed22018", GitTreeState:"clean", BuildDate:"2021-10-17T05:13:46Z", GoVersion:"go1.13.15", Compiler:"gc", Platform:"linux/amd64"}
为了尽量减少这个问题,我在高峰时段部署了 Pod Disruption Budget 来阻止缩减,并在晚上需求低迷时删除了启动缩减的 PDB。但是,这不是正确的解决方案,即使在低峰期间,仍有豆荚过早停止。