K8s Affinity亲和力详解(调度策略)

 更新时间:2025年08月14日 09:50:32   作者:大新屋  
文章介绍了Kubernetes中亲和力和反亲和力的调度策略,包括节点和Pod的硬性、软性规则,用于实现Pod与节点的标签匹配、区域均衡负载及避免单节点过载等场景,强调标签匹配和副本数限制对调度结果的影响

K8s Affinity亲和力

提示:Kubernetes 官网Affinity说明文档 https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/

kubernetes Affinity亲和力是一种调度策略,用于确保Pod被调度到具有特定标签(label)或字段的节点上。

亲和力和反亲和力:

  • 亲和力和反亲和力可以用来控制 Pod 如何调度到节点上。
  • 亲和力表示 Pod 要求与特定的节点调度在一起,反亲和力表示 Pod 不希望与特定的节点调度在一起。

Affinity亲和力分为两类:

  • 节点亲和力:NodeAffinity (包括节点亲和力和节点反亲和力)
  • Pod亲和力:PodAffinity/PodAntiAffinity(PodAffinity Pod亲和力和PodAntiAffinity Pod反亲和力)

亲和力和反亲和力有两种性:

  • requiredDuringSchedulingIgnoredDuringExecution(硬亲和性):这种类型亲和力是硬性,表示Pod必须被调度到满足指定条件的节点上。如果不满足条件,Pod将不会被调度。
  • preferredDuringSchedulingIgnoredDuringExecution(软亲和性):这种类型亲和力是软性,表示Pod更倾向于被调度到满足指定条件的节点上,但如果无法满足,Pod仍会被调度到其他节点。

一、Affinity参数说明

提示:节点反亲和力通过operator参数设置成Notln值实现

1、节点nodeAffinity(硬性)亲和力

spec:
  affinity:                                             # 定义Affinity亲和力配置
    nodeAffinity:                                       # 定义节点Affinity亲和力配置
      requiredDuringSchedulingIgnoredDuringExecution:   # 定义硬性Affinity亲和力配置
        nodeSelectorTerms:                              # 定义节点选择器配置
        - matchExpressions:                             # 定义匹配节点标签键值对key=value
          - key: disktype                               # 设置节点标签键名key
            operator: In                                # 节点标签匹配方式,In等于
            values:                                     # 设置节点标签值value
            - ssd

2、节点nodeAffinity(软性)亲和力

spec:
  affinity:                                               # 定义Affinity亲和力配置
    nodeAffinity:                                         # 定义节点Affinity亲和力配置
      preferredDuringSchedulingIgnoredDuringExecution:    # 定义软性Affinity亲和力配置
      - weight: 10                                        # 软亲和力的权重,权重越高优先级越大,范围1-100
        preference:                                       # 软亲和力配置项
          matchExpressions:                               # 定义匹配节点标签键值对key=value
          - key: disktype                                 # 设置节点标签键名key
            operator: In                                  # 节点标签匹配方式,In等于
            values:                                       # 设置节点标签值value
            - ssd

3、Pod podAffinity(硬性)亲和力

spec:
  affinity:                                            # 定义Affinity亲和力配置
    podAffinity:                                       # 定义Pod Affinity亲和力配置
      requiredDuringSchedulingIgnoredDuringExecution:  # 定义Affinity硬性亲和力配置
      - labelSelector:                                 # 定义Pod选择器配置
          matchExpressions:                            # 定义匹配Pod标签键值对key=value
          - key: disktype              i               # 设置Pod标签键名key
            operator: In                               # Pod标签规则匹配条件,In等于
            values:                                    # 设置Pod标签值value
            - ssd
        topologkey: kubernetes.io/hostname             # 定义亲和力的范围,匹配的拓扑域的key,也就是节点上label和key,key和value相同的为同一个域。topologyke拓扑域,主要针对宿主机,相当于对宿主机进行区域的划分。用label进行判断,不同的key和不同的value是属于不同的拓扑域。kubernetes.io/hostname是K8s默认节点标签

4、Pod podAffinity(软性)亲和力

spec:
  affinity:                                             # 定义Affinity亲和力配置
    podAffinity:                                        # 定义Pod Affinity亲和力配置
      requiredDuringSchedulingIgnoredDuringExecution:   # 定义Affinity硬性亲和力配置
      - labelSelector:                                  # 定义Pod选择器配置
          matchExpressions:                             # 定义匹配Pod标签键值对key=value
          - key: disktype                               # 设置Pod标签键名key
            operator: In                                # Pod标签规则匹配条件,In等于
            values:                                     # 设置Pod标签值value
            - ssd
        topologkey: kubernetes.io/hostname              # 定义亲和力的范围,匹配的拓扑域的key,也就是节点上label和key,key和value相同的为同一个域。topologyke拓扑域,主要针对宿主机,相当于对宿主机进行区域的划分。用label进行判断,不同的key和不同的value是属于不同的拓扑域。kubernetes.io/hostname是K8s默认节点标签

