如何确保 Kubernetes autoscaler 不会删除运行特定 pod 的节点

How to make sure Kubernetes autoscaler not deleting the nodes which runs specific pod

我是 运行 一个带有 Autoscaler pod 的 Kubernetes 集群(AWS EKS 集群) 这样集群将根据集群内的资源请求自动缩放。

此外,当负载降低时,集群将缩减节点数。据我观察,Autosclaer可以删除这个过程中的任何节点。

我想控制这种行为,例如要求 Autoscaler 停止删除运行特定 pod 的节点。 例如,如果一个节点运行 Jenkins pod,Autoscaler 应该跳过该节点并从集群中删除其他匹配的节点。

请问有什么办法可以达到这个要求。请说出你的想法。

您可以使用"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"

...

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

     spec:
       nodeSelector:
         failure-domain.beta.kubernetes.io/zone: us-west-2b
...

您应该设置一个 pod disruption budget,通过标签引用特定的 pods。例如,如果你想确保始终至少有一个 Jenkins worker pod 运行ning,你可以创建一个像

这样的 PDB
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: jenkins-worker-pdb
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: jenkins
      component: worker

(改编自 Kubernetes 文档中 Specifying a Disruption Budget 中的基本示例)。

这样做不会阻止节点被销毁;集群自动缩放器仍然可以自由地缩小规模。它会做的是暂时延迟销毁节点,直到可以再次满足中断预算。

例如,假设您已将 Jenkins 设置配置为拥有三个工作人员。两个被安排在同一个节点上,自动缩放器使该节点离线。普通的 Kubernetes Deployment 系统会在仍然存在的节点上创建两个新的副本。如果自动缩放器还决定要销毁拥有最后一个工作人员的节点,则上面的 pod 中断预算将阻止它这样做,直到至少有一个其他工作人员 运行ning.

当您在问题中说“Jenkins pod”时,还有另外两个重要的含义。一是您应该几乎总是使用 higher-level 对象(如 Deployments 或 StatefulSets)来配置您的应用程序,而不是裸露的 Pods。另一个是,如果没有别的,它通常对 运行 多份事物的冗余有用。即使没有集群自动缩放器,磁盘也会出现故障,亚马逊偶尔会任意停用 EC2 实例,否则节点可能会在您的控制之外脱机;您通常不希望集群中只有一个 运行ning 副本,尤其是当您将其视为一项关键服务时。

autoscaler FAQ on github中您可以阅读以下内容:

What types of pods can prevent CA from removing a node?

  • Pods with restrictive PodDisruptionBudget.
  • Kube-system pods that:
    • are not run on the node by default, *
  • Pods that are not backed by a controller object (so not created by deployment, replica set, job, stateful set etc). *
  • Pods with local storage. *
  • Pods that cannot be moved elsewhere due to various constraints (lack of resources, non-matching node selectors or affinity, matching anti-affinity, etc)
  • Pods that have the following annotation set: "cluster-autoscaler.kubernetes.io/safe-to-evict": "false"

*Unless the pod has the following annotation (supported in CA 1.0.3 or later): "cluster-autoscaler.kubernetes.io/safe-to-evict": "true"