亲和性 && 反亲和性

在默认的K8S调度中,一般经过预选和优选即可完成调度,但是生产的实际使用中,考虑到部分业务的特殊性,一般会手动进行一些"指定", K8S 把这些"指定"分为nodeAffinity(节点亲和性)、podAffinity(pod 亲和性) 以及 podAntiAffinity(pod 反亲和性), 这在调度过程中,称之为亲和性调度,亲和性调度可以分成软策略(preferredDuringSchedulingIgnoredDuringExecution )和硬策略(requiredDuringSchedulingIgnoredDuringExecution)两种方式,软策略意思是如果现在没有满足调度要求要求的话,那就跳过这条策略,继续调度,总结起来就是"有则用之,无则跳过", 而硬策略相对就强硬很多,如果不满足调度策略,则不停重试,直到满足策略。

nodeAffinity:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: affinity-test
  labels:
    app: affinity-test
spec:
  replicas: 2
  selector:
    matchLabels:
      app: affinity-test
  template:
    metadata:
      labels:
        app: affinity-test
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
          name: nginxhttp
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:  # 硬策略
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/hostname
                operator: NotIn
                values:
                - nginx-node001
          preferredDuringSchedulingIgnoredDuringExecution:  # 软策略
          - weight: 1
            preference:
              matchExpressions:
              - key: webnode
                operator: In
                values:
                - true

pod 有podAffinity和podAntiAffinity,但是node 却只有nodeAffinity,这是因为operator , operator 是匹配表达式的操作符,nodeAffinity支持In, NotIn, Exists, DoesNotExist, Gt和Lt,所以想支持"nodeAntiAffinity"只要operator使用NotIn或者DoesNotExist就可以实现了。

podAffinity&&podAntiAffinity:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: affinity-test
  labels:
    app: affinity-test
spec:
  replicas: 2
  selector:
    matchLabels:
      app: affinity-test
  template:
    metadata:
      labels:
        app: affinity-test
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
          name: nginxhttp
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:  # 硬策略
            labelSelector:
            - matchExpressions:
              - key: name
                operator: In
                values:
                - podaffinity-nginx
            topologyKey: failure-domain.beta.kubernetes.io/zone
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100 // 1-100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: security
                  operator: In
                  values:
                  - securityA
              topologyKey: kubernetes.io/securityA

podAffinity的operator支持In, NotIn, Exists, DoseNotExit. 相对nodeAffinity,podAffinity多了一个topologyKey,topologyKey可以理解为拓扑域,在yaml里的意思是调度需要对应的node有对应的标签,而不关心这个label对应的值,假设反topologykey是idc的维度,公司有北京上海2个idc,pod的副本数量为2,那么pod在完成了topologykey-idc=beijing之后,根据podAntiAffinity的策略,则不会在同样个zone的topologykey在创建了,而会创建在shanghai,从而做到了IDC的均衡部署。

污点 && 容忍

亲和性和反亲和性的作用是为了让pod可以根据需要调度到自己像分配的一个或者一组node上,污点的作用其实就是反过来,就是给node打上一个特殊的标签,让该node不再被分配pod,除非该pod容忍了该污点。假设有服务器硬件发生了预告警,或者服务器维保到期需要预下线,那么从服务器等待维护/预下线到真正服务器不在提供服务的周期里,该node不会被调度。

taints
kubectl taint nodes node-name key=value:effect
# key 和 value 为污点标签, value 可以为空,effect 描述污点的作用
effect 支持以下3种:
  • NoSchedule //不会将 Pod 调度到有污点的 Node
  • PreferNoSchedule//避免将 Pod 调度到有污点的 Node
  • NoExecute //不会将 Pod 调度到有污点的 Node, 将已经存在的 Pod 驱逐出去
    eg:
#给nodeA打污点标签
kubectl taint nodes nodeA taintA=node:NoSchedule
#查看
kubectl describe node nodeA |grep Taints
#取消污点
kubectl taint nodes nodeA taintA-
tolerations

eg:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: taint
  labels:
    app: taint
spec:
  replicas: 2
  selector:
    matchLabels:
      app: taint
  template:
    metadata:
      labels:
        app: taint
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - name: http
          containerPort: 80
      tolerations:
      - key: "node-role.kubernetes.io/maintenance"
        operator: "Exists"
        effect: "NoSchedule"

假设NodeA存在"node-role.kubernetes.io/maintenance"的标签,该pod可以容忍NoSchedule的污点。容忍存在以下默认场景:

  • 如果不指定 operator 属性,则operator默认值为 Equal
  • 空的 key 如果再配合 Exists 就能匹配所有的 key 与 value,也就是能容忍所有节点的所有 Taints
  • 空的 effect 匹配所有的 effect
  • 如果需要容忍多个污点,就写多个-key:–effect的过滤策略即可。
个人公众号, 分享一些日常开发,运维工作中的日常以及一些学习感悟,欢迎大家互相学习,交流

在这里插入图片描述

Logo

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

更多推荐