【容器应用系列教程】Kubernetes调度系统
一、基于nodeName调度
指定在哪个
node
节点上,创建Pod
1.查看所有节点
[root@k8s-master ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master.linux.com Ready control-plane,master 8d v1.20.7
k8s-node01.linux.com Ready <none> 8d v1.20.7
k8s-node02.linux.com Ready <none> 8d v1.20.7
2.基于nodeName
调度
[root@k8s-master test]# vim test1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: test1-nginx
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: test1-nginx
template:
metadata:
labels:
app: test1-nginx
spec:
nodeName: k8s-node02.linux.com #指定所有Pod都运行在node02上
containers:
- name: test1-nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
[root@k8s-master test]# kubectl create -f test1.yaml
deployment.apps/test1-nginx created
3.查看Pod
可以看到所有
Pod
都跑在node02
节点上
[root@k8s-master test]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test1-nginx-5bccbd59df-cfl6v 1/1 Running 0 2m29s 192.168.242.131 k8s-node02.linux.com <none> <none>
test1-nginx-5bccbd59df-r68jk 1/1 Running 0 2m29s 192.168.242.130 k8s-node02.linux.com <none> <none>
二、基于nodeSelector
调度
1.查看所有节点的标签
[root@k8s-master test]# kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
k8s-master.linux.com Ready control-plane,master 8d v1.20.7 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master.linux.com,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=
k8s-node01.linux.com Ready <none> 8d v1.20.7 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node01.linux.com,kubernetes.io/os=linux
k8s-node02.linux.com Ready <none> 8d v1.20.7 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node02.linux.com,kubernetes.io/os=linux
2.创建基于nodeSelector
调度
[root@k8s-master test]# vim test2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: test2-nginx
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: test2-nginx
template:
metadata:
labels:
app: test2-nginx
spec:
nodeSelector: #nodeSelector调度类型
name: wsjj #在有name=wsjj的标签机器上创建
containers:
- name: test2-nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
[root@k8s-master test]# kubectl create -f test2.yaml
deployment.apps/test1-nginx created
3.查看Pod
可以看到所有
Pod
都是处于pending
等待调度状态
这是因为,在所有节点上,都没有找到name=wsjj
标签的机器
[root@k8s-master test]# kubectl get pod
NAME READY STATUS RESTARTS AGE
test2-nginx-5f89c875cf-cfl6v 0/1 Pending 0 6s
test2-nginx-5f89c875cf-r68jk 0/1 Pending 0 6s
4.手动打标签
[root@k8s-master test]# kubectl label node k8s-node01.linux.com name=wsjj
node/k8s-node01.linux.com labeled
node01
身上多了name=wsjj
的标签
[root@k8s-master test]# kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
k8s-master.linux.com Ready control-plane,master 8d v1.20.7 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master.linux.com,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=
k8s-node01.linux.com Ready <none> 8d v1.20.7 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node01.linux.com,kubernetes.io/os=linux,name=wsjj
k8s-node02.linux.com Ready <none> 8d v1.20.7 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node02.linux.com,kubernetes.io/os=linux
5.再次查看Pod
当有了标签后,
Pod
正常运行
[root@k8s-master test]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test2-nginx-5f89c875cf-cfl6v 1/1 Running 0 7m4s 192.168.201.194 k8s-node01.linux.com <none> <none>
test2-nginx-5f89c875cf-r68jk 1/1 Running 0 7m4s 192.168.201.195 k8s-node01.linux.com <none> <none>
6.删除标签
# kubectl label nodes <node_name> key-
[root@k8s-master test]# kubectl label nodes k8s-node01.linux.com name-
node/k8s-node01.linux.com labeled
可以看到即使标签被删除了,旧的Pod
不会被影响
[root@k8s-master test]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test2-nginx-5f89c875cf-cfl6v 1/1 Running 0 11m 192.168.201.194 k8s-node01.linux.com <none> <none>
test2-nginx-5f89c875cf-r68jk 1/1 Running 0 11m 192.168.201.195 k8s-node01.linux.com <none> <none>
[root@k8s-master test]# kubectl delete pod test2-nginx-5f89c875cf-cfl6v
pod "test2-nginx-5f89c875cf-cfl6v" deleted
[root@k8s-master test]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test2-nginx-5f89c875cf-7d9tj 0/1 Pending 0 17s <none> <none> <none> <none>
test2-nginx-5f89c875cf-r68jk 1/1 Running 0 12m 192.168.201.195 k8s-node01.linux.com <none> <none>
7.修改标签的值
# kubectl label nodes <node_name> key=value --overwrite
三、基于nodeAffinity
节点亲缘性
使用
nodeAffinity
可以在部署Pod
时,将Pod
调度运行到符合特定条件或不符合特定条件的节点
1.nodeAffinity
调度策略
requiredDuringSchedulingIgnoredDuringExecution
- 表示
pod
必须部署到满足条件的节点上,如果没有满足条件的节点,就不停重试。 IgnoreDuringExecution
表示pod
部署之后运行的时候,如果节点标签发生了变化,不再满足pod
指定的条件,pod
也会继续运行。
requiredDuringSchedulingRequiredDuringExecution
- 表示
pod
必须部署到满足条件的节点上,如果没有满足条件的节点,就不停重试 RequiredDuringExecution
表示pod
部署之后运行的时候,如果节点标签发生了变化,不再满足pod
指定的条件,则重新选择符合要求的节点
preferredDuringSchedulingIgnoredDuringExecution
- 表示优先部署到满足条件的节点上,如果没有满足条件的节点,就忽略这些条件,按照正常逻辑部署
preferredDuringSchedulingRequiredDuringExecution
- 表示优先部署到满足条件的节点上,如果没有满足条件的节点,就忽略这些条件,按照正常逻辑部署。
RequiredDuringExecution
表示如果后面节点标签发生了变化,满足了条件,则重新调度到满足条件的节点。
2.案例1:基于nodeAffinity
节点亲缘性调度
为node02
打标记
[root@k8s-master test]# kubectl label node k8s-node02.linux.com yewu=dev
node/k8s-node02.linux.com labeled
[root@k8s-master test]# kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
k8s-master.linux.com Ready control-plane,master 8d v1.20.7 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master.linux.com,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=
k8s-node01.linux.com Ready <none> 8d v1.20.7 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node01.linux.com,kubernetes.io/os=linux
k8s-node02.linux.com Ready <none> 8d v1.20.7 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node02.linux.com,kubernetes.io/os=linux,yewu=dev
创建Deployment
测试
apiVersion: apps/v1
kind: Deployment
metadata:
name: test3-nginx
namespace: default
labels:
app: test3-nginx
spec:
replicas: 2
selector:
matchLabels:
app: test3-nginx
template:
metadata:
labels:
app: test3-nginx
spec:
affinity:
nodeAffinity: #类型
requiredDuringSchedulingIgnoredDuringExecution: #指定策略
nodeSelectorTerms:
- matchExpressions:
- key: yewu #键
operator: NotIn #表示label的值不在某个列表中,类似取反
values:
- dev #值
containers:
- name: test3-nginx
image: nginx
ports:
- containerPort: 80
- 支持的操作符:
In
:label
的值在某个列表中NotIn
:label
的值不在某个列表中Exists
:某个label
存在DoesNotExist
:某个label
不存在Gt
:label
的值大于某个值(字符串比较)Lt
:label
的值小于某个值(字符串比较)
[root@k8s-master test]# kubectl create -f test3.yml
deployment.apps/test3-nginx created
查看结果
由于取反的原因,
node02
身上有符合要求的标签,所以取反到node01
身上创建
[root@k8s-master test]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test3-nginx-654cf47554-bzbh4 1/1 Running 0 2m34s 192.168.201.195 k8s-node01.linux.com <none> <none>
test3-nginx-654cf47554-cwggc 1/1 Running 0 2m34s 192.168.201.196 k8s-node01.linux.com <none> <none>
3.案例2:基于nodeAffinity
节点亲缘性调度
[root@k8s-master test]# vim test4.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: test4-nginx
namespace: default
labels:
app: test4-nginx
spec:
replicas: 2
selector:
matchLabels:
app: test4-nginx
template:
metadata:
labels:
app: test4-nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: yewu
operator: In
values:
- dev
containers:
- name: test4-nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
[root@k8s-master test]# kubectl create -f test4.yml
deployment.apps/test4-nginx created
查看Pod
本案例中同时设置了
requiredDuringSchedulingIgnoredDuringExecution
和preferredDuringSchedulingIgnoredDuringExecution
两种策略,表示的意思为将Pod
要调度到具有kubernetes.io/os=linux
这个标签的节点时,在满足该条件的情况下,preferredDuringSchedulingIgnoredDuringExecution
表示的意思是优先将其调度到同时具有yewu=dev
的节点上
[root@k8s-master test]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test4-nginx-5bf9894f8c-87wsf 1/1 Running 0 2m3s 192.168.242.132 k8s-node02.linux.com <none> <none>
test4-nginx-5bf9894f8c-nznnn 1/1 Running 0 2m3s 192.168.242.131 k8s-node02.linux.com <none> <none>
四、污点Taint
、容忍Toleration
Taint
和toleration
相互配合,可以用来避免pod
被分配到不合适的节点上。每个节点上都可以应用一个或多个taint
,这表示对于那些不能容忍这些taint
的pod
,是不会被该节点接受的。如果将toleration
应用于pod
上,则表示这些pod
可以被调度到具有相应taint
的节点上。
1.污点Taint
管理操作
查看Taint
污点
由于我是基于
kubeadm
部署的集群,集群会默认为Master
节点配置一个污点,防止资源被调度到Master
节点上。
[root@k8s-master test]# kubectl describe node k8s-master.linux.com | grep -i Taints
Taints: node-role.kubernetes.io/master:NoSchedule
为节点添加Taint
污点
# kubectl taint nodes <node_name> key=value:{NoSchedule|NoExecute|PreferNoSchedule}
- 污点的影响策略:
NoSchedule
- 新的不能容忍该污点的
Pod
不会再调度过来 - 但已经运行在该节点上的
Pod
不会受影响
- 新的不能容忍该污点的
NoExecute
- 新的不能容忍该污点的
Pod
不会再调度过来 - 同时该节点上的所有
Pod
都会被驱逐
- 新的不能容忍该污点的
PreferNoSchedule
- 尽量不向该节点调度
删除Taint
污点
# kubectl taint node <node_name> key:{NoSchedule|NoExecute|PreferNoSchedule}-
3.示例:为node02
添加Tatin
污点,指定策略为NoExecute
[root@k8s-master ~]# kubectl taint nodes k8s-node02.linux.com AA=10:NoExecute
可以看到node02
身上的所有Pod
都被驱逐了
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-client 1/1 Running 4 10d 10.88.0.9 k8s-node01.linux.com <none> <none>
test1-nginx-6fcf9564d5-6x8mz 0/1 ContainerCreating 0 3s <none> k8s-node01.linux.com <none> <none>
test1-nginx-6fcf9564d5-7wkhg 0/1 ContainerCreating 0 3s <none> k8s-node01.linux.com <none> <none>
test1-nginx-6fcf9564d5-c8pf9 1/1 Running 0 10m 172.168.201.231 k8s-node01.linux.com <none> <none>
test1-nginx-6fcf9564d5-fbfxp 1/1 Running 0 10m 172.168.201.230 k8s-node01.linux.com <none> <none>
test1-nginx-6fcf9564d5-j4j62 1/1 Terminating 0 10m 172.168.242.138 k8s-node02.linux.com <none> <none>
test1-nginx-6fcf9564d5-j4zkd 0/1 ContainerCreating 0 3s <none> k8s-node01.linux.com <none> <none>
test1-nginx-6fcf9564d5-lfct5 1/1 Terminating 0 10m 172.168.242.139 k8s-node02.linux.com <none> <none>
test1-nginx-6fcf9564d5-nnlml 1/1 Terminating 0 10m 172.168.242.135 k8s-node02.linux.com <none> <none>
test1-nginx-6fcf9564d5-p4nrz 0/1 ContainerCreating 0 3s <none> k8s-node01.linux.com <none> <none>
test1-nginx-6fcf9564d5-t8jdc 1/1 Terminating 0 10m 172.168.242.134 k8s-node02.linux.com <none> <none>
删除污点
# kubectl taint node 节点名 键-
[root@k8s-master ~]# kubectl taint nodes k8s-node02.linux.com AA-
4.容忍Toleration
一般容忍
Toleration
和污点Taint
是配合使用的
当用户想要在,存在Taint
污点的Node
节点上创建Pod
的时候,就需要有容忍Toleration
的存在
添加Tatin
污点
[root@k8s-master ~]# kubectl taint nodes k8s-node02.linux.com AA=10:NoExecute
创建Pod
配置容忍Toleration
策略
[root@k8s-master test]# vim test5.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: test5-nginx
namespace: default
labels:
app: test5-nginx
spec:
replicas: 2
selector:
matchLabels:
app: test5-nginx
template:
metadata:
labels:
app: test5-nginx
spec:
containers:
- name: test5-nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
tolerations:
- key: "AA"
operator: "Equal"
value: "10"
effect: NoExecute
tolerationSeconds: 30 #容忍时间可以不写
[root@k8s-master test]# kubectl create -f test5.yml
- 配置项说明:
tolerations
添加容忍策略key
指定所容忍的key
,要与对应污点的key
一致value
指定所容忍的value,要与对应污点的value
一致effect
指定所容忍的策略,一定要与污点指定的策略一致tolerationSeconds
指定容忍的超时时间,到达该时间后,Pod
将会被驱逐
容忍的匹配规则也可以写多个
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
查看Pod
[root@k8s-master ]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test1-nginx-654d4cc68c-2mh68 1/1 Running 0 6s 172.168.242.149 k8s-node02.linux.com <none> <none>
test1-nginx-654d4cc68c-8z8kw 1/1 Running 0 6s 172.168.242.147 k8s-node02.linux.com <none> <none>
删除污点Taint
[root@k8s-master ~]# kubectl taint node k8s-node02.linux.com AA-