Kubernetes----Pod亲和性调度

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: Kubernetes----Pod亲和性调度

一、亲和性调度简介

1.1 亲和性简介

亲和性调度是指通过配置的形式,实现优先选择满足条件的Node进行调度,如果没有,也可以调度到不满足条件的节点上,使调度更加灵活

亲和性(Affinity)主要分为三类:

  • 节点亲和性(nodeAffinity):以node为目标,解决pod可以调度到哪些node的问题
  • pod亲和性(podAffinity):以pod为目标,解决pod可以和哪些已经存在pod部署到同一个拓扑域中的问题
  • pod反亲和性(podAntiAffinity):以pod为目标,解决pod不能和哪些已存在的pod部署在统一个拓扑域中的问题

1.2 亲和性和反亲和性说明

  • 亲和性:如果两个应用频繁交互,那就有必要利用亲和性让两个应用尽可能靠近,这样可以减少因网络通信而带来的性能损耗
  • 反亲和性:当应用采用多副本部署时,有必要采用反亲和性让各个应用实例分布在各个node节点上,这样可以提高服务的高可用性

二、亲和性配置

2.1 节点亲和性(NodeAffinity)

2.1.1 NodeAffinity配置项说明

pod.spec.affinity.nodeAffinity
  requiredDuringSchedulingIgnoredDuringExecution   Node节点必须满足指定的所有规则才可以,相当于硬限制
    nodeSelectorTerms    节点选择列表
      matchFields     按节点字段列出的节点选择器要求列表
      matchExpressions    按节点标签列出的节点选择器要求列表(推荐)
        key    键
        values    值
        operator    关系符,支持Exists,DoesNotExist,In,NotIn,Gt,Lt
  preferredDuringSchedulingIgnoredDuringExecution    优先调整到满足指定的规则的Node,相当于软限制(倾向)
    preference    一个节点选择器,与相应的权重相关联
      matchFields  按节点字段列出的节点选择器要求列表
      matchExpressions    按节点标签列出的节点选择器要求列表(推荐)
        key    键
        values    值
        operator    关系符,支持In,NotIn,Exists,DoesNotExist,Gt,Lt
    weight    倾向权重,范围1-100

关系运算符说明:

  - matchExpressions:
    - key: nodeenv               # 匹配存在标签的key为nodeenv的节点
      operator: Exists
    - key: nodeenv               # 匹配标签的key为nodeenv,且value是 "xxx" 或 "yyy" 的节点
      operator: In
      values: ["xxx","yyy"]
    - key: nodeenv               # 匹配标签的key为nodeenv,且value大于 "xxx" 的节点
      operator: Gt
      values: "xxx"

2.1.2 使用required类型的节点亲和性

首先使用如下命令先给node1和node2打标签

[root@master resource_manage]# kubectl label nodes node1 nodeenv=test
node/node1 labeled
[root@master resource_manage]# kubectl label nodes node2 nodeenv=demo
node/node2 labeled
[root@master resource_manage]# kubectl get node --show-labels
NAME     STATUS   ROLES                  AGE   VERSION   LABELS
master   Ready    control-plane,master   10d   v1.21.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
node1    Ready    <none>                 10d   v1.21.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node1,kubernetes.io/os=linux,nodeenv=test
node2    Ready    <none>                 10d   v1.21.2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node2,kubernetes.io/os=linux,nodeenv=demo
[root@master resource_manage]#

编辑pod_nodeaffinity_required.yaml文件,内容如下:

apiVersion: v1
kind: Namespace
metadata:
  name: dev

---

apiVersion: v1
kind: Pod
metadata:
  name: pod-nginx
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: nodeenv
            operator: In
            values: ["demo","demo1"]

使用如下命令创建资源

[root@master resource_manage]# kubectl apply -f pod_nodeaffinity_required.yaml
namespace/dev unchanged
pod/pod-nginx created
[root@master resource_manage]#

如下,可以查询到被调度到node2节点上,符合设置调度规则

[root@master resource_manage]# kubectl get pod -n dev -o wide
NAME        READY   STATUS    RESTARTS   AGE    IP            NODE    NOMINATED NODE   READINESS GATES
pod-nginx   1/1     Running   0          118s   10.244.2.45   node2   <none>           <none>
[root@master resource_manage]#

如下,删除资源

