这里介绍Kubernetes调度中的节点亲和性
楔子
节点亲和性,可以实现根据节点上的标签来决定Pod可以调度到哪些节点上。所以其效果上和nodeSelector节点选择器是类似地,都是功能会更加强大。具体地,节点亲和性有两种:
- requiredDuringSchedulingIgnoredDuringExecution:requiredDuringScheduling表明其是一个强制性的调度,调度器只有在规则被满足的时候才能执行调度;而IgnoredDuringExecution则表明其不会影响已在节点上运行的Pod
- preferredDuringSchedulingIgnoredDuringExecution:preferredDuringScheduling表明其是一个偏好性的调度,调度器会根据偏好优先选择满足对应规则的节点来调度Pod。但如果找不到满足规则的节点,调度器则会选择其他节点来调度Pod。而IgnoredDuringExecution则表明其不会影响已在节点上运行的Pod
强制性调度
这里我们使用了一个包含3个工作节点的K8s集群。同时为了便于验证调度结果,这里我们选择使用DaemonSet来进行测试。因为对于DaemonSet而言,其原本应该在每个工作节点上都需要部署一个Pod。这里我们使用requiredDuringSchedulingIgnoredDuringExecution来说明实现强制性调度。需要注意的是,对于nodeSelectorTerms下的多个matchExpressions而言,他们的关系是OR或
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| apiVersion: apps/v1 kind: DaemonSet metadata: name: my-app-1 spec: selector: matchLabels: app: my-app-1 template: metadata: labels: app: my-app-1 spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: Country operator: In values: - CN - matchExpressions: - key: Author operator: In values: - Aaron containers: - name: my-app-1 image: tutum/dnsutils command: - sleep - infinity
|
效果如下所示。Pod被调度到标签信息满足 Country等于CN 或 Author等于Aaron 的节点上
对于matchExpressions下的多个条件而言,他们的关系是AND与。与此同时,operator操作符可以使用In、NotIn、Exists、DoesNotExist、Gt大于、Lt小于。其中,NotIn、DoesNotExist操作符可用于实现节点的反亲和性。示例配置如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| apiVersion: apps/v1 kind: DaemonSet metadata: name: my-app-2 spec: selector: matchLabels: app: my-app-2 template: metadata: labels: app: my-app-2 spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: Country operator: NotIn values: - CN - key: Author operator: NotIn values: - Aaron containers: - name: my-app-2 image: tutum/dnsutils command: - sleep - infinity
|
效果如下所示。Pod被调度到标签信息满足 Country不等于CN 且 Author不等于Aaron 的节点上
偏好性调度
这里我们使用了一个包含3个工作节点的K8s集群。这里我们使用preferredDuringSchedulingIgnoredDuringExecution来说明实现偏好性调度。可通过权重值来定义对节点偏好,权重值越大优先级越高。其中,权重范围: 1~100。需要注意的是,对于matchExpressions下的多个条件而言,他们的关系是AND与。配置文件如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| apiVersion: apps/v1 kind: Deployment metadata: name: my-app-3 spec: replicas: 10 selector: matchLabels: app: my-app-3 template: metadata: labels: app: my-app-3 spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 80 preference: matchExpressions: - key: Country operator: In values: - USA - key: Author operator: In values: - Aaron - weight: 40 preference: matchExpressions: - key: Country operator: In values: - CN containers: - name: my-app-3 image: tutum/dnsutils command: - sleep - infinity
|
其中可通过-o custom-columns选项实现自定义查看信息及别名
1 2
| kubectl get pod -o custom-columns=PodName:.metadata.name,NodeName:.spec.nodeName
|
效果如下所示。可以看到其会倾向于将Pod调度到偏好的节点上。但如果实在没有符合偏好的节点,调度器也会选择其他节点对Pod进行调度
参考文献
- Kubernetes in Action中文版 Marko Luksa著
- 深入剖析Kubernetes 张磊著