目录

一、概念

二、nodeAffinity-节点亲和性

1.给k8s节点创建标签

2.编辑资源清单设置节点亲和性

3.查看pod所在节点,验证亲和性

三、podAffinity-pod的亲和性

1.编辑资源清单设置pod亲和性

2.查看pod所在节点

四、podAntAffinity-pod的反亲和性


一、概念

在K8S中,亲和性(Affinity)用来定义Pod与节点关系的概念,亲和性通过指定标签选择器和拓扑域约束来决定 Pod 应该调度到哪些节点上。与污点相反,它主要是尽量往某节点靠。

关键点是标签label

在k8s当中,“亲和性”分为三种,节点亲和性、pod亲和性、pod反亲和性;

亲和性分类名称解释说明
nodeAffinity节点亲和性通过【节点】标签匹配,用于控制pod调度到哪些node节点上,以及不能调度到哪些node节点上;(主角node节点)
podAffinitypod亲和性通过【节点+pod】标签匹配,可以和哪些pod部署在同一个节点上(拓扑域);(主角是pod)
podAntiAffinitypod反亲和性通过【节点+pod】标签匹配,与pod亲和性相反,就是和那些pod不在一个节点上(拓扑域);

二、nodeAffinity-节点亲和性

  1. 亲和与反亲和。nodeSelector 提供了一种非常简单的方法来将 pod 约束到具有特定标签的节点上。亲和/反亲和功能极大地扩展了你可以表达约束的类型。
  2. 你可以发现规则是“软”/“偏好”,而不是硬性要求,因此,如果调度器无法满足该要求,仍然调度该 pod
  3. 你可以使用节点上的 pod 的标签来约束,而不是使用节点本身的标签,来允许哪些 pod 可以或者不可以被放置在一起。
  4. 节点亲和(仅作用于调度期间)
    1. requiredDuringSchedulingIgnoredDuringExecution 必须满足
    2. preferredDuringSchedulingIgnoredDuringExecution 倾向满足
  5. IgnoreDuringExecution 表示如果在Pod运行期间Node的标签发生变化,导致亲和性策略不能满足,则继续运行当前的Pod。
  6. nodeaffinity还支持多种规则匹配条件的配置如
    1. In:label 的值在列表内
    2. NotIn:label 的值不在列表内
    3. Gt:label 的值大于设置的值,不支持Pod亲和性
    4. Lt:label 的值小于设置的值,不支持pod亲和性
    5. Exists:设置的label 存在
    6. DoesNotExist:设置的 label 不存在

1.给k8s节点创建标签

[root@k8s1 ~]# kubectl label nodes k8s1 k8s=oslee1
node/k8s1 labeled
[root@k8s1 ~]# kubectl label nodes k8s2 k8s=oslee2
node/k8s2 labeled

# 查看标签
[root@k8s1 ~]# kubectl get nodes --show-labels
NAME   STATUS   ROLES                  AGE     VERSION    LABELS
k8s1   Ready    control-plane,master   5d12h   v1.23.17   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,k8s=oslee1,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s1,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=,node=k8s1,os=lee
k8s2   Ready    <none>                 5d12h   v1.23.17   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,k8s=oslee2,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s2,kubernetes.io/os=linux,node=k8s2,os=lee

2.编辑资源清单设置节点亲和性

[root@k8s1 deploy]# cat deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dm-affinity
spec: 
  replicas: 20
  selector: 
    matchLabels:
      k8s: oslee
  template:
    metadata:
      name: pod-affinity 
      labels:
        k8s: oslee
    spec:
      #声明亲和性
      affinity:
        #声明亲和性类型
        nodeAffinity:
          #硬亲和力,即支持必须部署在指定的节点上,也支持必须不部署在指定的节点上(不满足下面的条件,亲和性就设置失败)
          requiredDuringSchedulingIgnoredDuringExecution:
            #设置节点选择器列表:
            nodeSelectorTerms:
            #声明基于节点的标签进行关联
            - matchExpressions:
              - key: k8s
                values: 
                - oslee1
                - oslee2
                #设置key和value的关系;
                #--In:key==value(必须写value)
                #--NotIn:key !=value(必须写value)
                operator: In
          #软亲和力:尽量部署在满足条件的节点上,或尽量不要部署在被匹配的节点上
          preferredDuringSchedulingIgnoredDuringExecution:
          #配置权重
          - weight: 1
            #偏向性
            preference:
              #基于节点的标签进行关联
              matchExpressions:
              #节点的标签名称
              - key: k8s
                values:
                # 硬亲和力设置了oslee1和oslee2,软亲和力使尽量在oslee1上
                - oslee1
                #关联关系,表示key和values的关系
                #In:表示包含关系(value必须写),部署在满足条件的节点上
                #NotIn:表示不包含(value必须写),匹配不在条件中的节点,实现节点反亲和性
                #Exists: 表示存在关系(只要存在 key 名字就可以,不能写value)
                #DoesNotExist:不存在(不能写value),实现节点反亲和性
                #Gt:大于(value 为数值,大于节点上的值)
                #Lt:小于(value 为数值,小于节点上的值)
                operator: In
      containers:
      - name: c1
        image: nginx:1.20.1-alpine
        ports:
        - containerPort: 80