[root@master resource_manage]# kubectl delete -f pod_nodeaffinity_required.yaml
namespace "dev" deleted
pod "pod-nginx" deleted
[root@master resource_manage]#

2.1.3 使用prefered类型的节点亲和性

编辑pod_nodeaffinity_preferred.yaml文件,内容如下:

apiVersion: v1
kind: Namespace
metadata:
  name: dev

---

apiVersion: v1
kind: Pod
metadata:
  name: pod-nginx
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 10
        preference:
          matchExpressions:
          - key: nodeenv
            operator: In
            values: ["demo2","demo1"]

使用如下命令创建资源

[root@master resource_manage]# kubectl apply -f pod_nodeaffinity_preferred.yaml
namespace/dev unchanged
pod/pod-nginx created
[root@master resource_manage]#

查看结果如下,虽然这里不符合调度条件,但仍然能调度到node2节点,因为这里的调度不是强制性的

[root@master resource_manage]# kubectl get pod -n dev -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
pod-nginx   1/1     Running   0          57m   10.244.2.46   node2   <none>           <none>
[root@master resource_manage]#

使用如下命令删除资源

[root@master resource_manage]# kubectl delete -f pod_nodeaffinity_preferred.yaml
namespace "dev" deleted
pod "pod-nginx" deleted
[root@master resource_manage]#

2.1.4 Node亲和性注意事项

  • 1 如果同时定义了nodeSelector和NodeAffinity,name必须两个条件都得到满足,Pod才能运行在指定的Node上
  • 2 如果NodeAffinity指定了多个nodeSelectorTerms,name只需要其中一个能匹配成功即可
  • 3 如果一个nodeSelectorTerms中有多个matchExpressions,则一个节点必须满足左右的才能匹配成功
  • 4 如果一个pod所在的Node在Pod运行期间其标签发生了改变,不再符合该Pod的节点亲和性需求,则系统忽略此变化

2.2 Pod亲和性(PodAffinity)

2.2.1 Pod亲和性配置项

pod.spec.affinity.podAffinity
  requiredDuringSchedulingIgnoredDuringExecution    硬限制
    namespace      指定参照pod的namespace
    topologyKey    指定调度作用域
    labelSelector  标签选择器
      matchExpressions    按节点标签列出的节点选择器要求列出(推荐)
        key        键
        values     值
        operator   关系符,支持 In,NotIn,Exists,NoesNotExist
      matchLabels   指多个matchExpressions映射的内容
  preferredDuringSchedulingIgnoredDuringExecution    软限制
    PodAffinityTerm  选项
      namespace
      topologyKey
      labelSelector
        matchExpressions:
          key       键
          values    值
          operator
    matchLabels
    

其中topologyKey用于指定调度的作用域,如:

  • 如果指定为Kubernetes.io/hostname,那就是以Node节点为分区范围
  • 如果指定为beta.kubernets.io/os,则以node节点的操作系统类型来区分

2.2.2 Pod亲和性实例演示

首先使用如下pod_podaffinnity_target.yaml文件创建一个dev命名空间以及一个目标Pod

apiVersion: v1
kind: Namespace
metadata:
  name: dev

---

apiVersion: v1
kind: Pod
metadata:
  name: pod-podaffinity-target
  namespace: dev
  labels:
    podenv: pro
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  nodeName: node1

使用如下命令创建资源

[root@master resource_manage]# kubectl apply -f pod_podaffinnity_target.yaml
namespace/dev created
pod/pod-podaffinity-target created
[root@master resource_manage]#

然后编写pod亲和性的yaml文件pod_podaffinity_required.yaml,内容如下:

apiVersion: v1
kind: Pod
metadata:
  name: pod-podaffinity-required
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: podenv
            operator: In
            values: ["pro"]
        topologyKey: kubernetes.io/hostname

使用如下命令创建资源

[root@master resource_manage]# kubectl apply -f pod_podaffinity_required.yaml
pod/pod-podaffinity-required created
[root@master resource_manage]#

通过如下命令可以查看到pod亲和性生效了,此两个pod在一个节点上

[root@master resource_manage]# kubectl get pod -n dev -o wide
NAME                       READY   STATUS    RESTARTS   AGE    IP            NODE    NOMINATED NODE   READINESS GATES
pod-podaffinity-required   1/1     Running   0          2m7s   10.244.1.21   node1   <none>           <none>
pod-podaffinity-target     1/1     Running   0          13m    10.244.1.20   node1   <none>           <none>
[root@master resource_manage]#