5、Pod podAffinity(硬性)反亲和力

spec:
  affinity:                                             # 定义Affinity亲和力配置
    podAffinity:                                        # 定义Pod Affinity亲和力配置
      requiredDuringSchedulingIgnoredDuringExecution:   # 定义Affinity硬性亲和力配置
      - labelSelector:                                  # 定义Pod选择器配置
          matchExpressions:                             # 定义匹配Pod标签键值对key=value
          - key: disktype                               # 设置Pod标签键名key
            operator: In                                # Pod标签规则匹配条件,In等于
            values:                                     # 设置Pod标签值value
            - ssd
        topologkey: kubernetes.io/hostname             # 定义亲和力的范围,匹配的拓扑域的key,也就是节点上label和key,key和value相同的为同一个域。topologyke拓扑域,主要针对宿主机,相当于对宿主机进行区域的划分。用label进行判断,不同的key和不同的value是属于不同的拓扑域。kubernetes.io/hostname是K8s默认节点标签

6、Pod podAntAffinity(软性)反亲和力

spec:
  affinity:                                                 # 定义Affinity亲和力配置
    podAntAffinity:                                         # 定义Pod Affinity反亲和力配置
      preferredDuringSchedulingIgnoredDuringExecution:      # 定义Affinity软性反亲和力配置
      - weight: 10                                          # 反亲和力的权重,权重越高反亲和力越大,范围1-100
        podAffinityTerm:                                   # Pod反亲和力配置项
          labelSelector:                                   # 定义Pod选择器配置
            matchExpressions:                              # 定义匹配Pod标签键值对key=value
            - key: security                                # 设置Pod标签键名key
              operator: In                                 # Pod标签规则匹配条件,In等于
              values:                                      # 设置Pod标签值value
              - S2
          topologyKey: failure-domain.beta.kubernetes.io/zone   # 定义反亲和力的范围,匹配的拓扑域的key,也就是节点上label和key,key和value相同的为同一个域。topologyke拓扑域,主要针对宿主机,相当于对宿主机进行区域的划分。用label进行判断,不同的key和不同的value是属于不同的拓扑域。

7、operator参数规则匹配条件

operator                # 规则匹配条件
  --- In                # 相当于key=value的形式(等于)
  --- Notln             # 相当于key!=value的形式(不等于)
  --- Exists            # 节点存在label的key为指定的值即可,不能配置values字段
  --- DoesNotExist      # 节点不存在label的key为指定的值即可,不能配置values字段
  --- Gt                # 大于value指定的值
  --- Lt                # 小于value指定的值

二、示例1:节点Affinity(硬性)亲和力(强制Pod部署到指定节点)

### 查看K8s集群节点是否有污点,如果有污点需要清除节点污点,为了不影响Affinity亲和力参数
kubectl get nodes -o=custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

### 选择k8s-node01和k8s-node02节点打标签
kubectl label node k8s-node01 k8s-node02 disktype=ssd
kubectl get nodes --show-labels -l disktype=ssd

### 创建Deployment
mkdir -p /data/yaml/affinity
cat > /data/yaml/affinity/deploy-nodeaffinity-hard.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: deploy-nodeaffinity-hard
  name: deploy-nodeaffinity-hard
  namespace: default
spec:
  replicas: 6
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: disktype
                operator: In
                values:
                - ssd
      containers:
      - name: nginx
        image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.26
        imagePullPolicy: IfNotPresent
EOF

kubectl create -f /data/yaml/affinity/deploy-nodeaffinity-hard.yaml
kubectl get deploy deploy-nodeaffinity-hard -n default -oyaml

### 查看Pod节点部署节点
kubectl get pods -n default -owide

### 删除Deployment和节点标签
kubectl delete -f /data/yaml/affinity/deploy-nodeaffinity-hard.yaml
kubectl label nodes k8s-node01 k8s-node02 disktype-

三、示例2:节点Affinity(软性)亲和力(尽可能Pod部署到指定节点)

### 查看K8s集群节点是否有污点,如果有污点需要清除节点污点,为了不影响Affinity亲和力参数
kubectl get nodes -o=custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

### 选择k8s-node02节点打标签
kubectl label node k8s-node02 node=erp
kubectl get nodes --show-labels -l node=erp

