如何部署pod是重要的集群的调度机制,合理的配置pod调度机制可以实现资源最大化利用。
调度策略 | 匹配标签 | 操作符 | 拓扑域 | 调度目标 |
---|---|---|---|---|
node的亲和性 | 主机标签 | In、NotIn、Exists、DoesNotExist、Gt、Lt | 不支持 | 指定主机 |
pod的亲和性 | pod的标签 | In、NotIn、Exists、DoesNotExist | 支持 | pod和指定标签的pod部署在同一拓扑域中 |
pod的反亲和性 | pod的标签 | In、NotIn、Exists、DoesNotExist | 支持 | pod和指定标签的pod部署在不同的拓扑域中 |
拓扑域:k8s集群节点当中的一个组织结构,可以更具节点的物理关系或者逻辑关系进行划分。可以用来表示节点之间的空间关系。网络关系或者其他类型的关系。
这里的亲和性反亲和性都指的是标签。
node匹配的是主机的标签而pod匹配的是pod自己的标签
策略部署实验
这里使用硬策略
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
app: nginx2
template:
metadata:
creationTimestamp: null
labels:
app: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx2
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: test1
#topologyKey:指定拓扑域的关键字段
#表示我正在使用test1作为拓扑域的关键字
#这个test1一般是节点标签。
#表示希望把pod调度到包含有app标签的pod。他的值为nginx在test1的拓扑域上的节点
使用Exists包含类型:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
app: nginx2
template:
metadata:
creationTimestamp: null
labels:
app: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx2
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: Exists
topologyKey: test1
#topologyKey:指定拓扑域的关键字段
#表示我正在使用test1作为拓扑域的关键字
#这个test1一般是节点标签。
#表示希望把pod调度到包含有app标签的pod。他的值为nginx在test1的拓扑域上的节点
使用DoesNotExist不包含:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
test: nginx
name: nginx
spec:
replicas: 3
selector:
matchLabels:
test: nginx
template:
metadata:
creationTimestamp: null
labels:
test: nginx
spec:
containers:
- image: nginx:1.22
name: nginx
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: DoesNotExist
topologyKey: test3
#topologyKey:指定拓扑域的关键字段
#表示我正在使用test1作为拓扑域的关键字
#这个test1一般是节点标签。
#表示希望把pod调度到包含有app标签的pod。他的值为nginx在test1的拓扑域上的节点
#这里DoesNotExists表示不包含key值为app还必须满足在包含test1的拓扑域中
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
test: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
test: nginx2
template:
metadata:
creationTimestamp: null
labels:
test: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx2
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: DoesNotExist
topologyKey: test1
pod的反亲和性
这里使用软策略:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
test: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
test: nginx2
template:
metadata:
creationTimestamp: null
labels:
test: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx2
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx1
topologyKey: test1
这里使用硬策略:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
test: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
test: nginx2
template:
metadata:
creationTimestamp: null
labels:
test: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx2
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx1
topologyKey: test1
特点:
-
pod的亲和性策略。在配置时,必须要加上拓扑域的关键字topologkey指向的是节点标签
-
pod亲和性的策略也分为硬策略和软策略
-
pod亲和性的notin可以替代反亲和性
-
pod亲和性主要是为了把相关联的pod组件部署在同一节点上。例如:LNMP
污点和容忍
污点和容忍可以配合node的亲和性一起使用。
污点是node的调用机制。不是pod的
被设置为污点的节点不会部署pod
污点和亲和性相反。亲和性是尽量选择和一定选择。
污点的节点一定不被选择。
taint(污点)有三种策略:
-
NoSchedule:k8s不会把pod调度到这个节点上。
-
PreferNoSchedule:这个污点类型表示尽量避免把pod部署在该节点上。不是一定(master节点的污点就是这个类型在一定程度上提高资源利用率)
-
NoExecute:这个污点类型表示k8s将会把该节点上的pod驱逐出去。也不会调度到这个节点。
基于控制器创建的pod虽然被驱逐,但是会在其他节点上重新部署。
如果是自主pod将会被直接杀死
过滤污点
kubectl describe nodes master01 | grep -i taints
#查看污点
kubectl taint nodes 主机名 node-role.kubernetes.io/master:NoSchedule-
#过滤并删除污点
设置污点
kubectl taint node node01 key=1:NoSchedule
#key=1设置标签的值
#:NoSchedule并将这个值与污点做映射
kubectl taint node node01 key:NoSchedule-
#删除污点
PreferNoSchedule
kubectl taint node node02 key=1:PreferNoSchedule
NoExecute(驱逐):
kubectl taint node node02 key=1:NoExecute
所有的pod都会被驱逐和命名空间无关。所有的pod都会被驱逐。只有组件pod还在。
不论创建方式是什么都会被驱逐。系统集群组件不会被驱逐。
所有的pod都会被驱逐和命名空间无关。所有的pod都会被驱逐。基于控制器创建的pod会驱逐到其他节点上重新部署。自主创建的将直接被杀死。系统集群组件不会被驱逐。
容忍
即使节点上设置了污点。有了容忍机制,依然可以在设置为污点的节点上部署pod
配置容忍
容忍NoSchedule举例:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
test: nginx2
name: nginx2
spec:
replicas: 6
selector:
matchLabels:
test: nginx2
template:
metadata:
creationTimestamp: null
labels:
test: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx2
tolerations:
#tolerations:表示容忍
- key: key
#这里的key是节点的标签名
operator: Equal
value: "1"
effect: NoSchedule
#effect:表示对应的污点类型。必须要和节点的污点保持一致
#表示容忍节点上的标签是key。对应的标签值是1
容忍NoExecute举例:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
test: nginx2
name: nginx2
spec:
replicas: 6
selector:
matchLabels:
test: nginx2
template:
metadata:
creationTimestamp: null
labels:
test: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx2
tolerations:
- key: key
#tolerations:表示容忍
#这里的key是节点的标签名
operator: Equal
value: "1"
effect: NoExecute
tolerationSeconds: 36
#effect:表示对应的污点类型。必须要和节点的污点保持一致
#表示容忍节点上的标签是key。对应的标签值是1
#tplerationSeconds:设置节点可以容忍多长时间。
设置容忍策略36秒后
时间到期后将会销毁并且拉起新的容器
特殊情况:NoExecute依然可以部署pod但是有生命周期。时间一到pod将会被销毁。生命周期结束之后,会驱逐一部分pod到其他节点。
用于该节点维护完毕,测试以下节点的工作是否正常
不指定key实验举例:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
test: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
test: nginx2
template:
metadata:
creationTimestamp: null
labels:
test: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx2
tolerations:
- operator: Exists
effect: NoSchedule
#如果没有声明key和value。将会容忍所有污点的key。
#key对应节点的污点类型是NoSchedule
没有key。他不会匹配节点的标签。他会容忍所有污点。但是类型是指定的类型。
指定key不指定effect实验举例:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
test: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
test: nginx2
template:
metadata:
creationTimestamp: null
labels:
test: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx2
tolerations:
- key: key
operator: Exists
#指定key没有设置effect:容忍污点的类型
#他将会容忍所有节点的所有污点类型
指定节点的标签值。但是不指定污点类型。那么所有节点上只要包含了这个指定的标签名,那么它可以容忍所有的污点
pod的亲和性和反亲和性以及污点和容忍的作用就是通过判断条件选择node节点来部署pod。选择一个期望的节点来部署pod
多个master节点的情况:
,node-role.kubernetes.io/master=:PreferNoSchedule
#尽量不往master节点上部署pod。但是不是一定。这样可以防止资源浪费。同样也可也自定义一个标签。
业务维护的情况:
当node02需要维护两个小时,但是节点上还有业务pod在运行。
这个时候就需要把这个节点的污点设置为:NoExecute(驱逐)污点类型。
我们部署pod一般都是使用deployment部署,会在其他的节点重启杀死,并不是被杀死
但是自主式的pod会被删除
一旦节点恢复就把污点去除
cordon和drain
cordon
cordon:可以直接把节点标记为不可用状态
kubectl cordon 节点名称
#直接把节点标记为不可用状态
kubectl uncordon 节点名称
#取消标记为不可用状态
drain
drain:排水。把节点下的pod全部转移到其他的node节点上运行。
-
一旦执行了drain。被执行的节点会变成不可调度状态。
-
会驱逐该节点上的所有pod
kubectl drain 节点名称 --ignore-daemonsets --delete-local-data --force
#drain:开始标记node节点为不可调度。然后驱逐pod
#--ignore-daemonsets:表示忽视。会无视daemonsets部署的pod。他还会在原节点上。
#--delete-local-data:如果有本地挂载卷的pod将会被强制杀死
#--force:强制释放不是控制器管理的pod
#是控制器创建的将会被驱逐。不是控制器创建的将会被杀死
#daemonsets一般部署的都是重要的后台系统pod。所以会忽略
kubectl uncordon 节点名称
#取消标记驱逐节点