集群调度:
schedule的调度算法。
预算策略:过滤出合适的节点
优先策略:
选择部署的节点
nodeName:硬匹配,不走调度策略。node01.
nodeSelector:根据节点的标签选择,会走调度算法。
只要是走调度算法,在不满足策略的情况下,所有的pod都是Pengding
node节点的亲和心:
硬策略:必须一定满足的条件。匹配原主也是根据节点的标签。
软策略:尽量满足你的要求,而不是一定满足。
如何部署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自己的标签
pod的亲和性
硬策略:
in
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx1name: nginx1
spec:replicas: 3selector:matchLabels:app: nginx1template:metadata:labels:app: nginx1spec:containers:- image: nginx:1.22.0name: nginxaffinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- nginxtopologyKey: test#硬策略:表示部署在 node节点标签是test 且有 pod标签是app,app为nginx的节点
NotIN
apiVersion: apps/v1
kind: Deployment
metadata:labels:
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx1name: nginx1
spec:replicas: 3selector:matchLabels:app: nginx1template:metadata: labels:app: nginx1spec: containers:- image: nginx:1.22.0name: nginx affinity:podAffinity: requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions: - key: appoperator: NotInvalues:- nginxtopologyKey: test#硬策略:表示部署在node节点标签是test 且有 pod标签是app,app不为nginx的节点
exists
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx2name: nginx2
spec:replicas: 3selector:matchLabels:app: nginx2template:metadata:labels: app: nginx2 spec:containers:- image: nginx:1.22.0name: nginx2affinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector: matchExpressions:- key: appoperator: ExiststopologyKey: test#硬策略:表示部署在node节点标签是test 且有 pod标签是app
软策略
Exists
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx3name: nginx3
spec:replicas: 3selector:matchLabels:app: nginx3template:metadata:labels:app: nginx3spec:containers:- image: nginx:1.22.0name: nginx3affinity:podAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 1podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: ExiststopologyKey: test#软策略:表示部署在node节点标签是test 且 pod标签是app
DoesNotExist
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx3name: nginx3
spec:replicas: 3selector:matchLabels:app: nginx3template:metadata:labels:app: nginx3spec:containers:- image: nginx:1.22.0name: nginx3affinity:podAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 1podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: DoesNotExisttopologyKey: test#软策略:表示部署在node节点标签是test 且有 pod标签不是app
反亲和性
硬策略
IN
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx2name: nginx2
spec:replicas: 3selector:matchLabels:app: nginx2template:metadata:labels:app: nginx2spec:containers:- image: nginx:1.22.0name: nginx2affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- nginxtopologyKey: test#反亲和性---硬策略in:这里指test节点中含有app=nginx标签不部署服务
也就是说:除了指定声明的不部署服务,其他的节点部署
NotIn
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx2name: nginx2
spec:replicas: 3selector:matchLabels:app: nginx2template:metadata:labels:app: nginx2 spec: containers:- image: nginx:1.22.0name: nginx2affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: NotInvalues:- nginxtopologyKey: test
Exists
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx2name: nginx2
spec:replicas: 3selector:matchLabels:app: nginx2template:metadata:labels:app: nginx2spec:containers:- image: nginx:1.22.0name: nginx2affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: ExiststopologyKey: test#反亲和性---硬策略exists:这里指test节点中含有app标签不部署服务也就是说:除了此处声明的不部署服务,其他的节点部署
DoesNotExist
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx2name: nginx2
spec:replicas: 3selector:matchLabels:app: nginx2template:metadata:labels:app: nginx2spec:containers:- image: nginx:1.22.0name: nginx2affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: DoesNotExisttopologyKey: test#反亲和性---硬策略DoesNotExist:这里指test节点中不含有app标签不部署服务也就是说:除了此处声明的不部署服务,其他的节点部署
软策略
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx2name: nginx2
spec:replicas: 3selector:matchLabels:app: nginx2template:metadata:labels:app: nginx2spec:containers:- image: nginx:1.22.0name: nginx2affinity:podAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 1podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: NotInvalues:- nginxtopologyKey: test
#并非强制,经过预先策略、优先策略后,满足条件就执行并非一定要,只是希望
注意点:
-
pod的亲和性策略。在配置时,必须要加上拓扑域的关键字topologkey指向的是节点标签
-
pod亲和性的策略也分为硬策略和软策略
-
pod亲和性的notin可以替代反亲和性
-
pod亲和性主要是为了把相关联的pod组件部署在同一节点上。例如:LNMP
污点和容忍
污点:taint是定义在node节点之上的键值型属性数据,用于让node节点拒绝将pod调度运行于其上。
- 污点和容忍可以配合node的亲和性一起使用。
- 污点是node的调用机制,不是pod的
- 被设为污点的节点,不会部署pod
- 污点和亲和性相反,亲和性是尽量选择 和 一定选择
- 污点的节点一定不被选择
taints三种类型
类型 | 说明 |
NoSchedule (一定是) | k8s不会把pod调度到这个节点上 |
PreferNoSchedule (希望是,但不一定。) | 如果污点类型是它,尽量避免把pod部署在该节点上。 (master节点的污点就是这个类型在一定程度上提高资源利用率) |
NoExecute (驱逐) | 如果污点类型是它,k8s将会把该节点上的pod驱逐出去,而且也不会调度到这个节点。 |
查看污点
kubectl describe nodes 主机名 | grep -i taints
kubectl describe nodes master01 | grep -i taints设置污点
kubectl taint node 主机名 key=1:NoSchedule
#key=1设置标签的值
#:NoSchedule并将这个值与污点做映射
kubectl taint node node01 key=1:NoSchedule删除污点
kubectl taint node 主机名 标签:主机污点类型-
kubectl taint node node01 key:NoSchedule-
驱逐的情况下:
1、基于控制器创建的pod,虽然被驱逐,会在其他节点重新部署
自主pod会被直接杀死
2、应用场景:节点服务器需要维护,服务器关机,节点上的pod会失效。在工作中,我们主要部署pod的方式控制器部署。deployment最多的。一旦节点设置为驱逐,控制器创建的pod会在其他节点重新部署。
3、所有的pod都会被驱逐,跟命名空间无关,所有的一切都会被驱逐。
4、不论你的创建方式是什么,都会被驱逐
5、系统集群组件(kube-proxy)不会被驱逐
NoExecute(驱逐):
kubectl taint node node02 key=1:NoExecute
容忍:
即使节点上设置了污点,有了容忍机制,依然可以在设置为污点的节点上部署pod
特殊情况:
NoExecute依然可以部署pod,但是有生命周期,时间一到,pod会被销毁然后重新拉起。
生命周期结束之后,会驱逐一部分pod到其他节点。有的节点还是会保留在污点节点上。
节点维护完毕,测试一下节点的挂载是否正常。
容忍配置
例NoSchedule
apiVersion: apps/v1
kind: Deployment
metadata:creationTimestamp: nulllabels:test: nginx4name: nginx4
spec:replicas: 6selector:matchLabels:test: nginx4template:metadata:creationTimestamp: nulllabels:test: nginx4spec:containers:- image: nginx:1.22name: nginx4tolerations:
#tolerations:表示容忍- key: app
#这里的key是节点的标签名operator: Equalvalue: "1"effect: NoSchedule
#effect:表示对应的污点类型。必须要和节点的污点保持一致
#表示容忍节点上的标签是key。对应的标签值是1
例NoExecute
apiVersion: apps/v1
kind: Deployment
metadata:creationTimestamp: nulllabels:test: nginx2name: nginx2
spec:replicas: 6selector:matchLabels:test: nginx2template:metadata:creationTimestamp: nulllabels:test: nginx2spec:containers:- image: nginx:1.22name: nginx2tolerations:- key: keyoperator: Equalvalue: "1"effect: NoExecutetolerationSeconds: 36
#effect:表示对应的污点类型。必须要和节点的污点保持一致
#表示容忍节点上的标签是key。对应的标签值是1
#tplerationSeconds:设置节点可以容忍多长时间,单位为秒
不指定key
apiVersion: apps/v1
kind: Deployment
metadata:creationTimestamp: nulllabels:app: nginxname: nginx
spec:replicas: 6selector:matchLabels:app: nginxtemplate:metadata:creationTimestamp: nulllabels:app: nginxspec:containers:- image: nginx:1.22name: nginxtolerations:- operator: Existseffect: NoSchedule
#如果没有声明key和value。将会容忍所有污点的key。
##key对应节点的污点类型是NoSchedule
没有key,不匹配节点标签,容忍所有污点,但是类型是指定的类型。
指定节点的标签值(key),但是不指定污点的类型(effect)
apiVersion: apps/v1
kind: Deployment
metadata:creationTimestamp: nulllabels:app: nginxname: nginx
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:creationTimestamp: nulllabels:app: nginxspec:containers:- image: nginx:1.22name: nginxtolerations:- key: keyoperator: Exists
#指定key没指定effect,所有节点上只要包含了这个指定的标签名,可以容忍所有的污点
指定节点的标签值,但是不指定污点的类型,那么所有节点上只要包含了这个指定的标签名,可以容忍所有的污点
总结:pod的亲和性和反亲和性
污点和容忍
工作内容:任何选择node节点的部署pod
多个master节点:
kubectl taint node master节点名称 node-role.kubernetes.io/master=:PreferNoSchedule
尽量不往master节点上部男pod,但是不是一定的。防止资源浪费。自定义一个标签
业务维护:
node02需要维护2小时,但这个节点的业务pod在运行。
就需要把这个节点的污点设置为:NoExeccute
我们部署pod一般都使用deployment部署,会在其他的重新部署,并不是被杀死自主式的pod会被杀死。
自主式的pod会被杀死。
一旦节点恢复,要把污点去除。
cordon和drain
cordon
cordon:可以直接把节点标记为不可用状态
设置为不可调度状态:
kubectl cordon 节点名
kubectl cordon master01
取消不可调度状态
kubectl uncordon 节点名
kubectl uncordon master01
drain
drain:排水,把该节点下的pod全部转移到其他的node节点上运行。
1、一旦执行drain,被执行的节点会变成不可调度的状态
2、会驱逐该节点上的所有pod
设置驱逐节点
kubectl drain node02 --ignore-daemonsets --delete-emptydir-data --force#drain:开始标记node节点为不可调度。然后驱逐pod
#--ignore-daemonsets:表示忽视。会无视daemonsets部署的pod。他还会在原节点上。
#--delete-local-data:如果有本地挂载卷的pod将会被强制杀死
#--force:强制释放不是控制器管理的pod
#是控制器创建的将会被驱逐。不是控制器创建的将会被杀死
#daemonsets一般部署的都是重要的后台系统pod。所以会忽略
取消标记驱逐节点
kubectl uncordon 节点名
kubectl uncordon master01