Kubernetes实践之深入掌握Pod——玩转Pod调度
1|0玩转Pod调度
Deployment或RC:全自动调度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | apiVersion: apps /v1beta1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 |
NodeSelector:定向调度
(1)首先通过kubectl label命令给目标Node打上一些标签:
1 | kubectl label nodes k8s-node-1 zone=north |
(2)然后,在Pod的定义中加上nodeSelector的设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | apiVersion: v1 kind: ReplicationController metadata: name: redis-master labels: name: redis-master spec: replicas: 1 selector: name: redis-master template: metadata: labels: name: redis-master spec: containers: - name: master image: kubeguide /redis-master ports: - containerPort: 6379 nodeSelector: zone: north |
NodeAffinity:Node亲和性调度
RequiredDuringSchedulingIgnoredDuringExecution:必须满足指 定的规则才可以调度Pod到Node上(功能与nodeSelector很像,但是使用 的是不同的语法),相当于硬限制
PreferredDuringSchedulingIgnoredDuringExecution:强调优先满足指定规则,调度器会尝试调度Pod到Node上,但并不强求,相当于软 限制。多个优先级规则还可以设置权重(weight)值,以定义执行的先 后顺序
IgnoredDuringExecution的意思是:如果一个Pod所在的节点在Pod运 行期间标签发生了变更,不再符合该Pod的节点亲和性需求,则系统将 忽略Node上Label的变化,该Pod能继续在该节点运行
下面的例子设置了NodeAffinity调度的如下规则
requiredDuringSchedulingIgnoredDuringExecution要求只运行在 amd64的节点上(beta.kubernetes.io/arch In amd64)preferredDuringSchedulingIgnoredDuringExecution的要求是尽量 运行在磁盘类型为ssd(disk-type In ssd)的节点上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: beta.kubernetes.io /arch operator: In values: - amd64 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: disk- type operator: In values: - ssd containers: - name: with-node-affinity image: gcr.io /google_containers/pause :2.0 |
从上面的配置中可以看到In操作符,NodeAffinity语法支持的操作 符包括In、NotIn、Exists、DoesNotExist、Gt、Lt。虽然没有节点排斥功 能,但是用NotIn和DoesNotExist就可以实现排斥的功能了。
NodeAffinity规则设置的注意事项如下
- 如果同时定义了nodeSelector和nodeAffinity,那么必须两个条 件都得到满足,Pod才能最终运行在指定的Node上。
- 如果nodeAffinity指定了多个nodeSelectorTerms,那么其中一个 能够匹配成功即可。
- 如果在nodeSelectorTerms中有多个matchExpressions,则一个节 点必须满足所有matchExpressions才能运行该Pod。
PodAffinity:Pod亲和与互斥调度策略
Pod的亲和性被定义 于PodSpec的affinity字段下的podAffinity子字段中。Pod间的互斥性则被 定义于同一层次的podAntiAffinity子字段中
1.参照目标Pod
首先,创建一个名为pod-flag的Pod,带有标签security=S1和 app=nginx,后面的例子将使用pod-flag作为Pod亲和与互斥的目标Pod
1 2 3 4 5 6 7 8 9 10 11 | apiVersion: v1 kind: Pod metadata: name: pod-flag labels: security: "S1" app: "nginx" spec: containers: - name: nginx image: nginx |
2.Pod的亲和性调度
下面创建第2个Pod来说明Pod的亲和性调度,这里定义的亲和标签 是security=S1,对应上面的Pod“pod-flag”,topologyKey的值被设置 为“kubernetes.io/hostname”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | apiVersion: v1 kind: Pod metadata: name: pod-affinity spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: security operator: In values: - S1 topologyKey: kubernetes.io /hostname containers: - name: with-pod-affinity image: gcr.io /google_containers/pause :2.0 |
有兴趣的读者还可以测试一下,在创建这个Pod之前,删掉这个节 点的kubernetes.io/hostname标签,重复上面的创建步骤,将会发现Pod一 直处于Pending状态,这是因为找不到满足条件的Node了
3.Pod的互斥性调度
创建第3个Pod,我们希望它不与目标Pod运行在同一个Node上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | apiVersion: v1 kind: Pod metadata: name: anti-affinity spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: security operator: In values: - S1 topologyKey: failure-domain.beta.kubernetes.io /zone podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - nginx topologyKey: kubernetes.io /hostname containers: - name: anti-affinity image: gcr.io /google_containers/pause :2.0 |
这里要求这个新Pod与security=S1的Pod为同一个zone,但是不与 app=nginx的Pod为同一个Node。创建Pod之后,同样用kubectl get pods -o wide来查看,会看到新的Pod被调度到了同一Zone内的不同Node上,与节点亲和性类似,Pod亲和性的操作符也包括In、NotIn、Exists、 DoesNotExist、Gt、Lt
Taints和Tolerations(污点和容忍)
Taint需要和Toleration配合使用,让Pod避开那些不合适的Node。在 Node上设置一个或多个Taint之后,除非Pod明确声明能够容忍这些污点,否则无法在这些Node上运行。Toleration是Pod的属性,让Pod能够 (注意,只是能够,而非必须)运行在标注了Taint的Node上
可以用kubectl taint命令为Node设置Taint信息:
1 | kubectl taint nodes node1 key=value:NoSchedule |
这个设置为node1加上了一个Taint。该Taint的键为key,值为value,Taint的效果是NoSchedule。这意味着除非Pod明确声明可以容忍 这个Taint,否则就不会被调度到node1上
在Pod上声明Toleration
1 2 3 4 5 6 7 8 9 | spec: tolerations: - key: "key" operator: "Equal" value: "value" effect: "NoSchedule" containers: - name: pod-toleration image: gcr.io /google_containers/pause :2.0 |
下面语法也行
1 2 3 4 | tolerations: - key: "key" operator: "Exists" effect: "NoSchedule" |
Pod的Toleration声明中的key和effect需要与Taint的设置保持一致, 并且满足以下条件之一。
- operator的值是Exists(无须指定value)
- operator的值是Equal并且value相等,如果不指定operator,则默认值为Equal
另外,有如下两个特例
- 空的key配合Exists操作符能够匹配所有的键和值
- 空的effect匹配所有的effect
多个Taint和Toleration会先忽略匹配的部分,在按如下规则匹配:
- 如果在剩余的Taint中存在effect=NoSchedule,则调度器不会把该Pod调度到这一节点上
- 如果在剩余的Taint中没有NoSchedule效果,但是有PreferNoSchedule效果,则调度器会尝试不把这个Pod指派给这个节点
- 如果在剩余的Taint中有NoExecute效果,并且这个Pod已经在该 节点上运行,则会被驱逐;如果没有在该节点上运行,则也不会再被调 度到该节点上
例如:
1 2 3 | kubectl taint nodes node1 key1=value1:NoSchedule kubectl taint nodes node1 key1=value1:NoExecute kubectl taint nodes node1 key2=value2:NoSchedule |
Pod上设置两个Toleration:
1 2 3 4 5 6 7 8 9 | tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoSchedule" - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute" |
这样的结果是该Pod无法被调度到node1上,这是因为第3个Taint没 有匹配的Toleration。但是如果该Pod已经在node1上运行了,那么在运行 时设置第3个Taint,它还能继续在node1上运行,这是因为Pod可以容忍前两个Taint。
Node加上effect=NoExecute的Taint,那么在该 Node上正在运行的所有无对应Toleration的Pod都会被立刻驱逐,系统允许给具有NoExecute 效果的Toleration加入一个可选的tolerationSeconds字段,这个设置表明 Pod可以在Taint添加到Node之后还能在这个Node上运行多久(单位为 s)
1 2 3 4 5 6 7 8 9 10 | tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoSchedule" - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute" tolerationsSeconds: 3600 |
上述定义的意思是,如果Pod正在运行,所在节点都被加入一个匹 配的Taint,则这个Pod会持续在这个节点上存活3600s后被逐出。如果在 这个宽限期内Taint被移除,则不会触发驱逐事件
Taint和Toleration案例:
1.独占节点
1 | kubectl taint nodes nodename dedicated=groupName:NoSchedule |
2.具有特殊硬件设备的节点
1 2 | kubectl taint nodes nodename special= true :NoSchedule kubectl taint nodes nodename special= true :PreferNoSchedule |
3.定义Pod驱逐行为,以应对节点故障
NoExecute的taint影响
没有设置Toleration的Pod会被立刻驱逐
配置了对应Toleration的Pod,如果没有为tolerationSeconds赋值,则会一直留在这一节点中
配置了对应Toleration的Pod且指定了tolerationSeconds值,则会 在指定时间后驱逐
__EOF__

本文链接:https://www.cnblogs.com/Wshile/p/12957857.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!