K8S学习之污点容忍

污点:使节点能够排斥一类特定的 pod。Taint 和 toleration 相互配合,可以用来避免pod 被分配到不合适的节点上。

节点亲和性:是pod的一种属性(偏好或硬性要求),它使pod被吸引到一类特定的节点。

taints:污点,定义在节点上,是键值数据

tolerations:容忍度,定义在pod上,可以定义能容忍哪些污点

污点的查看

[root@master ~]# kubectl describe nodes master | grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule
					....
[root@master ~]# kubectl explain node.spec.taints
NoSchedule 				不会被调度 
PreferNoSchedule		尽量不调度
NoExecute 				驱逐节点

污点的添加与删除

[root@master ~]# kubectl taint nodes node1 key=value:NoSchedule
[root@master ~]# kubectl taint nodes node1 key:NoSchedule-

key=value:NoSchedule key:NoSchedule-
它的 key 键是 key,value 值是 value,effect行为是 NoSchedule。这表示只有拥有和这个 taint 相匹配的 toleration 的 pod 才能够被分配到 node1 这个节点。当然你也可以给一个节点添加多个 taint ,也可以给一个 pod 添加多个 toleration。

容忍度(pod.spec.tolerations)

effect、key、operator、tolerationSeconds、value

一个 toleration和一个 taint 相“匹配”是指它们有一样的key和effect ,operator 默认是 Equal ,即value 相等才匹配。如果operator是Exists,则toleration 不能指定 value。

tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoSchedule"

tolerations:
- key: "key"
  operator: "Exists"
  effect: "NoSchedule"

如果一个 toleration 的 effect 为空,则 key 值与之相同就能完成匹配 ,taint的effect可以是任意值。

tolerations:
- key: "key"
  operator: "Exists"

如果这个pod的所在节点打了该污点,配置了tolerationSeconds那么pod 还将继续在节点上运行 一段时间,如下3600 秒

tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoExecute"
  tolerationSeconds: 3600

使用场景

专用节点:如果你想将某些节点专门分配给特定的一组用户使用,你可以给这些节点添加一个 taint。如果要使pod 只能被分配到专用节点,那么你可以给节点打个标签,将 pod 的节点亲和性与容忍结合使用。

配备了特殊硬件的节点:在部分节点配备了特殊硬件(比如 GPU)的集群中,我们希望不需要这类硬件的 pod 不要被分配到这些特殊节点,以便为后继需要这类硬件的 pod 保留资源。

节点问题:当某种条件为真时,node controller会自动给节点添加一个 taint当前内置的 taint 包括:

node.kubernetes.io/not-ready:节点未准备好。这相当于节点状态 Ready 的值为 “False”。
node.kubernetes.io/unreachable:node controller 访问不到节点
node.kubernetes.io/out-of-disk:节点磁盘耗尽。
node.kubernetes.io/memory-pressure:节点存在内存压力。
node.kubernetes.io/disk-pressure:节点存在磁盘压力。
node.kubernetes.io/network-unavailable:节点网络不可用。
node.kubernetes.io/unschedulable: 节点不可调度。

比如,一个使用了很多本地状态的应用程序在网络断开时,仍然希望停留在当前节点上运行一段较长的时间,愿意等待网络恢复以避免被驱逐。在这种情况下,pod 的 toleration 可能是下面这样的:

tolerations:
- key: "node.kubernetes.io/unreachable"
  operator: "Exists"
  effect: "NoExecute"
  tolerationSeconds: 6000

注意,Kubernetes 会自动给 pod 添加 key 为 node.kubernetes.io/not-ready 的 toleration 并配置 tolerationSeconds=300,和key为node.kubernetes.io/unreachable 的 toleration 并配置 tolerationSeconds=300,除非用户提供的 pod 配置中已经已存在了这两个key。这种自动添加 toleration 机制保证了在其中一种问题被检测到时 pod 默认能够继续停留在当前节点运行 5 分钟。

