pod的亲和性和反亲和性
拓扑域:k8s集群节点当中的一个组织结构,可以根据节点的物理关系或者逻辑关系进行划分,可以用来表示节点之间的空间关系,网格关系或者其他类型的关系。pod和指定标签的pod部署在同一拓扑域。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集群节点当中的一个组织结构,可以根据节点的物理关系或者逻辑关系进行划分,可以用来表示节点之间的空间关系,网格关系或者其他类型的关系 |
硬策略
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx1
name: nginx1
spec:
replicas: 3
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
nodeName: master01
containers:
- image: nginx:1.22
name: nginx
部署在master01上
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
app: nginx2
template:
metadata:
labels:
app: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx2
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: Exists
topologyKey: test1
#podAffinity pod亲和性
#requiredDuringSchedulingIgnoredDuringExecution: 硬策略
#operator: Exists 只要包含 - key: app
#topologkey指定拓扑域的关键字段,表示我正在使用test1作为拓扑域的关键字,test1一般是#节点标签,表示希望把pod调度到包含有app标签的pod,值为nginx1的在test1的拓扑域上的节点
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
app: nginx2
template:
metadata:
labels:
app: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx2
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: DoesNotExist
topologyKey: test1
使用requiredDuringSchedulingIgnoredDuringExecution 和 DoesNotExist ,那么就是硬策略,要求标签不能是app 亲和标签为 test1 的节点,虽然master01和node01是test1 ,但是这里标签都是app,所以都不满足
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
test: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
test: nginx2
template:
metadata:
labels:
test: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx2
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: DoesNotExist
topologyKey: test1
这里不选 标签为app的节点,三个节点都满足,亲和test1 ,只有master01和node01满足
软策略
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
test: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
test: nginx2
template:
metadata:
labels:
test: nginx2
spec:
containers:
- image: nginx:1.22
name: nginx2
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
#使用软策略必须要加权重
podAffinityTerm:
#选择倾向性
labelSelector:
matchExpressions:
#匹配条件
- key: app
operator: DoesNotExist
#选择没有app标签的节点
topologyKey: test1
#拓扑域选择test1
apiVersion: apps/v1:
表明这是一个使用 Kubernetes API 版本 apps/v1 的对象。
kind: Deployment:
定义了 Kubernetes 对象的类型,这里是一个 Deployment(部署)。
metadata:
包含 Deployment 的元信息,如标签(labels)、名称等。
labels:
为 Deployment 设置标签,这里设置了一个 "test: nginx2" 的标签。
name: nginx2:
指定 Deployment 的名称为 "nginx2"。
spec:
定义了 Deployment 的规格,包括副本数量、选择器和 Pod 模板。
replicas: 3:
指定要创建的 Pod 的副本数量为 3。
selector:
定义了标签选择器,用于选择属于该 Deployment 的 Pod。
matchLabels:
指定了匹配标签 "test: nginx2" 的 Pod。
template:
定义了创建 Pod 所使用的模板。
metadata.labels:
为 Pod 设置标签,这里设置了一个 "test: nginx2" 的标签。
spec.containers:
定义了 Pod 中包含的容器。
image: nginx:1.22:
指定了要使用的容器镜像,这里是 Nginx 1.22 版本。
name: nginx2:
指定了容器的名称为 "nginx2"。
affinity:
定义了 Pod 的亲和性规则。
podAffinity:
定义了 Pod 之间的亲和性规则,这里使用了 "preferredDuringSchedulingIgnoredDuringExecution" 策略。
preferredDuringSchedulingIgnoredDuringExecution:
定义了软调度策略,即倾向性规则。
weight: 1:
给倾向性规则设置权重,表示在调度时的优先级。
podAffinityTerm:
定义了 Pod 亲和性的条件。
labelSelector:
使用标签选择器,匹配具有 "app" 标签不存在的节点。
matchExpressions:
定义了匹配条件,这里指定 "app" 标签不存在。
key: app:
指定了要匹配的标签键。
operator: DoesNotExist:
指定了匹配操作,即 "app" 标签不存在。
topologyKey: test1:
指定了拓扑域键,这里使用 "test1"。
反亲和性软策略
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
test: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
test: nginx2
template:
metadata:
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
软策略, podAntiAffinity 反亲和性
反亲和性硬策略
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
test: nginx2
name: nginx2
spec:
replicas: 3
selector:
matchLabels:
test: nginx2
template:
metadata:
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的亲和性策略,在配置时,必须要加上拖区域的关键字topologykey指向的是节点标签 Pod亲和性策略分为硬策略和软策略 Pod亲和性可以替代反亲和性 Pod亲和性只要是为了把相关联的pod部署在同一节点,如lnmp |
你在进行部署的时候怎么考虑node节点,一般是考虑软策略和硬策略 污点和容忍可以配合node 的亲和性一块使用 ,污点:是node的调度机制,不是pod,被设置污点的节点,不会部署pod 污点和亲和性相反,亲和性是尽量选择和一定选择 污点的节点一定不被选择? |
污点:taint有三种设置方法
1 | NoSchedule:k8s不会把pod调度到这个节点上 |
2 | PreferNoSchedule:如果污点类型,尽量避免把pod部署在该节点上,不是一定不部署(master节点的污点就是这个) |
3 | NoExecute:如果污点类型是它,k8s将会把该节点上的所有pod全部驱逐出去,而且也不会调度到这个节点 |
两个注意点 1.基于控制器创建的pod,虽然被驱逐,会在其他节点重新部署 2.自主pod会被直接杀死 注意点:节点服务器需要维护,服务器关机,节点上pod将会失效,在工作中我们主要部署pod的方式控制器部署,尤其deployment最多,一旦节点设置为驱逐,控制器创建的pod会在其他节点重新部署,也就是驱逐一般用于服务器维护 所有的pod都会被驱逐,跟命名空间无关,所有的一切都会被驱逐 不论创建方式是什么,都会被驱逐,系统集群组件不会被驱逐 |
污点相关命令
#创建污点,key=1:NoSchedule
kubectl taint node node01 污点种类
[root@master01 k8s.yaml]# kubectl taint node node01 key=1:NoSchedule
#删除污点
[root@master01 k8s.yaml]# kubectl taint node node01 key:NoSchedule-
#查看污点
[root@master01 k8s.yaml]# kubectl describe nodes node01 | grep -i taints
Taints: key=1:NoSchedule
容忍
即使节点上设置了污点,有了容忍机制,依然可以在设置了污点了节点上部署pod 特殊情况:NoExecute依然可以部署pod,但是有生命周期,时间一到,pod会被销毁然后重新拉起 生命周期结束之后,会驱逐一部分pod到其他节点, *有的节点还是会保持在污点之上 适用于该节点维护完毕,测试一下该节点工作是否正常 |
污点测试
[root@master01 k8s.yaml]# kubectl taint node node01 key=1:NoSchedule
node/node01 tainted
[root@master01 k8s.yaml]# kubectl taint node node02 key=2:NoSchedule
node/node02 tainted
两个节点设置一下不能部署,主节点不设置
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
nodeSelector:
test1: a
containers:
- image: nginx:1.22
name: nginx1
容忍测试
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
nodeSelector:
test1: a
containers:
- image: nginx:1.22
name: nginx1
tolerations:
- key: key
operator: Equal
value: "1"
effect: NoExecute
tolerationSeconds: 36
#容忍策略容忍节点上的标签key,对应的标签值是1 effect就是对应的污点的类型
#key: 指定污点的键(Taint 的键)。
#operator: 定义 key 和 value 之间的比较运算符。在这里是 Equal,表示 key 的值必须等于指定的值。
#value: 指定 Taint 的值,即 key 所对应的具体值。
#effect: 定义容忍的效果。在这里是 NoExecute,表示这是一个不会允许新的 Pod 被调度到被污点的节点上的 Taint。NoExecute 效果表示即使节点上的现有 Pod 也会被驱逐。
#tolerationSeconds: 指定容忍的持续时间(以秒为单位)。在这里是 36 秒。这表示 Pod 允许在节点上停留 36 秒,即使节点被标记为不适用于调度新的 Pod,该 Pod 仍然可以在节点上运行
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
nodeSelector:
test1: a
containers:
- image: nginx:1.22
name: nginx1
tolerations:
- operator: Exists
effect: NoSchedule
#容忍所有污点的key,key对应的节点类型是NoSchedule
不指定污点类型,容忍为key的污点
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
nodeSelector:
test1: a
containers:
- image: nginx:1.22
name: nginx1
tolerations:
- key: key
- operator: Exists
node的亲和性 pod的亲和性和发亲和性 污点和容忍 以上都是如何选择node节点部署pod 选择一个期望的节点来部署pod |
cordon和drain
cordon:可以把节点标记为不可用状态
#标记节点为cordon不可部署
[root@master01 k8s.yaml]# kubectl cordon master01 node01
node/master01 cordoned
#标记为不可用
[root@master01 k8s.yaml]# kubectl uncordon master01 node01
node/master01 uncordoned
node/node01 uncordoned
#取消标记
drain:排水,把该节点下的pod全部转移到其他node节点上运行
- 一旦执行了drain,被执行的节点会变成不可调度状态
- 会驱逐该节点上的所有pod
kubectl drain node02 --ignore-daemonsets --delete-local-data --force
drain:开始排水,标记node节点为不可调度,然后驱逐pod
--ignore-daemonsets:忽视daemonset方式部署的pod,daemonset部署的pod不会被转移(daemonset要部署的一般是重要的后台运行的,系统pod,所以不动)
--delete-local-data:有本地挂载的pod会被强制杀死
--force:强制释放不是控制器管理的pod
#取消drain:
kubectl uncordon node02
更多推荐
所有评论(0)