k8s中的亲和性、污点与容忍(调度到不同的宿主机)

本文章并未经过严格实践,如有错误,辛苦指出。

背景

服务需要多副本,来保证高可靠、多活。
那么问题来了,假如这些副本都在同一个宿主机上,或者同一个交换机下…宿主机、交换机其中一项坏掉了,那多副本还有什么意义?
怎么解决呢?需要用到k8s中的亲和性和反亲和性。将容器调度到不同的宿主机即可。

nodeSelector标签实践:Pod只能调度到某些node上

背景:如某些服务对磁盘读写要求很高,则需要调度到SSD或nvme硬盘的宿主机上。

示例:

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

解释:

  • 通过nodeSelector指定label标签,pod将会只调度到具有该标签的node之上。

affinity标签:软要求和硬要求

可以把亲和性分成软要求硬要求
硬要求的意思是:必须满足这些要求,否则就会调度失败。Pod无法启动。
软要求的意思是:应当优先满足这些要求,如果满足不了,不作强求,Pod可以正常启动。比如前面说的固态硬盘要求。

标签解释
podAffinityPod亲和性
podAntiAffinityPod反亲和性
nodeAffinityNode亲和性
requiredDuringSchedulingIgnoredDuringExecution硬要求
preferredDuringSchedulingIgnoredDuringExecution软要求

示例:

作用:Pod的3个副本不能再同一个宿主机上

apiVersion: apps/v1beta1 # for versions before 1.6.0 use extensions/v1beta1
kind: Deployment
metadata:
  name: redis-cache
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: store
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - store
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: redis-server
        image: redis:3.2-alpine

解释:

  • podAntiAffinity表示Pod反亲和性
  • requiredDuringSchedulingIgnoredDuringExecution是硬要求。
  • 标签选择器匹配了key:value为app:store的宿主机,同时该Pod存在一个标签就是app:store。所以,该Pod的3个副本不能在同一个宿主机上。

污点taint与容忍tolerations

前面提到的nodeAffinity是Node亲和性,表示希望调度都某些宿主机上。
相反,污点容忍可以让Pod不调度到某些有污点的宿主机上,但Pod可以容忍这些污点宿主。
官方文档:https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/

污点taint

给Node设置污点:

kubectl taint nodes node1 key1=value1:NoSchedule		#给宿主机node1设置了key1=value1的污点,策略是NoSchedule
关键词作用
NoSchedulePod不会被调度到此宿主机,除非该Pod容忍
PreferNoScheduleNoSchedule 的软策略版本,表示尽量不调度到污点节点上去
NoExecute一旦设置NoExecute,不容忍NoExecute的Pod将会被驱逐到其他宿主机上去

NoExecute和NoSchedule的区别:

  • NoSchedule只是不调度,但并不影响已经调度好的容器,即使给宿主机新增了污点,这些Pod依然会正常运行。同样PreferNoSchedule也是。
  • NoExecute就不一样了,会将Pod驱逐到其他宿主,除非该Pod容忍。

其他关于污点的操作:

#删除污点:
kubectl taint nodes node1 key1=value1:NoSchedule-		#在后面加一个减号表示删除
#查询污点:
kubectl describe nodes server1 |grep Taints

容忍tolerations

表示该Pod可以容忍某些污点宿主机。

示例:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  tolerations:
	- key: "key1"
  	operator: "Equal"
  	value: "value1"
  	effect: "NoSchedule"

解释:

  • 上述示例的意思是:可以调度到key1=value1的宿主机上。
  • operator可以设置为Equal、Exists。其中Equal需要设置value,Exists省略value(官网是这样的)。
  • operator可以省略,默认值是Equal。
  • key和value可以同时省略,表示匹配所有污点。这样就能调度到所有有污点的宿主了。
  • effect可以省略,表示匹配所有,包括NoSchedule、PreferNoSchedule等。
  • 如果effect容忍的是NoExecute,可以设置容忍时间tolerationSeconds: 3600。超过了容忍时间还是会被驱逐。




参考文档:
https://blog.csdn.net/BIGmustang/article/details/109391323
https://www.cnblogs.com/sxgaofeng/p/13188723.html
https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/
https://blog.csdn.net/zwqjoy/article/details/90669857



“京城郭少”

posted @ 2021-10-08 00:22  NetRookieX  阅读(66)  评论(0编辑  收藏  举报