Kubernetes AutoScaler或在AWS中更改所需节点会提前终止Docker Pod

sbtkgmzw  于 2022-11-21  发布在  Kubernetes
关注(0)|答案(3)|浏览(174)

我 构建 了 一 个 利用 Docker Pod 来 处理 数据 的 服务 。 它 所 花费 的 时间 从 少 到 15 分钟 到 多 到 1 小时 不等 。
我 的 应用 程序 会 捕获 SIGTERM , 以 确保 在 Pod 和 节点 停用 期间 需求 下降 时 正常 关机 。
在 每个 Docker 映像 中 , 我 都 放置 了 代码 , 以便 报告 它 是否 因为 完成 了 工作 而 关闭 , 以及 是否 发生 了 SIGTERM 事件 , 从而 完成 了 处理 并 终止 。
我 的 系统 是 使用 EKS 部署 在 AWS 中 的 。 当 需求 上升 时 , 我 使用 EKS 来 管理 节点 部署 , 当 需求 下降 时 , 我 使用 EKS 来 降低 节点 的 转速 。 我 使用 KEDA 来 管理 POD 部署 , 这 有助于 触发 是否 需要 额外 的 节点 。 在 KEDA 中 , 我 将 冷却 周期 定义 为 2 小时 , 这 是 我 期望 一 个 POD 最 多 需要 的 时间 , 尽管 它 最 多 需要 1 小时 。
在 AWS EKS 中 , 我 也 将 terminationGracePeriodSeconds 定义 为 2 小时 。
我 隔离 了 节点 缩减 期间 的 问题 , 即 当 终止 节点 时 , terminationGracePeriodSeconds 未 被 接受 , 并且 我 的 Pod 在 约 30 分钟 内 关闭 。 由于 Pod 被 突然 删除 , 我 无法 查看 其 日志 以 了解 发生 了 什么 。
我 尝试 通过 发出 kubernetes 节点 耗尽 命令 来 模拟 此 问题 , 并 保持 Pod 运行

kubectl drain <MY NODE>

中 的 每 一 个
我 看到 SIGTERM 通过 了 , 我 还 注意 到 吊舱 只 在 2 小时 后 终止 而 不 是 之前 。
所以 有 那么 一 小 会儿 我 想 可能 我 没有 正确 配置 terminationGracePeriod , 所以 我 检查 了 一下 :

kubectl get deployment test-mypod -o yaml|grep terminationGracePeriodSeconds
  terminationGracePeriodSeconds: 7200

格式
我 甚至 重新 部署 了 配置 , 但 这 没有 任何 区别 。
但是 , 我 可以 通过 修改 节点 组 的 desiredSize 来 重现 这个 问题 。 我 可以 通过 以下 方式 在 Python 中 以 编程 方式 重现 这个 问题 :

resp = self.eks_client.update_nodegroup_config(clusterName=EKS_CLUSTER_NAME,
                                                       nodegroupName=EKS_NODE_GROUP_NAME,
                                                       scalingConfig={'desiredSize': configured_desired_size})

格式
或者 简单 地 转到 AWS 控制 台 并 在 那里 修改 desiredSize 。
我 看到 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"

格式
我 曾经 看到 过 一 个 pod 被 无缘无故 地 删除 , 当 scaledown 被 禁用 时 , 但 它 决定 删除 我 的 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 中断 预算 , 以 阻止 规模 缩小 , 并 在 晚上 需求 较 低 时 移除 PDB , 启动 规模 缩小 。 然而 , 这 不是 正确 的 解决 方案 , 即使 在 低 峰 时段 , 仍 有 Pod 过早 停止 。

r1zhe5dt

r1zhe5dt1#

