为什么 kubernetes 调度程序忽略 nodeAffinity?

Why kubernetes scheduler ignores nodeAffinity?

我使用 kops 将 1.12 版 kubernetes 集群部署到 aws

集群有几个节点标有标签'example.com/myLabel',取值a、b、c、d

例如:

Node name          example.com/myLabel
instance1          a
instance2          b
instance3          c
instance4          d

并且有一个测试部署

apiVersion: apps/v1
kind: Deployment
metadata:
 name: test-scheduler
spec:
 replicas: 6
 selector:
   matchLabels:
     app: test-scheduler
 template:
   metadata:
     labels:
       app: test-scheduler
   spec:
     tolerations:
       - key: spot
         operator: Exists
     affinity:
       nodeAffinity:
         preferredDuringSchedulingIgnoredDuringExecution:
         - preference:
             matchExpressions:
             - key: example.com/myLabel
               operator: In
               values:
               - a
           weight: 40
         - preference:
             matchExpressions:
             - key: example.com/myLabel
               operator: In
               values:
               - b
           weight: 35
         - preference:
             matchExpressions:
             - key: example.com/myLabel
               operator: In
               values:
               - c
           weight: 30
         - preference:
             matchExpressions:
             - key: example.com/myLabel
               operator: In
               values:
               - d
           weight: 25
     containers:
     - name: a
       resources:
         requests:
           cpu: "100m"
           memory: "50Mi"
         limits:
           cpu: "100m"
           memory: "50Mi"
       image: busybox
       command:
         - 'sleep'
         - '99999'

根据文档,每个可用于调度 pod 的节点都必须存在 nodeAffinity,并选择具有最大权重和的节点。

我希望所有 pods 都被安排到标签为“a”的节点 instance1,但在我的例子中,节点是随机选择的。

比如这里部署的6pods计划的5个节点,包括another1和another2个节点,根本不包含我的label(还有一个节点有这个label的值为'd'):

NODE        LABEL
another1    NONE
node1        a
node2        b
node3        c
another2    NONE

所有节点都有容量,它们可用并且可以运行 pods

我有 2 个问题

  1. 为什么会这样?

  2. k8s 调度程序在哪里记录有关如何为 pod 分配节点的信息?事件不包含此信息并且主节点上的调度程序日志为空

更新:

我的节点包含正确的标签

example.com/myLabel=a
example.com/myLabel=b
example.com/myLabel=c
example.com/myLabel=d

如果您在节点上放置一个仅包含该值的标签,则该标签将不起作用,您必须在每个节点上放置一个带有标签 key=value 的标签,例如来自我的一个集群在 GCP 上,我通过在一个节点上执行 kubectl describe 获得了这个:

Labels:         beta.kubernetes.io/arch=amd64
                beta.kubernetes.io/fluentd-ds-ready=true
                beta.kubernetes.io/instance-type=n1-standard-2
                beta.kubernetes.io/os=linux

您必须按以下方式正确放置标签:

example.com/myLabel=a

至此,您的节点已正确分类

preferredDuringSchedulingIgnoredDuringExecution 只是意味着调度程序会将您设置的权重添加到它用来选择要调度到哪个节点的算法中。这不是硬性规定,而是首选规则。

根据您设置的权重,您将获得稍微均匀的分布。在开始看到您想要的价差之前,您需要有非常大的样本量。

请记住,"weight"不仅取决于您设置的亲和力,节点的其他因素也有其自身的权重。如果想更清楚地看到效果,请使用每个affinity之间更大的权重差异