Kubernetes(k8s)亲和力Affinity

需求:

Pod和Node之间的关系

某些Pod优先选择有ssd=true标签的节点,如果没有在考虑部署到其它节点;
某些Pod需要部署在ssd=true和type=physical的节点上,但是优先部署在ssd=true的节点上;

Pod和Pod之间的关系

同一个应用的Pod不同的副本或者同一个项目的应用尽量或必须不部署在同一个节点或者符合某个标签的一类节点上或者不同的区域;
相互依赖的两个Pod尽量或必须部署在同一个节点上或者同一个域内。

Affinity分类

image.png

节点亲和力配置详解

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:      # 硬亲和力配置
        nodeSelectorTerms:      # 节点选择器配置,可以配置多个matchExpressions(满足其一),每个matchExpressions下可以配置多个key、value类型的选择器(都需要满足),其中values可以配置多个(满足其一)
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In      # 标签匹配的方式 
                                     # In:相当于key = value的形式
                                     # NotIn:相当于key != value的形式 
                                     # Exists:节点存在label的key为指定的值即可,不能配置values字段
                                     # DoesNotExist:节点不存在label的key为指定的值即可,不能配置values字段
            values:
            - e2e-az1
            - az-2
      preferredDuringSchedulingIgnoredDuringExecution:      # 软亲和力配置
      - weight: 1      # 软亲和力的权重,权重越高优先级越大,范围1-100
        preference:      # 软亲和力配置项,和weight同级,可以配置多个
          matchExpressions:      # 和硬亲和力一致
          - key: another-node-label-key
            operator: In      # 标签匹配的方式 
                                     # In:相当于key = value的形式
                                     # NotIn:相当于key != value的形式 
                                     # Exists:节点存在label的key为指定的值即可,不能配置values字段
                                     # DoesNotExist:节点不存在label的key为指定的值即可,不能配置values字段
            values:
            - another-node-label-value
  containers:
  - name: with-node-affinity
    image: nginx

Pod亲和力和反亲和力详解

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity:      # pod亲和力配置
      requiredDuringSchedulingIgnoredDuringExecution:      # 硬亲和力配置
      - labelSelector:      # Pod的lableSelector配置,可以配置多个
          matchExpressions:      # 配置和节点亲和力配置一致
          - key: security
            operator: In      # 配置和节点亲和力一致
            values:
            - S1
        topologyKey: failure-domain.beta.kubernetes.io/zone      # 匹配的拓扑域的key,也就是节点上label的key,key和value相同的为同一个域,可以用于标注不同的机房和地区
    podAntiAffinity:      # pod反亲和力配置
      preferredDuringSchedulingIgnoredDuringExecution:      # 软亲和力配置
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          namespaces:      # 和哪个命名空间的Pod进行匹配,空为default命名空间,可以写多个namespace
          - default
          topologyKey: failure-domain.beta.kubernetes.io/zone      # 匹配的拓扑域的key,也就是节点上label的key,key和value相同的为同一个域,可以用于标注不同的机房和地区
  containers:
  - name: with-pod-affinity
    image: nginx

示例1:同一个应用部署在不同的宿主机

使用pod的亲和力app=must-be-diff-nodes, 通过节点默认label topologyKey: kubernetes.io/hostname 实现每个pod都调度到不同的宿主机

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: must-be-diff-nodes
  name: must-be-diff-nodes
  namespace: kube-public
spec:
  replicas: 3
  selector:      # Pod选择器配置,可以配置多个
    matchLabels:      # 配置和节点亲和力一致
      app: must-be-diff-nodes
  template:
    metadata:
      labels:
        app: must-be-diff-nodes
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In      # 配置和节点亲和力一致
                values:
                - must-be-diff-nodes
            topologyKey: kubernetes.io/hostname      # 匹配的拓扑域的key,也就是节点上label的key,key和value相同的为同一个域,可以用于标注不同的机房和地区
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent
        name: must-be-diff-nodes

示例2:同一个应用不同副本固定节点

使用pod反亲和力app=store,通过topologyKey: "kubernetes.io/hostname"实现多副本的pod,不调度到同一台节点上

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-cache
spec:
  selector:
    matchLabels:
      app: store
  replicas: 3
  template:
    metadata:
      labels:
        app: store
    spec:
      nodeSelector:
          app: store
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - store
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: redis-server
        image: redis:3.2-alpine

示例3:应用和缓存尽量部署在同一个域内

使用pod的硬亲和性和软亲和性,实现pod app=store的label尽量部署在同一个域中

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  selector:
    matchLabels:
      app: web-store
  replicas: 3
  template:
    metadata:
      labels:
        app: web-store
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - web-store
            topologyKey: "kubernetes.io/hostname"
        podAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - store
              topologyKey: "kubernetes.io/hostname"
      containers:
      - name: web-app
        image: nginx:1.16-alpine

示例4:尽量调度到高配置服务器

通过节点的硬亲和性,一次匹配ssd=true,weight100,weight10

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: prefer-ssd
  name: prefer-ssd
  namespace: kube-public
spec:
  replicas: 3
  selector:
    matchLabels:
      app: prefer-ssd
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: prefer-ssd
    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - preference:
              matchExpressions:
              - key: ssd
                operator: In
                values:
                - "true"
              - key: master
                operator: NotIn
                values:
                - "true"
            weight: 100
          - preference:
              matchExpressions:
              - key: type
                operator: In
                values:
                - physical
            weight: 10
      containers:
      - env:
        - name: TZ
          value: Asia/Shanghai
        - name: LANG
          value: C.UTF-8
        image: nginx
        imagePullPolicy: IfNotPresent
        name: prefer-ssd

TopologyKey配置详解

匹配的拓扑域的key,也就是节点上label的key,key和value相同的为同一个域,可以用于标注不同的机房和地区


image.png

image.png

示例:同一个应用多区域部署

通过pod的硬亲和性,和topologyKey node节点的同一个key,不同的value实现多区域部署

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: must-be-diff-zone
  name: must-be-diff-zone
  namespace: kube-public
spec:
  replicas: 3
  selector:
    matchLabels:
      app: must-be-diff-zone
  template:
    metadata:
      labels:
        app: must-be-diff-zone
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - must-be-diff-zone
            topologyKey: region      # region为node的label,上述图中,region分别=daxing、chaoyang
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent
        name: must-be-diff-zone

你可能感兴趣的:(Kubernetes(k8s)亲和力Affinity)