[root@k8s1 deploy]# kubectl apply -f deploy.yaml 
deployment.apps/dm-affinity created

3.查看pod所在节点,验证亲和性

[root@k8s1 deploy]# kubectl get all -owide

三、podAffinity-pod的亲和性

基于“节点标签”进行设置,第一个pod副本创建在了哪个节点上,那么其余副本也会创建在这个节点上;

拓扑域:节点机器的标签的key和value都相等的机器,就是同一个拓扑域;

1.编辑资源清单设置pod亲和性

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dm-affinity
spec: 
  replicas: 20
  selector: 
    matchLabels:
      k8s: oslee
  template:
    metadata:
      name: pod-affinity 
      labels:
        k8s: oslee
    spec:
      #声明亲和性
      affinity:
        #声明亲和性类型
        podAffinity:
          #硬限制,必须满足的条件有哪些?(不满足下面的条件,亲和性就设置失败)
          requiredDuringSchedulingIgnoredDuringExecution:
          #设置拓扑域,指定【节点的标签名】
          #【节点key】就是说,设置了拓扑域,pod就会往这个标签的节点进行创建

          #只要满足key是k8s的节点的标签,那么就是同一个拓扑域
          - topologyKey: k8s
            #【pod标签】确定pod的标签,用于二次确认,选中了拓扑域(节点标签的key),再次选中pod标签才能确认调度到哪个节点;
            labelSelector:
              matchExpressions: 

              #意思是说,只要key的值是k8s的pod创建在了哪个节点,“我”就跟随他。也创建在这个节点上;
              - key: k8s
                #如果pod标签,出现了key值相同,value值不同的情况下,就不见设置Exists存在的关系了
                #建议设置:In的方式进行匹配,当然此时Value就不能设置了;
                operator: Exists
      containers:
      - name: c1
        image: nginx:1.20.1-alpine
        ports:
        - containerPort: 80

[root@k8s1 deploy]# kubectl apply -f deploy.yaml 
deployment.apps/dm-affinity created

2.查看pod所在节点

四、podAntAffinity-pod的反亲和性

pod的亲和性:符合拓扑域的范围,指定标签的pod创建在哪里,其他pod就创建在哪里;

pod的反亲和性:与之相反,符合拓扑域的范围,指定标签的pod创建在哪里,其他pod就不能创建在哪里;

[root@k8s1 deploy]# cat deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dm-affinity
spec: 
  replicas: 4
  selector: 
    matchLabels:
      k8s: oslee
  template:
    metadata:
      name: pod-affinity 
      labels:
        k8s: oslee
    spec:
      #声明亲和性
      affinity:
        #声明亲和性类型
        podAntiAffinity:
          #硬限制,必须满足的条件有哪些?(不满足下面的条件,亲和性就设置失败)
          requiredDuringSchedulingIgnoredDuringExecution:
          #设置拓扑域,指定【节点的标签名】
          #【节点key】就是说,设置了拓扑域,pod就会往这个标签的节点进行创建
          - topologyKey: k8s
            #【pod标签】确定pod的标签,用于二次确认,选中了拓扑域(节点标签的key),再次选中pod标签才能确认调度到哪个节点;
            labelSelector:
              matchExpressions: 
              - key: k8s
                #如果pod标签,出现了key值相同,value值不同的情况下,就不见设置Exists存在的关系了
                #建议设置:In的方式进行匹配,当然此时Value就不能设置了;
                operator: Exists
      containers:
      - name: c1
        image: nginx:1.20.1-alpine
        ports:
        - containerPort: 80

[root@k8s1 deploy]# kubectl apply -f deploy.yaml 
deployment.apps/dm-affinity created

[root@k8s1 deploy]# kubectl get all -owide

 结论:

  1. 由于第一pod创建在了k8s1,所以第二个pod就无法再k8s1中创建;
  2. 第二个pod就再k8s2中创建了;
  3. 由于我们是4个副本,只有两个节点,pod3和pod4没法创建了;

==============================至此,已成艺术===============================

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