kubernetes之Affinity亲和性

背景介绍

一般情况部署的Pod是通过集群的自动调度策略来选择节点,默认情况下调度器考虑的是资源足够,并且负载尽量平均。但是有时候我们并不需要一些服务都部署在同一节点上,害怕服务之间产生影响;但是有时候也需要部署在同一节点上。这时候就用到了亲和性与反亲和性

亲和性种类:nodeAffinity(节点亲和性)、podAffinity(Pod亲和性)

nodeSelector

首先了解最常见与简单的调度方法nodeSelector。通过匹配label去匹配Pod资源。查看node的label

kubectl get nodes --show-labels

为node添加label

kubectl label nodes node1 app=test

之后在Pod的yaml文件中的spec字段添加即可,文档添加的是node-role.kubernetes.io/worker(kubernetes内置节点标签)

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    app: test

亲和性与反亲和性

调度策略:软策略与硬策略

  • 软策略:满足条件最好,不满足也可以。preferredDuringSchedulingIgnoredDuringExecution
  • 硬策略:必须满足,不然就不干了。requiredDuringSchedulingIgnoredDuringExecution

nodeAffinity

控制pod可以部署在哪些node上,不可以在那些node上。
示例分析

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: affinity
spec:
  replicas: 2
  revisionHistoryLimit: 15
  template:
    metadata:
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: nginxweb
      affinity:
        nodeAffinity:     #节点亲和
          requiredDuringSchedulingIgnoredDuringExecution:  # 硬策略
            nodeSelectorTerms:   
            - matchExpressions:  #匹配label
              - key: kubernetes.io/hostname
                operator: NotIn
                values:
                - node03
          preferredDuringSchedulingIgnoredDuringExecution:  # 软策略
          - weight: 1
            preference:
              matchExpressions:
              - key: app
                operator: In
                values:
                - test

解释说明:不能运行在node03节点上。如果有节点满足app=test,就先调度到这个节点上。
操作符operator

  • In:label 的值在某个列表中
  • NotIn:label 的值不在某个列表中
  • Gt:label 的值大于某个值
  • Lt:label 的值小于某个值
  • Exists:某个 label 存在
  • DoesNotExist:某个 label 不存在

:如果指定多个nodeSelectorTerms,满足其中一个即可
如果指定多个matchExpressions,必须满足所有

pod亲和与反亲和

示例分析

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: failure-domain.beta.kubernetes.io/zone   #内置节点标签
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: failure-domain.beta.kubernetes.io/zone
  containers:
  - name: with-pod-affinity
    image: k8s.gcr.io/pause:2.0

内置节点标签如下:
kubernetes.io/hostname
failure-domain.beta.kubernetes.io/zone
failure-domain.beta.kubernetes.io/region
beta.kubernetes.io/instance-type
kubernetes.io/os
kubernetes.io/arch

文件解释说明:在这个 pod 的 affinity 配置定义了一条 pod 亲和规则和一条 pod 反亲和规则。在此示例中,podAffinity 配置为 requiredDuringSchedulingIgnoredDuringExecution,然而 podAntiAffinity 配置为 preferredDuringSchedulingIgnoredDuringExecution。pod 亲和规则表示,仅当节点和至少一个已运行且有键为“security”且值为“S1”的标签的 pod 处于同一区域时,才可以将该 pod 调度到节点上。(更确切的说,如果节点 N 具有带有键 failure-domain.beta.kubernetes.io/zone 和某个值 V 的标签,则 pod 有资格在节点 N 上运行,以便集群中至少有一个节点具有键 failure-domain.beta.kubernetes.io/zone 和值为 V 的节点正在运行具有键“security”和值“S1”的标签的 pod。)pod 反亲和规则表示,如果节点已经运行了一个具有键“security”和值“S2”的标签的 pod,则该 pod 不希望将其调度到该节点上。(如果 topologyKey 为 failure-domain.beta.kubernetes.io/zone,则意味着当节点和具有键“security”和值“S2”的标签的 pod 处于相同的区域,pod 不能被调度到该节点上。)

操作符:In NotIn Exists DoesNotExist

topologyKey 可以是任何合法的标签键。然而,出于性能和安全原因,topologyKey 受到一些限制

  1. 对于亲和与 requiredDuringSchedulingIgnoredDuringExecution 要求的 pod
    反亲和,topologyKey 不允许为空。
  2. 对于 requiredDuringSchedulingIgnoredDuringExecution 要求的 pod 反亲和,准入控制器
    LimitPodHardAntiAffinityTopology 被引入来限制 topologyKey 不为
    kubernetes.io/hostname。如果你想使它可用于自定义拓扑结构,你必须修改准入控制器或者禁用它。
  3. 对于 preferredDuringSchedulingIgnoredDuringExecution 要求的 pod 反亲和,空的
    topologyKey 被解释为“所有拓扑结构”(这里的“所有拓扑结构”限制为
    kubernetes.io/hostname,failure-domain.beta.kubernetes.io/zone 和
    failure-domain.beta.kubernetes.io/region 的组合)。
  4. 除上述情况外,topologyKey 可以是任何合法的标签键。

示例2

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: affinity
  labels:
    app: affinity
spec:
  replicas: 2
  revisionHistoryLimit: 15
  template:
    metadata:
      labels:
        app: affinity
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: nginxweb
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:  # 硬策略
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - busybox-pod
            topologyKey: kubernetes.io/hostname

解释:如果一个节点上面有一个app=busybox-pod这样的 pod 的话,那么我们的 pod 就别调度到这个节点上面来

你可能感兴趣的:(k8s)