在Kubernetes中使用podAntiAffinity排除特定节点

149次阅读
没有评论

问题描述

在使用Kubernetes提交作业时,有一个需求是希望在特定的一组节点上排除部署。这组节点目前没有不同的标签来区分它们,因此我们只能通过主机名来排除它们(目前)。
所有关于使用 podAntiAffinity 的示例都使用了 labelSelector,它期望在Pod上有一个标签来区分它。
那么,我如何限制我的作业只在特定的一组节点上部署呢?从文档中抓取的最接近的示例如下,但不起作用:

affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:               <--- 这是错误的,这里没有标签
      matchExpressions:
      - key: "kubernetes.io/hostname"
        operator: In
        values:
          - hostname1
          - hostname2

解决方案

请注意以下操作可能涉及版本差异及风险,建议在操作前备份。
在Kubernetes中,要在提交作业时排除特定的一组节点,应使用 Node Affinity,它在概念上类似于 nodeSelector。它允许你基于节点上的标签来约束Pod可调度的节点,你应该能够使用主机名作为标签。

以下是一个示例,我运行一个带有节点亲和性定义的作业,其目标是在我的集群的node-01上启动5个任务:

apiVersion: batch/v1
kind: Job
metadata:
  labels:
    run: busybox
  name: busybox
spec:
  completions: 5
  template:
    metadata:
      labels:
        run: busybox
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/hostname
                operator: In
                values:
                - k8s-node01
      containers:
      - image: busybox
        name: busybox
        resources: {}
      restartPolicy: OnFailure

在这个示例中,我们定义了一个作业,设置了5个完成任务。在作业的Pod模板中,我们使用了 affinitynodeAffinity 来指定节点亲和性。在 requiredDuringSchedulingIgnoredDuringExecution 部分,我们使用 nodeSelectorTerms 来设置节点选择条件,这里是通过 matchExpressions 使用 kubernetes.io/hostname 来选择特定的节点。

通过这种方式,我们可以确保作业只在具有特定主机名的节点上运行。

请注意,节点亲和性并不能保证节点的可用性。如果在特定节点上需要等待某些服务准备就绪,还需要相应的等待逻辑来保证作业的正确执行。

结果示例
以下是在示例中运行作业后的结果:

$ kubectl get all -o wide
NAME                READY   STATUS      RESTARTS   AGE     IP               NODE         NOMINATED NODE   READINESS GATES
pod/busybox-2gdp6   0/1     Completed   0          3m20s   192.168.85.204   k8s-node01   <none>           <none>
pod/busybox-l654d   0/1     Completed   0          3m55s   192.168.85.201   k8s-node01   <none>           <none>
pod/busybox-n7dbr   0/1     Completed   0          3m29s   192.168.85.203   k8s-node01   <none>           <none>
pod/busybox-pfc79   0/1     Completed   0          4m11s   192.168.85.200   k8s-node01   <none>           <none>
pod/busybox-r4xln   0/1     Completed   0          3m16s   192.168.85.205   k8s-node01   <none>           <none>

在上面的示例中,我们可以看到作业的5个任务都在k8s-node01节点上完成。

通过使用节点亲和性,你可以有效地限制作业只在特定的一组节点上运行,从而满足你的需求。

正文完