前情回顾
预算策略:过滤出合适的节点
优选策略:选择部署的节点
nodeName:硬匹配,不走调度策略。node01.
nodeSelector:根据节点的标签选择,会走调度算法。
只要是走调度算法,在不满足预算策略的情况下,所有pod都是pending。
node节点的亲和性:硬策略和软策略
硬策略:必须一定。匹配原则:根据节点的标签
软策略:尽量满足你的要求。
pod的亲和性和反亲和性
调度策略 | 匹配标签 | 操作符 | 拓展域 | 调度目标 |
node亲和性 | 主机标签 | In,NotIn,Exists,DoesExists,Gt,Lt | 不支持 | 指定主机 |
pod亲和性 | pod的标签 | In(在),NotIn(不在),Exists(存在),DoesExists(不存在) | 支持 | pod和指定标签的pod部署在同一个拓扑域 |
pod反亲和性 | pod的标签 | In,NotIn,Exists,DoesExists | 支持 | pod和指定标签的pod部署在同一个拓扑域 |
拓扑域:k8s集群节点当中的一个组织结构,可以根据节点的物理关系或者逻辑关系进行划分。
可以用来表示节点之间的空间关系,网络关系或者其他类型的关系。
pod内的拓扑域也就是 ---> 标签
pod亲和性演示操作
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx1name: nginx1
spec:replicas: 1selector:matchLabels:app: nginx1template:metadata:labels:app: nginx1spec:containers:- image: nginx:1.22name: nginx1affinity:podAffinity:preferredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- nginx1topologyKey: test1
#toplogyKey指定拓扑域的关键字段,表示正在使用test1作为拓扑域的关键字。test1一般都是节点标签,表示希望把pod调度到包含有app标签的Pod,值为nginx1的在test1的拓扑域上的节点。
部署pod时候会遇到pending的情况,是因为指定条件没有一个可以满足!!!!
pod亲和性的软策略展示
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx1name: nginx1
spec:replicas: 3selector:matchLabels:app: nginx1template:metadata:labels:app: nginx1spec:containers:- image: nginx:1.22name: nginx1affinity:podAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 1podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: DoesNotExisttopologyKey: test3
pod的反亲和性
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx1name: nginx1
spec:replicas: 3selector:matchLabels:app: nginx1template:metadata:labels:app: nginx1spec:containers:- image: nginx:1.22name: nginx1affinity:podAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 1podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: Invalues:- nginx1topologyKey: test3
总结:反亲和性顾名思义和亲和性相反,相当于NotIn
注意点:
1.pod的亲和性策略,在配置时,必须要加上拓扑域的关键字
2.pod亲和性的策略也分为硬策略和软策略
3.pod亲和性的notin可以替代反亲和性
4.pod亲和性主要是为了把相关联的pod部署在同一个节点。
k8s中污点和容忍可以配合node的亲和性一块使用
污点与容忍的概念
节点亲和性,是Pod的一种属性(偏好或硬性要求),它使Pod被吸引到一类特定的节点。Taint 则相反,它使节点能够排斥一类特定的 Pod。
污点(Taint) 和 容忍(Toleration) 相互配合,可以用来避免 Pod 被分配到不合适的节点上。每个节点上都可以应用一个或多个 taint ,这表示对于那些不能容忍这些 taint 的 Pod,是不会被该节点接受的。如果将 toleration 应用于 Pod 上,则表示这些 Pod 可以(但不一定)被调度到具有匹配 taint 的节点上。
当前 taint effect 支持如下三个选项:
●NoSchedule:表示 k8s 将不会将 Pod 调度到具有该污点的 Node 上
●PreferNoSchedule:表示 k8s 将尽量避免将 Pod 调度到具有该污点的 Node 上
●NoExecute:表示 k8s 将不会将 Pod 调度到具有该污点的 Node 上,同时会将 Node 上已经存在的 Pod 驱逐出去
注意点:节点服务器肯定是需要维护的,服务器关机,此时节点上的pod将会失效。在工作中我们主要部署pod的方式控制器部署。尤其是deployment用的最多。一旦节点使用的是驱逐。控制器创建的pod会在其他节点重新部署。所以驱逐的应用场景:资源迁移。
1.所有的pod都会被驱逐,和命名空间无关(包括flannel等),kube-proxy是节点组件,所以他还存在。
2.不论你的创建方式是什么,都会被驱逐
污点的基本操作
格式:kubectl describe nodes <节点名称> | grep Taints
或者是kubectl describe nodes <节点名称> | grep -i taints
eg:查看master01的污点
kubectl describe nodes master01 |grep -i taints
如何设置污点
kubectl taint node node01 key=1:NoSchedulekubectl taint node node名称 名称
污点的容忍机制
容忍:即使集群上设置了污点,有了容忍机制,依然可以在设置为污点的节点上部署pod。
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx2name: nginx2
spec:replicas: 1selector:matchLabels:app: nginx2template:metadata:labels:app: nginx2spec:containers:- image: nginx:1.22name: nginx2tolerations:- key: keyoperator: Equalvalue: "1"effect: NoSchedule
容忍策略:容忍节点上的标签key,对应的标签值是1,effect就是对应的污点的类型
其他都是NoSchedule,所以无法匹配,就是pending。
污点---NoExcute
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx2name: nginx2
spec:replicas: 1selector:matchLabels:app: nginx2template:metadata:labels:app: nginx2spec:containers:- image: nginx:1.22name: nginx2tolerations:- key: keyoperator: Equalvalue: "2"effect: NoExecutetolerationSeconds: 10
到时间就会销毁,反复循环
特殊情况:NotExecute依然可以部署pod,但是有生命周期,时间一到,pod会被销毁,生命周期结束之后会驱逐一部分pod到其他节点
tolerations:- key: keyoperator: Existseffect: NoSchedule指定key的值(节点的标签值),但是不指定污点的类型,所有节点上只要包含了指定的标签名,可以容忍所有的污点tolerations:- operator: Existseffect: NoSchedule 没有key,不匹配节点的标签,容忍所有污点,但是类型是指定的类型(只要是effect指定的,我都能容忍)
总结:
多个master节点:
kubelet taint node master节点名称 node-role.kubernetes.io/master=PreferNoSchedule
尽量不往master节点上部署pod,但是不是一定的,防止资源浪费。自定义一个标签。
业务维护: node02需要维护两个小时,但是这个业务上还有pod在运行,此时就需要将这个节点的污点设置成NoExecute。
我们部署pod一般都使用deployment部署,会在其他的节点重新部署,并不是被杀死
自主式的pod会被杀死。
一旦节点恢复,一定要把污点驱逐
cordon和drain
cordon:可以直接把节点标记为不可用的状态。
kubectl get node
kubectl cordon master01
kkubectl get node
kubectl uncordon master01
drain
排水,把该节点下的节点全部转移到其他的node节点上运行。
1.一旦执行drain,被执行的节点会变成不可调度状态。
2.会驱逐该节点上的所有pod。
kubectl drain node02 --ignore-daemonsets --delete-local-data --forcedrain:排水,标记node节点为不可调度,然后驱逐pod
--ignore-daemonsets:无视daemonsets部署的pod,daemonsets部署的pod还在节点
--delete-local-data:有本地挂载卷的pod会被强制杀死
--force:强制释放不是控制器管理的pod。
还是如何管理和部署pod