AWS EKS和cluster-autoscaler也遇到了同样的问题-节点意外关闭,没有采取任何预防措施,甚至node注解cluster-autoscaler.kubernetes.io/scale-down-disabled=true也没有任何影响。
经过两天的故障排除,我们找到了原因-这是因为我们在ASG配置中使用了多个可用性区域,该配置具有自动“AZRebalance”进程。AZRebalance尝试确保所有可用性区域之间的节点数量大致相同。因此,有时当发生纵向扩展事件时,它尝试通过删除一个节点并在不同时区创建另一个节点来重新平衡节点。事件日志中的消息如下所示:

Cluster-autoscaler不控制此过程,因此有两个系统(cluster-autoscaler和AWS ASG)同时管理节点数量,这会导致意外行为。
作为解决方法,我们暂停了ASG中的“AZRebalance”进程。

另一种解决方案是分别为每个可用性区域使用ASG,并在集群自动缩放器中使用--balance-similar-node-groups功能。
Here's这篇文章介绍了这一点,这里是集群自动缩放器文档。

azpvetkf

azpvetkf2#

使用Amazon EKS时,节点自动定标器不荣誉terminationGracePeriodSeconds。
https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#does-ca-respect-gracefultermination-in-scale-down
节点自动定标器仅提供10分钟的宽限期。
集群自动定标器的速度有多快?
默认情况下,在单元被标记为不可调度后的10秒内,向上扩展被认为是最大的;在节点变为不需要后的10分钟内,向下扩展被认为是最小的。有多个标志可用于配置这些阈值。例如,在某些环境中,您可能希望给予k8s调度程序比CA的扫描间隔多一点的时间来调度pod。一种方法是设置--new-pod-scale-up-delay,这使得CA忽略不可调度的POD,直到它们达到一定的“年龄”,而不管扫描间隔。如果k8在该延迟结束时还没有调度它们,则CA可以考虑它们进行可能的扩大。
另一个相关链接:https://github.com/kubernetes/autoscaler/issues/147
我实现了一个作为preStopHook调用的脚本,该脚本有望阻止下一个发出SIGTERM的状态,并启动10分钟倒计时,给予我有机会优雅地关闭我的服务。
该设置的一些参考:
https://www.ithands-on.com/2021/07/kubernetes-101-pods-lifecycle-hooks_30.html
https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/
相反,我根据以下参考将以下注解添加到我的pod部署配置中:
https://aws.github.io/aws-eks-best-practices/cluster-autoscaling/#prevent-scale-down-eviction

template:
  metadata:
    labels:
      annotations:
        cluster-autoscaler.kubernetes.io/safe-to-evict: 'false'

然后,我确保我的pod成为按需pod,也就是说,没有pod被部署为空闲状态,因为空闲pod会影响EKS规模缩小,并且只在需要时生成,并在任务完成时关闭。这降低了我对作业的响应时间,但相对于在昂贵的计算环境中关闭Pod,这是一个较小的代价。
如果有人想了解如何部署AWS集群自动定标器:https://docs.aws.amazon.com/eks/latest/userguide/autoscaling.html#cluster-autoscaler
它还提供了有关禁用Pod收回的参考
在负载下,我们仍然看到safe-to-evit注解没有被遵守,并将此报告给Amazon AWS。通过额外的调试,我发现尽管EKS忽略了具有safe-to-evit的节点,但EKS仍看到托管pod的节点消失。EKS和EC2之间可能存在互操作性问题。在此问题得到解决之前,我正在考虑使用Fargate作为备用自动定标器。

m1m5dgzv

m1m5dgzv3#

我们与亚马逊支持部门合作解决了这个问题。最终的解决方案离@lub0v答案不远,但仍然缺少一个组件。
我们的EKS系统只有一个管理多个可用性区域的节点组。相反,我为每个可用性区域部署了一个节点组。这样做之后,TerminationGracePeriod就得到了遵守。
另外,不要忘记我之前添加的答案,确保pod注解包含设置为false的safe-to-evict
最后,如果您希望在升级过程中部署相同数量的节点,请在集群自动缩放器命令行参数中使用--balance-similar-node-groups。
自动缩放参考:https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md

相关问题