10

我正在运行一个带有Autoscaler pod 的 Kubernetes 集群(AWS EKS one),因此该集群将根据集群内的资源请求自动扩展。

此外,当负载减少时,集群将减少节点数量。正如我所观察到的,Autosclaer 可以删除此过程中的任何节点。

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

有没有办法实现这个要求。请给出你的想法。

4

3 回答 3

11

您可以使用"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
...
于 2020-09-13T13:51:16.130 回答
3

您应该设置一个按标签引用特定pod 的pod 中断预算。例如,如果您想确保至少有一个 Jenkins 工作容器始终在运行,您可以创建一个 PDB,例如

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

(改编自Kubernetes 文档中指定中断预算中的基本示例)。

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

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

当您在问题中说“Jenkins pod”时,这还有另外两个重要含义。一是您应该几乎总是使用更高级别的对象(例如 Deployment 或 StatefulSets)而不是裸 Pod 来配置您的应用程序。另一个是,如果没有别的,运行多个副本以实现冗余通常很有用。即使没有集群自动扩缩器,磁盘也会出现故障,Amazon 偶尔会随意停用 EC2 实例,否则节点可能会在您无法控制的情况下脱机;您通常不希望集群中只运行一个副本,尤其是当您将其视为一项关键服务时。

于 2020-09-13T16:42:49.003 回答
0

github 上的 autoscaler FAQ 中,您可以阅读以下内容:

哪些类型的 pod 可以阻止 CA 删除节点?

  • 具有限制性 PodDisruptionBudget 的 Pod。
  • Kube 系统 pod:
    • 默认不在节点上运行,*
    • 没有设置pod 中断预算 ,或者他们的 PDB 过于严格(自 CA 0.6 起)。
  • 不受控制器对象支持的 Pod(因此不是由部署、副本集、作业、有状态集等创建的)。*
  • 具有本地存储的 Pod。*
  • 由于各种限制(缺乏资源、不匹配的节点选择器或亲和性、匹配的反亲和性等)而无法移动到其他地方的 Pod
  • 具有以下注释集的 Pod:"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"

*除非 pod 有以下注解(CA 1.0.3 或更高版本支持):"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"

于 2020-09-14T13:20:17.413 回答