自 Kubernetes 1.8 起, DaemonSet 控制器自动为所有守护进程添加如下 NoSchedule toleration 以防 DaemonSet 崩溃

node.kubernetes.io/memory-pressure
node.kubernetes.io/disk-pressure
node.kubernetes.io/out-of-disk (只适合 critical pod)
node.kubernetes.io/unschedulable (1.10 或更高版本)
node.kubernetes.io/network-unavailable (只适合 host network)

这里查看了一下之前创建的daemonset,fluentd的容忍

[root@master ~]# kubectl describe pod -n kube-system fluentd-elasticsearch-
Tolerations:     :NoSchedule op=Exists
                 :NoExecute op=Exists
                 CriticalAddonsOnly op=Exists
                 node.kubernetes.io/disk-pressure:NoSchedule op=Exists
                 node.kubernetes.io/memory-pressure:NoSchedule op=Exists
                 node.kubernetes.io/network-unavailable:NoSchedule op=Exists
                 node.kubernetes.io/not-ready:NoExecute op=Exists
                 node.kubernetes.io/pid-pressure:NoSchedule op=Exists
                 node.kubernetes.io/unreachable:NoExecute op=Exists
                 node.kubernetes.io/unschedulable:NoSchedule op=Exists

污点容忍的举例

给node1打污点,创建pod,此时 Events:告诉我们两个节点,0个可用。两个节点都有taints。pod的创建时一致处于Pending ,是失败的

[root@master ~]# kubectl taint nodes node1 name=lucky:NoSchedule
node/node1 tainted
[root@master ~]# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-nginx
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
[root@master ~]# kubectl apply -f pod.yaml
pod/pod-nginx created
[root@master ~]# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
pod-nginx   0/1     Pending   0          5s
[root@master ~]# kubectl describe pod pod-nginx
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  16s   default-scheduler  0/2 nodes are available: 1 node(s) had taint {name: lucky}, that the pod didn't tolerate, 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate.

我们删除污点后pod在node1上创建成功

[root@master ~]# kubectl taint nodes node1 name:NoSchedule-
node/node1 untainted
[root@master ~]# kubectl get pod -owide
NAME        READY   STATUS    RESTARTS   AGE   IP            NODE    NOMINATED 
pod-nginx   1/1     Running   0          12s   10.244.1.87   node1       

我们重新添加污点,发现已存在的pod不受影响

[root@master ~]# kubectl taint nodes node1 name=lucky:NoSchedule
node/node1 tainted
[root@master ~]# kubectl get pod -owide
NAME        READY   STATUS    RESTARTS   AGE     IP            NODE    
pod-nginx   1/1     Running   0          3m25s   10.244.1.87   node1      

删除pod,创建一个带有容忍的pod

[root@master ~]# kubectl delete -f pod.yaml
[root@master ~]# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-nginx
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  tolerations:
  - key: name
    value: lucky
    effect: NoSchedule
[root@master ~]# kubectl apply -f pod-pvc.yaml
可以看到pod已经创建成功
[root@master ~]# kubectl get pod -owide
NAME        READY   STATUS    RESTARTS   AGE     IP            NODE    pod-nginx   1/1     Running   0          6m33s   10.244.1.87   node1      
[root@master ~]# kubectl describe nodes node1 | grep Taints
Taints:             name=lucky:NoSchedule
[root@master ~]# kubectl taint nodes node1 name:NoSchedule-
node/node1 untainted

对于tolerations属性的写法:

其中的key、value、effect 与Node的Taint设置需保持一致

​ 1、如果operator的值是Exists,则value属性可省略。

​ 2、如果operator的值是Equal,则表示其key与value之间的关系是equal(等于)。

​ 3、如果不指定operator属性,则默认值为Equal。

另外,还有两个特殊值:

​ 1、空的key 如果再配合Exists ,就能匹配所有的key与value ,也就是能容忍所有node上的所有Taints。

​ 2、空的effect,匹配所有的effect

你可能感兴趣的:(k8s学习,kubernetes,docker,容器)