一图看懂pod亲和性调度策略,再也不担心学不废了!

高斋晓开卷,独共圣人语。这篇文章主要讲述一图看懂pod亲和性调度策略,再也不担心学不废了!相关的知识,希望能为你提供帮助。




    哈喽!大家好,我是李大白。
    本文是我《5分钟学习k8s》系列的文章,众所周知,kubernetes技术栈是一个非常广泛的技术,所涉及的技术也比较广,学习起来也比较花费时间,本系列文章将kubernetes相关的知识点切割成一个个的知识点,每篇文章花5分钟时间即可阅读完成,充分利用零碎的时间来学习更多的知识。







知识点简记1、亲和性调度可以分成软策略和硬策略两种方式:


  • 软亲和性策略(preferredDuringSchedulingIgnoredDuringExecution)
可以理解为尽量(非强制性),就是如果现在没有满足调度要求的节点的话,pod就会忽略这条规则,继续完成调度的过程,说白了就是满足条件最好了,没有的话也无所谓。


  • 硬亲和性策(requiredDuringSchedulingIgnoredDuringExecution)
可以理解为必须,就是如果没有满足条件的节点的话,就不断重试直到满足条件为止,即强制性满足指定的条件。


2、亲和性的配置规则
亲和性调度策略分为 Node亲和性、Pod亲和性、Pod反亲和性:
(1)nodeAffinity(节点亲和性)
将pod调度到满足指定条件的node节点上;用来控制 Pod 要部署在哪些节点上,以及不能部署在哪些节点上的,这个是 Pod 与 Node 之间匹配规则的。我们在创建Pod资源的时候,Pod会根据kube-Scheduler控制器组件按照一定算法和策略将Pod调度到节点。
如果某个节点资源很低,但符合Pod调度到该节点的条件,Pod调度到该节点会加大该节点的压力。我们更希望新的Pod调度到另外一个资源充足的节点上时,我们该怎么办呢?
kubernetes中,可以在定义Pod时,使用nodeName和nodeSelector字段来将Pod调度到满足条件的节点上。
nodeName字段:指定节点的主机名,那么Pod就会被调度到这台主机上;
nodeSelector字段:指定节点标签,如果node节点上具有这个标签,即满足条件,Pod就会调度到具有这个标签的节点上。


nodeName和nodeSelector的区别?
  • nodename:Pod只会调度到这个节点,其它节点不会调度,范围较窄。实际应用中,如果两个具有很强依赖性的Pod会通过该字段将两个Pod调度到同一个节点。如果持久卷使用的是host的方式,也需要使用该字段。
  • nodeSelector:具有这个标签的节点有多个,Pod都可以调度到这些节点上。例如,集群中节点的硬件配置有的内存高、有的节点内存低,我们想让每台节点的内存使用率都平衡些,可将内存低的节点定义一个标签(menory=min),内存高的节点定义另一个标签(memory=max),当创建资源的时候,我们定义nodeSelector使用menory=max的标签,那么创建的Pod就会被调度到内存配置高的节点上。


(2)podAffinity (pod 亲和性)
这个是 Pod 与 Pod 之间匹配规则的。将关联性较强的多个Pod调度到一起(妹妹去哪,哥哥也去哪儿!)。例如,一个Pod提供了mysql数据库服务,另一个Pod提供nginx服务,Nginx需要调用Mysql服务,如果两个Pod调度到不同的地方,那么Pod之间的通信会存在一定的影响,为了降低影响,我们更倾向与将两个Pod调度到相同地方。
·
(3)podAntiAffinity  (pod 反亲和性)
与 podAffinity 相反,即不希望两个(或者多个)调度到一起(仇人相见分外眼红,夺妻之仇不共戴天)


apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent



反亲和性在业务中的实践应用在生产业务环境中,为保证服务的高可用性,需要将Pod的副本数设置为多个(2个以上)。但如果该提供某个服务的所有的Pod都调度到某一个节点上,当这个节点刚好出问题的时候,就会造成该服务完全无法访问,影响业务的稳定性。
为防止这种情况的发生,我们可使用PodAntiAffinity(Pod)反亲和性调度策略来将同一个Deployment控制器创建的Pod分别调度到不同的节点上。如果其中一个节点出现宕机等问题造成节点上的Pod无法访问,另一个节点上的依然可以正常提供服务,以此来保证服务的稳定性。
(1) 资源模板
spec:
containers:# 定义Pod中的容器
......
affinity:# 亲和性调度策略
podAntiAffinity:# 使用Pod反亲和性调度
requiredDuringSchedulingIgnoredDuringExecution:# 硬亲和性
- labelSelector:# 使用标签匹配,即某个节点上具有该标签,那么Pod就不会调度到该节点上。
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: kubernetes.io/hostname# 位置拓扑键



(2) 实战练习
【一图看懂pod亲和性调度策略,再也不担心学不废了!】可使用下面的文件来练习Pod反亲和性,加深对Pod反亲和性(podAntiAffinity)的理解。
  • 定义资源清单文件
[root@sc-master1 work]# vim test/nginx-dey.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default# 命名空间
spec:
replicas: 2# Pod副本数
selector:
matchLabels:
app: nginx
template:# 定义Pod模板,即控制器会根据该模板创建Pod
metadata:# Pod元数据信息
labels:# 定义Pod的标签列表
app: nginx# 定义Pod的标签
spec:
containers:# 定义Pod中的容器
- name: nginx# 容器的名称
image: nginx# 容器使用的镜像
imagePullPolicy: IfNotPresent# 镜像拉取凭证
affinity:# 亲和性调度策略
podAntiAffinity:# 使用Pod反亲和性调度
requiredDuringSchedulingIgnoredDuringExecution:# 硬亲和性
- labelSelector:# 使用标签匹配,即某个节点上具有该标签,那么Pod就不会调度到该节点上。
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: kubernetes.io/hostname# 位置拓扑键

  • 创建资源
[root@sc-master1 test]# kubectl apply -f nginx-dey.yaml
deployment.apps/nginx unchanged

  • 查看资源调度情况
[root@sc-master1 test]# kubectl get pods
NAMEREADYSTATUSRESTARTSAGE
nginx-7955648796-6vsgd1/1Running12d17h
nginx-7955648796-qqq6k1/1Running12d17h
tomcat-747db4758b-s8qn91/1Running12d14h
tomcat-747db4758b-vk5jd1/1Running12d14h
[root@sc-master1 test]# kubectl get pods -owide
NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATED NODEREADINESS GATES
nginx-7955648796-6vsgd1/1Running12d17h10.244.242.183sc-node2< none> < none>
nginx-7955648796-qqq6k1/1Running12d17h10.244.119.195sc-node1< none> < none

    推荐阅读