### 创建Deployment
mkdir -p /data/yaml/affinity
cat > /data/yaml/affinity/deploy-nodeaffinity-soft.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: deploy-nodeaffinity-soft
  name: deploy-nodeaffinity-soft
  namespace: default
spec:
  replicas: 10
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
              matchExpressions:
              - key: node
                operator: In
                values:
                - erp
      containers:
      - name: nginx
        image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.26
        imagePullPolicy: IfNotPresent
EOF

kubectl create -f /data/yaml/affinity/deploy-nodeaffinity-soft.yaml
kubectl get deploy deploy-nodeaffinity-soft -n default -oyaml

### 查看Pod节点部署节点
kubectl get pods -n default -owide

### 删除Deployment和节点标签
kubectl delete -f /data/yaml/affinity/deploy-nodeaffinity-soft.yaml
kubectl label nodes k8s-node02 node-

四、示例3:Pod Affinity(硬性)反亲和力(强制Pod部署到指定的不同的节点)

示例场景描述:假如k8s-node01是深圳机房,k8s-node02是北京机房,k8s-master03是杭州机房,每个不同的机房部署一个nginx容器,实现区域性均衡负载

提示:当Deployment定义启动超过3个Pod数量,但节点只定义了3个key,当定义了3个key节点各自都只能运行一个Pod(不会运行两个以上的Pod),那剩下的Pod会在其它节点上运行

### 查看K8s集群节点是否有污点,如果有污点需要清除节点污点,为了不影响Affinity亲和力参数
kubectl get nodes -o=custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

### 节点创建label中键名key要一样,但value值不要一样,topologyke拓扑域参数才能区分不同的区域
kubectl get nodes
kubectl label nodes k8s-master01 area=hangzhou
kubectl label nodes k8s-node01 area=shenzhen
kubectl label nodes k8s-node02 area=beijing
kubectl get nodes --show-labels | grep area

### 创建Deployment 
mkdir -p /data/yaml/affinity
cat > /data/yaml/affinity/deploy-podantaffinity-area.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: deploy-podantaffinity-area
  name: deploy-podantaffinity-area
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      run: deploy-pod-area
  template:
    metadata:
      labels:
        run: deploy-pod-area
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: run
                operator: In
                values:
                - deploy-pod-area
            topologyKey: area
      containers:
      - name: nginx
        image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.26
        imagePullPolicy: IfNotPresent
EOF

kubectl create -f /data/yaml/affinity/deploy-podantaffinity-area.yaml
kubectl get deploy deploy-podantaffinity-area -n default -oyaml

### 查看Pod节点部署节点
kubectl get pods -n default -owide

### 删除Deployment和节点标签
kubectl delete -f /data/yaml/affinity/deploy-podantaffinity-area.yaml
kubectl label nodes k8s-node01 k8s-node02 k8s-master01 area-

五、示例4:Pod Affinity(硬性)反亲和力(强制Pod部署到K8s集群中每一个节点)

提示:Deployment设置的Pod副本数不能超过K8s节点数,超过的Pod副本数启动Pod会失败,kubernetes.io/hostname是K8s内置的默认标签

### 查看K8s集群节点是否有污点,如果有污点需要清除节点污点,为了不影响Affinity亲和力参数
kubectl get nodes -o=custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

### 创建Deployment 
mkdir -p /data/yaml/affinity
cat > /data/yaml/affinity/deploy-podantaffinity-hostname.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: deploy-podantaffinity-hostname
  name: deploy-podantaffinity-hostname
  namespace: default
spec:
  replicas: 5
  selector:
    matchLabels:
      run: deploy-pod-hostname
  template:
    metadata:
      labels:
        run: deploy-pod-hostname
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: run
                operator: In
                values:
                - deploy-pod-hostname
            topologyKey: kubernetes.io/hostname
      containers:
      - name: nginx
        image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.26
        imagePullPolicy: IfNotPresent
EOF

kubectl create -f /data/yaml/affinity/deploy-podantaffinity-hostname.yaml
kubectl get deploy deploy-podantaffinity-hostname -n default -oyaml

### 查看Pod节点部署节点
kubectl get pods -n default -owide

### 删除Deployment
kubectl delete -f /data/yaml/affinity/deploy-podantaffinity-hostname.yaml

六、示例5:节点Affinity(软性)亲和力(重要Pod尽可能部署在高性能节点)

测试场景描述: nginx容器不部署到master节点,nginx容器第一选择部署到高存储性能k8s-node01,如果k8s-node01节点出现故障,第二选择部署到k8s-node02节点

