• 【k8s 高级调度--亲和力/反亲和力】


    1、亲和性/反亲和性介绍

    nodeSelector 提供了一种最简单的方法来将 Pod 约束到具有特定标签的节点上。 亲和性和反亲和性扩展了你可以定义的约束类型。使用亲和性与反亲和性的一些好处有:

    • 亲和性、反亲和性语言的表达能力更强。nodeSelector 只能选择拥有所有指定标签的节点。 亲和性、反亲和性为你提供对选择逻辑的更强控制能力。
    • 你可以标明某规则是“软需求”或者“偏好”,这样调度器在无法找到匹配节点时仍然调度该 Pod。
    • 你可以使用节点上(或其他拓扑域中)运行的其他 Pod 的标签来实施调度约束, 而不是只能使用节点本身的标签。这个能力让你能够定义规则允许哪些 Pod 可以被放置在一起。

    亲和性功能由两种类型的亲和性组成:

    • 节点亲和性功能类似于 nodeSelector 字段,但它的表达能力更强,并且允许你指定软规则。
    • Pod 间亲和性/反亲和性允许你根据其他 Pod 的标签来约束 Pod。

    2、Node节点亲和力/反亲和力

    节点亲和性概念上类似于 nodeSelector, 它使你可以根据节点上的标签来约束 Pod 可以调度到哪些节点上。 节点亲和性有两种:

    • requiredDuringSchedulingIgnoredDuringExecution: 调度器只有在规则被满足的时候才能执行调度。此功能类似于 nodeSelector, 但其语法表达能力更强。
    • preferredDuringSchedulingIgnoredDuringExecution: 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。

    2.1 配置文件

    spec:
      template:
        spec:
          affinity:
            nodeAffinity:  
              requiredDuringSchedulingIgnoredDuringExecution: # 硬匹配
                nodeSelectorTerms:
               - matchExpressions:
                  - key: kubernetes.io/os   # 匹配的key
                    operator: In      # 匹配的操作,In代表在
                    values:
                    - linux   # 匹配的值
              preferredDuringSchedulingIgnoredDuringExecution:  # 软匹配
              - weight: 1   # 匹配的权重,数值越大,权重越高
                preference:
                  matchExpressions:
                  - key: label-1   # 匹配的key
                    operator: In
                    values:
                    - key-1   # 匹配的值
              - weight: 50
                preference:
                  matchExpressions:
                  - key: label-2
                    operator: In
                    values:
                    - key-2
    
    • 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

    2.2 上文的软匹配中,给node1和node2分别添加一个标签

    [root@k8s-master ~]# kubectl label   nodes  k8s-node-01  label-1=key-1
    node/k8s-node-01 labeled
    [root@k8s-master ~]# kubectl label   nodes  k8s-node-02  label-2=key-2
    node/k8s-node-02 labeled
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    2.3 将上面节点亲和力的配置添加到deployment中

    在这里插入图片描述

    2.4 查看pod情况

    由于requiredDuringSchedulingIgnoredDuringExecution 硬匹配都可以匹配到,但是 在 preferredDuringSchedulingIgnoredDuringExecution 软匹配的时候,node2的亲和力比node1的高,所以pod都跑到了node2上。

    在这里插入图片描述

    2.5 修改一个软亲和力的操作

    在这里插入图片描述

    2.6 查看pod情况

    在这里插入图片描述

    2.7 NodeAffinity 亲和力的匹配类型

    • In: 满足一个就满足,就把pod部署过去
    • NotIn: 一个都不能满足,就是你满足了这个条件,pod不可以部署过来,也就是反亲和力
    • Exist: 只要存在就满足
    • DoesNotExist: 只要不存在就满足
    • Gt: 必须要打大于节点上的数值
    • Lt: 必须要打小于节点上的数值

    3、Pod资源亲和力/反亲和力

    Pod 间亲和性与反亲和性使你可以基于已经在节点上运行的 Pod 的标签来约束 Pod 可以调度到的节点,而不是基于节点上的标签。

    • Pod亲和力:将与指定pod亲和力相匹配的pod部在同一节点。
    • Pod反亲和力,将与指定的pod亲和力想匹配的pod部署在不同的同一节点

    3.1 分别给node打标签

    [root@k8s-master ~]# kubectl label nodes k8s-node-01 k8s-node-02  topology.kubernetes.io/zone=V
    node/k8s-node-01 labeled
    node/k8s-node-02 labeled
    
    [root@k8s-master ~]# kubectl label nodes k8s-master   topology.kubernetes.io/zone=R
    node/k8s-master labeled
    
    [root@k8s-master ~]# kubectl get nodes  --show-labels
    NAME          STATUS   ROLES           AGE    VERSION   LABELS
    k8s-master    Ready    control-plane   9d     v1.25.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ingress=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers=,topology.kubernetes.io/zone=R
    k8s-node-01   Ready    <none>          9d     v1.25.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ingress=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node-01,kubernetes.io/os=linux,label-1=key-1,topology.kubernetes.io/zone=V,type=microsvc
    k8s-node-02   Ready    <none>          7d1h   v1.25.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node-02,kubernetes.io/os=linux,label-2=key-2,topology.kubernetes.io/zone=V,type=microsvc
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.2 创建第一个deploy资源,pod标签是 security: S1

    3.2.1 配置文件

    apiVersion: apps/v1 # deployment api 版本
    kind: Deployment # 资源类型为 deployment
    metadata: # 元信息
      labels: # 标签
        app: nginx-deploy # 具体的 key: value 配置形式
      name: nginx-deploy-s1 # deployment 的名字
      namespace: default # 所在的命名空间
    spec:
      replicas: 2 # 期望副本数
      revisionHistoryLimit: 10 # 进行滚动更新后,保留的历史版本数
      selector: # 选择器,用于找到匹配的 RS
        matchLabels: # 按照标签匹配
          app: nginx-deploy # 匹配的标签key/value
      strategy: # 更新策略
        rollingUpdate: # 滚动更新配置
          maxSurge: 25% # 进行滚动更新时,更新的个数最多可以超过期望副本数的个数/比例
          maxUnavailable: 25% # 进行滚动更新时,最大不可用比例更新比例,表示在所有副本数中,最多可以有多少个不更新成功
        type: RollingUpdate # 更新类型,采用滚动更新
      template: # pod 模板
        metadata: # pod 的元信息
          labels: # pod 的标签
            app: nginx-deploy
          #   topology.kubernetes.io/zone: V
            security: S1
        spec: # pod 期望信息
          containers: # pod 的容器
          - image: nginx:1.20 # 镜像
            imagePullPolicy: IfNotPresent # 拉取策略
            name: nginx # 容器名称
            resources:
              limits:
                cpu: 200m
                memory: 128Mi
              requests:
                cpu: 100m
                memory: 128Mi
          restartPolicy: Always # 重启策略
          terminationGracePeriodSeconds: 30 # 删除操作最多宽限多长时间
    
    
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    3.2.2 创建这个deploy

    [root@k8s-master affinity]# kubectl create -f s1-nginx-deploy-affinity.yaml
    deployment.apps/nginx-deploy-s1 created
    
    • 1
    • 2

    3.2.3 查看这个pod信息

    • 有一个pod运行在了master、有一个运行在了node-02
    [root@k8s-master affinity]# kubectl get po   -owide    --show-labels
    NAME                               READY   STATUS    RESTARTS        AGE     IP           NODE          NOMINATED NODE   READINESS GATES   LABELS
    dns-test                           1/1     Running   2 (2d12h ago)   4d21h   10.2.1.58    k8s-node-02   <none>           <none>            run=dns-test
    fluentd-59k8k                      1/1     Running   1 (2d12h ago)   4d3h    10.2.2.34    k8s-node-01   <none>           <none>            app=logging,controller-revision-hash=7555d95dc,id=fluentd,pod-template-generation=2
    fluentd-hhtls                      1/1     Running   1 (2d12h ago)   4d3h    10.2.1.59    k8s-node-02   <none>           <none>            app=logging,controller-revision-hash=7555d95dc,id=fluentd,pod-template-generation=2
    nginx-deploy-579987f57f-ccgd8      1/1     Running   0               51m     10.2.2.113   k8s-node-01   <none>           <none>            app=nginx-deploy,pod-template-hash=579987f57f
    nginx-deploy-579987f57f-hwpjk      1/1     Running   0               51m     10.2.2.112   k8s-node-01   <none>           <none>            app=nginx-deploy,pod-template-hash=579987f57f
    nginx-deploy-s1-5cc987b754-82xt5   1/1     Running   0               26s     10.2.1.92    k8s-node-02   <none>           <none>            app=nginx-deploy,pod-template-hash=5cc987b754,security=S1
    nginx-deploy-s1-5cc987b754-kwsk5   1/1     Running   0               26s     10.2.0.7     k8s-master    <none>           <none>            app=nginx-deploy,pod-template-hash=5cc987b754,security=S1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.3 创建第二个deploy资源,pod标签是 security: S2

    3.3.1 配置文件

    apiVersion: apps/v1 # deployment api 版本
    kind: Deployment # 资源类型为 deployment
    metadata: # 元信息
      labels: # 标签
        app: nginx-deploy # 具体的 key: value 配置形式
      name: nginx-deploy-s2 # deployment 的名字
      namespace: default # 所在的命名空间
    spec:
      replicas: 1 # 期望副本数
      revisionHistoryLimit: 10 # 进行滚动更新后,保留的历史版本数
      selector: # 选择器,用于找到匹配的 RS
        matchLabels: # 按照标签匹配
          app: nginx-deploy # 匹配的标签key/value
      strategy: # 更新策略
        rollingUpdate: # 滚动更新配置
          maxSurge: 25% # 进行滚动更新时,更新的个数最多可以超过期望副本数的个数/比例
          maxUnavailable: 25% # 进行滚动更新时,最大不可用比例更新比例,表示在所有副本数中,最多可以有多少个不更新成功
        type: RollingUpdate # 更新类型,采用滚动更新
      template: # pod 模板
        metadata: # pod 的元信息
          labels: # pod 的标签
            app: nginx-deploy
        #     topology.kubernetes.io/zone: V
            security: S2
        spec: # pod 期望信息
          nodeSelector:
            kubernetes.io/hostname: k8s-master
          containers: # pod 的容器
          - image: nginx:1.20 # 镜像
            imagePullPolicy: IfNotPresent # 拉取策略
            name: nginx # 容器名称
            resources:
              limits:
                cpu: 200m
                memory: 128Mi
              requests:
                cpu: 100m
                memory: 128Mi
          restartPolicy: Always # 重启策略
          terminationGracePeriodSeconds: 30 # 删除操作最多宽限多长时间
    
    
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    3.3.2 创建这个deploy

    [root@k8s-master affinity]# kubectl create  -f s2-nginx-deploy-affinity.yaml
    deployment.apps/nginx-deploy-s2 created
    
    • 1
    • 2

    3.3.3 查看这个pod信息

    • 这个pod运行在了master上
    [root@k8s-master affinity]# kubectl get po   -owide    --show-labels
    NAME                               READY   STATUS    RESTARTS        AGE     IP           NODE          NOMINATED NODE   READINESS GATES   LABELS
    dns-test                           1/1     Running   2 (2d12h ago)   4d21h   10.2.1.58    k8s-node-02   <none>           <none>            run=dns-test
    fluentd-59k8k                      1/1     Running   1 (2d12h ago)   4d3h    10.2.2.34    k8s-node-01   <none>           <none>            app=logging,controller-revision-hash=7555d95dc,id=fluentd,pod-template-generation=2
    fluentd-hhtls                      1/1     Running   1 (2d12h ago)   4d3h    10.2.1.59    k8s-node-02   <none>           <none>            app=logging,controller-revision-hash=7555d95dc,id=fluentd,pod-template-generation=2
    nginx-deploy-579987f57f-ccgd8      1/1     Running   0               55m     10.2.2.113   k8s-node-01   <none>           <none>            app=nginx-deploy,pod-template-hash=579987f57f
    nginx-deploy-579987f57f-hwpjk      1/1     Running   0               56m     10.2.2.112   k8s-node-01   <none>           <none>            app=nginx-deploy,pod-template-hash=579987f57f
    nginx-deploy-s1-5cc987b754-82xt5   1/1     Running   0               5m19s   10.2.1.92    k8s-node-02   <none>           <none>            app=nginx-deploy,pod-template-hash=5cc987b754,security=S1
    nginx-deploy-s1-5cc987b754-kwsk5   1/1     Running   0               5m19s   10.2.0.7     k8s-master    <none>           <none>            app=nginx-deploy,pod-template-hash=5cc987b754,security=S1
    nginx-deploy-s2-656bfc8d9c-qpzl4   1/1     Running   0               3s      10.2.0.8     k8s-master    <none>           <none>            app=nginx-deploy,pod-template-hash=656bfc8d9c,security=S2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.4 创建这个Pod亲和力的deploy资源

    3.4.1 配置文件

    apiVersion: apps/v1 # deployment api 版本
    kind: Deployment # 资源类型为 deployment
    metadata: # 元信息
      labels: # 标签
        app: nginx-deploy # 具体的 key: value 配置形式
      name: nginx-deploy-test # deployment 的名字
      namespace: default # 所在的命名空间
    spec:
      replicas: 2 # 期望副本数
      revisionHistoryLimit: 10 # 进行滚动更新后,保留的历史版本数
      selector: # 选择器,用于找到匹配的 RS
        matchLabels: # 按照标签匹配
          app: nginx-deploy # 匹配的标签key/value
      strategy: # 更新策略
        rollingUpdate: # 滚动更新配置
          maxSurge: 25% # 进行滚动更新时,更新的个数最多可以超过期望副本数的个数/比例
          maxUnavailable: 25% # 进行滚动更新时,最大不可用比例更新比例,表示在所有副本数中,最多可以有多少个不更新成功
        type: RollingUpdate # 更新类型,采用滚动更新
      template: # pod 模板
        metadata: # pod 的元信息
          labels: # pod 的标签
            app: nginx-deploy
        spec: # pod 期望信息
          affinity:
            podAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:
                  - key: security
                    operator: In
                    values:
                    - S1
                topologyKey: topology.kubernetes.io/zone
            podAntiAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
              - weight: 100
                podAffinityTerm:
                  labelSelector:
                    matchExpressions:
                    - key: security
                      operator: In
                      values:
                      - S2
                  topologyKey: topology.kubernetes.io/zone
          containers: # pod 的容器
          - image: nginx:1.20 # 镜像
            imagePullPolicy: IfNotPresent # 拉取策略
            name: nginx # 容器名称
            resources:
              limits:
                cpu: 200m
                memory: 128Mi
              requests:
                cpu: 100m
                memory: 128Mi
          restartPolicy: Always # 重启策略
          terminationGracePeriodSeconds: 30 # 删除操作最多宽限多长时间
    
    
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    3.4.2 创建这个deploy

    [root@k8s-master affinity]# kubectl create -f nginx-affinity-deploy.yaml
    deployment.apps/nginx-deploy-test created
    
    • 1
    • 2

    3.4.3 查看这个pod信息

    在这里插入图片描述

    • 正常按照调度规则是s1所在的node上,新的这个亲和力的pod应该被创建到和s1相同的节点上,但是目前这个创建是不一样的。
    • 可能原因:

    在这里插入图片描述

    3.5 删除目前不使用的资源后重复以上3.2-3.4的操作过程后

    • 复现了我们设置的亲和力规则,新创建的资源匹配到 security=S1,两个资源所在的节点都是同一个节点。
      在这里插入图片描述
  • 相关阅读:
    java源码系列:HashMap底层存储原理详解——5、技术本质-原理过程-算法-取模会带来一个什么问题?什么是哈希冲突?为什么要用链表?
    【Android Studio学习】第一篇、制作一个拥有登录和注册功能的简易APP
    PS文字创建工作路径矢量化后变细,导出的svg也变细的解决方案
    Leetcode899 有序队列Orderly Queue
    C++ 智能指针
    pytest框架二次开发
    一次人脸识别ViewFaceCore使用的经验分享,看我把门店淘汰下来的POS机改成了人脸考勤机
    江苏全面推进双重预防数字化建设,强化落实危化企业主体责任
    王道 第二章物理层
    正负折线图凸显数据趋势变化
  • 原文地址:https://blog.csdn.net/u011709380/article/details/136357722