Kubernetes调度之节点亲和性

这里介绍Kubernetes调度中的节点亲和性

abstract.png

楔子

节点亲和性,可以实现根据节点上的标签来决定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
# Pod模板
template:
metadata:
labels:
app: my-app-1
spec:
# 亲和性
affinity:
# 节点亲和性规则
nodeAffinity:
# 强制性的调度规则, 但不会影响已在节点上运行的Pod
requiredDuringSchedulingIgnoredDuringExecution:
# 要求该节点的标签信息满足 Country等于CN 或 Author等于Aaron
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 的节点上

figure 1.jpeg

对于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
# Pod模板
template:
metadata:
labels:
app: my-app-2
spec:
# 亲和性
affinity:
# 节点亲和性规则
nodeAffinity:
# 强制性的调度规则, 但不会影响已在节点上运行的Pod
requiredDuringSchedulingIgnoredDuringExecution:
# 要求该节点的标签信息满足 Country不等于CN 且 Author不等于Aaron
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 的节点上

figure 2.jpeg

偏好性调度

这里我们使用了一个包含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:
# Pod副本数量
replicas: 10
selector:
matchLabels:
app: my-app-3
# Pod模板
template:
metadata:
labels:
app: my-app-3
spec:
# 亲和性
affinity:
# 节点亲和性规则
nodeAffinity:
# 偏好性的调度规则, 但不会影响已在节点上运行的Pod
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80 # 权重范围: 1~100, 权重值越大, 优先级越高
preference:
# 节点的标签信息满足 Country等于USA 且 Author等于Aaron, 则权重为80
matchExpressions:
- key: Country
operator: In
values:
- USA
- key: Author
operator: In
values:
- Aaron
- weight: 40
preference:
# 节点的标签信息满足 Country等于CN, 则权重为40
matchExpressions:
- key: Country
operator: In
values:
- CN
# 容器信息
containers:
- name: my-app-3
image: tutum/dnsutils
command:
- sleep
- infinity

其中可通过-o custom-columns选项实现自定义查看信息及别名

1
2
# 查看Pod的名称并定义别名为PodName、Pod所在节点的名称并定义别名为NodeName
kubectl get pod -o custom-columns=PodName:.metadata.name,NodeName:.spec.nodeName

效果如下所示。可以看到其会倾向于将Pod调度到偏好的节点上。但如果实在没有符合偏好的节点,调度器也会选择其他节点对Pod进行调度

figure 3.jpeg

参考文献

  1. Kubernetes in Action中文版 Marko Luksa著
  2. 深入剖析Kubernetes 张磊著
0%