### 查看K8s集群节点是否有污点,如果有污点需要清除节点污点,为了不影响Affinity亲和力参数
kubectl get nodes -o=custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

### 节点创建label
kubectl get nodes
kubectl label nodes k8s-master01 k8s-master02 k8s-master03 master=manager
kubectl label nodes k8s-node01 ssd=fastest
kubectl label nodes k8s-node02 sata=faster
kubectl get nodes --show-labels | grep master=manager
kubectl get nodes --show-labels | grep ssd
kubectl get nodes --show-labels | grep sata

### 创建Deployment
mkdir -p /data/yaml/affinity
cat > /data/yaml/affinity/nginx-deploy-select.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy-select
  name: nginx-deploy-select
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            preference:
              matchExpressions:
              - key: ssd
                operator: In
                values:
                - "fastest"
              - key: master
                operator: NotIn
                values:
                - "manager"
          - weight: 50
            preference:
              matchExpressions:
              - key: sata
                operator: In
                values:
                - "faster"
      containers:
      - name: nginx
        image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.26
        imagePullPolicy: IfNotPresent
EOF

kubectl create -f /data/yaml/affinity/nginx-deploy-select.yaml
kubectl get deploy nginx-deploy-select -n default -oyaml

### 查看Pod节点部署节点
kubectl get pods -n default -owide

### 删除Deployment
kubectl delete -f /data/yaml/affinity/deploy-podantaffinity-hostname.yaml

### 删除Deployment和节点标签
kubectl delete -f /data/yaml/affinity/nginx-deploy-select.yaml
kubectl label nodes k8s-node01 k8s-master01 k8s-master02 k8s-master03 master-
kubectl label nodes k8s-node01 ssd-
kubectl label nodes k8s-node02 sata-

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • ragflow k8s部署过程图文详解

    ragflow k8s部署过程图文详解

    这篇文章主要介绍了ragflow k8s部署详细过程,本文将使用ragflow-0.18.0,来进行演示详细部署过程,需要的朋友可以参考下
    2025-04-04
  • K8S中Pod重启策略及重启可能原因详细讲解

    K8S中Pod重启策略及重启可能原因详细讲解

    在k8s集群中当某个pod资源需要重启时,我们只会对其进行删除,由其pod控制器进行重新构建,下面这篇文章主要给大家介绍了关于K8S中Pod重启策略及重启可能原因的相关资料,需要的朋友可以参考下
    2023-05-05
  • k8s自身原理service及实现图文示例解析

    k8s自身原理service及实现图文示例解析

    这篇文章主要为大家介绍了k8s自身原理service图文示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • K8s学习之Pod的定义及详细资源调用案例

    K8s学习之Pod的定义及详细资源调用案例

    Kubernetes将所有内容抽象为资源,通过操作资源管理集群,核心单元是Pod,通过控制器管理Pod,资源管理分为命令式对象管理、命令式对象配置和声明式对象配置,各有适用场景,需要的朋友可以参考下
    2024-09-09
  • Spark三种属性配置方式详解

    Spark三种属性配置方式详解

    有时间还是多学习知识比较好,这篇文章主要介绍了Spark三种属性配置方式详解,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • 使用sealos快速搭建K8s集群环境的过程

    使用sealos快速搭建K8s集群环境的过程

    这篇文章主要介绍了使用sealos快速搭建K8s集群环境,主要包括sealos安装方法,虚拟机设置方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • MinIO分布式文件存储(从入门到飞翔)

    MinIO分布式文件存储(从入门到飞翔)

    MinIO是一款高性能的分布式对象存储系统,兼容Amazon S3协议,具有轻量级、易部署、高可用和可扩展性等优势,它通过纠删码技术实现数据冗余与高容错性,适用于私有云存储、大数据分析和静态资源托管等场景,本文介绍MinIO分布式文件存储的相关知识,感兴趣的朋友一起看看吧
    2025-03-03
  • k8s clientConfig和rawConfig区别解析

    k8s clientConfig和rawConfig区别解析

    k8s clientConfig和rawConfig区别k8s.io/client-gov0.28.2基于kubeconfig可以创建clientConfig和rawConfig,两者区别在于,clientConfig包含了访问kube-apiserver的地址和认证鉴权信息,感兴趣的朋友一起看看吧
    2025-03-03
  • Rainbond调用Vue React项目的后端接口

    Rainbond调用Vue React项目的后端接口

    这篇文章主要为大家介绍了Rainbond调用Vue React项目的后端接口问题解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • 使用kubeadm部署多节点集群

    使用kubeadm部署多节点集群

    这篇文章介绍了使用kubeadm部署多节点集群的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04

最新评论