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

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

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

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

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

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

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

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

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

2.1 配置文件

yaml 复制代码
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

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

cpp 复制代码
[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

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打标签

cpp 复制代码
[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

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

3.2.1 配置文件

yaml 复制代码
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 # 删除操作最多宽限多长时间

3.2.2 创建这个deploy

cpp 复制代码
[root@k8s-master affinity]# kubectl create -f s1-nginx-deploy-affinity.yaml
deployment.apps/nginx-deploy-s1 created

3.2.3 查看这个pod信息

  • 有一个pod运行在了master、有一个运行在了node-02
cpp 复制代码
[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

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

3.3.1 配置文件

yaml 复制代码
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 # 删除操作最多宽限多长时间

3.3.2 创建这个deploy

cpp 复制代码
[root@k8s-master affinity]# kubectl create  -f s2-nginx-deploy-affinity.yaml
deployment.apps/nginx-deploy-s2 created

3.3.3 查看这个pod信息

  • 这个pod运行在了master上
cpp 复制代码
[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

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

3.4.1 配置文件

yaml 复制代码
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 # 删除操作最多宽限多长时间

3.4.2 创建这个deploy

cpp 复制代码
[root@k8s-master affinity]# kubectl create -f nginx-affinity-deploy.yaml
deployment.apps/nginx-deploy-test created

3.4.3 查看这个pod信息

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

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

  • 复现了我们设置的亲和力规则,新创建的资源匹配到 security=S1,两个资源所在的节点都是同一个节点。
相关推荐
Kendra9194 小时前
Kubernetes 常用命令
云原生·容器·kubernetes
2501_9399090512 小时前
k8s基础与安装部署
云原生·容器·kubernetes
谷隐凡二13 小时前
Kubernetes Route控制器简单介绍
java·容器·kubernetes
李少兄18 小时前
Kubernetes 日志管理
docker·容器·kubernetes
秋饼18 小时前
【K8S测试程序--git地址】
git·容器·kubernetes
oMcLin18 小时前
如何在RHEL 9上配置并优化Kubernetes 1.23高可用集群,提升大规模容器化应用的自动化部署与管理?
kubernetes·自动化·php
ghostwritten18 小时前
Kubernetes 网络模式深入解析?
网络·容器·kubernetes
原神启动119 小时前
K8S(七)—— Kubernetes Pod 基础概念与实战配置
云原生·容器·kubernetes
不想画图19 小时前
Kubernetes(五)——rancher部署和Pod详解
linux·kubernetes·rancher
大都督老师20 小时前
配置 containerd 使用镜像加速器拉取 Docker Hub 镜像
容器·kubernetes·k8s