2.3 Pod反亲和性(PodAntiAffinity)

Pod 反亲和性主要是设置新建的pod与已知pod不在同一个节点上,配置内容和pod亲和性几乎完全一样,这里直接以实例演示
首先使用如下pod_podaffinnity_target.yaml文件创建一个dev命名空间以及一个目标Pod

apiVersion: v1
kind: Namespace
metadata:
  name: dev

---

apiVersion: v1
kind: Pod
metadata:
  name: pod-podaffinity-target
  namespace: dev
  labels:
    podenv: pro
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  nodeName: node1

使用如下命令创建资源

[root@master resource_manage]# kubectl apply -f pod_podaffinnity_target.yaml
namespace/dev created
pod/pod-podaffinity-target created
[root@master resource_manage]#

然后编辑pod反亲和性yaml文件pod_podantiaffinity_required.yaml,内容如下:

apiVersion: v1
kind: Pod
metadata:
  name: pod-podaffinity-required
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: podenv
            operator: In
            values: ["pro"]
        topologyKey: kubernetes.io/hostname

然后使用如下命令创建

[root@master resource_manage]# kubectl apply -f pod_podantiaffinity_required.yaml
pod/pod-podaffinity-required created
[root@master resource_manage]#

通过如下命令可以看出此时两个pod已经分别在两个节点上了

[root@master resource_manage]# kubectl get pod -n dev -o wide
NAME                       READY   STATUS    RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES
pod-podaffinity-required   1/1     Running   0          79s     10.244.2.47   node2   <none>           <none>
pod-podaffinity-target     1/1     Running   0          2m42s   10.244.1.22   node1   <none>           <none>
[root@master resource_manage]#
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
3月前
|
存储 边缘计算 Kubernetes
边缘计算问题之YurtControllerManager 接管原生 Kubernetes 的调度如何解决
边缘计算问题之YurtControllerManager 接管原生 Kubernetes 的调度如何解决
36 1
|
3月前
|
Kubernetes 负载均衡 调度
在k8S中,Pod的常见调度方式有哪些?
在k8S中,Pod的常见调度方式有哪些?
|
1月前
|
应用服务中间件 调度 nginx
Kubernetes的Pod调度:让你的应用像乘坐头等舱!
Kubernetes的Pod调度:让你的应用像乘坐头等舱!
|
2月前
|
Kubernetes 调度 容器
Kubernetes高级调度方式
文章介绍了Kubernetes的高级调度方式,包括调度器的工作机制、节点倾向性(Node Affinity)和Pod倾向性(Affinity)。
69 9
Kubernetes高级调度方式
|
2月前
|
机器学习/深度学习 Kubernetes 调度
Kubernetes与GPU的调度:前世今生
本文详细探讨了Kubernetes与GPU的结合使用,阐述了两者在现代高性能计算环境中的重要性。Kubernetes作为容器编排的佼佼者,简化了分布式系统中应用程序的部署与管理;GPU则凭借其强大的并行计算能力,在加速大规模数据处理和深度学习任务中发挥关键作用。文章深入分析了Kubernetes如何支持GPU资源的检测与分配,并介绍了热门工具如NVIDIA GPU Device Plugin和Kubeflow的应用。
|
1月前
|
Kubernetes 应用服务中间件 调度
k8s的Pod常见的几种调度形式
k8s的Pod常见的几种调度形式
31 0
|
1月前
|
Kubernetes 固态存储 调度
k8s学习--如何控制pod调度的位置
k8s学习--如何控制pod调度的位置
|
3月前
|
Kubernetes 调度 Perl
在K8S中,Pod多副本配置了硬亲和性,会调度到同⼀个节点上吗?
在K8S中,Pod多副本配置了硬亲和性,会调度到同⼀个节点上吗?
|
3月前
|
存储 Kubernetes 调度
在K8S中,影响Pod调度策略的有哪些?
在K8S中,影响Pod调度策略的有哪些?
|
3月前
|
Kubernetes 调度 容器
在k8S中,Requests和Limits如何影响Pod的调度?
在k8S中,Requests和Limits如何影响Pod的调度?