apiVersion: v1
kind: Node
metadata:
name: my-node
#...
spec:
taints:
- effect: NoExecute
key: key1
value: value1
#...
污点和容忍度允许节点控制哪些 Pod 应该(或不应该)在其上调度。
污点允许节点拒绝调度 Pod,除非该 Pod 具有匹配的容忍度。
您可以通过Node
规范 (NodeSpec
) 将污点应用于节点,并通过Pod
规范 (PodSpec
) 将容忍度应用于 Pod。当您将污点应用于节点时,除非 Pod 可以容忍该污点,否则调度程序无法将 Pod 放置到该节点上。
apiVersion: v1
kind: Node
metadata:
name: my-node
#...
spec:
taints:
- effect: NoExecute
key: key1
value: value1
#...
Pod
规范中的容忍度示例apiVersion: v1
kind: Pod
metadata:
name: my-pod
#...
spec:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
tolerationSeconds: 3600
#...
污点和容忍度由键、值和效果组成。
参数 | 描述 | ||||||
---|---|---|---|---|---|---|---|
|
|
||||||
|
|
||||||
|
效果是以下之一
|
||||||
|
|
如果您向控制平面节点添加NoSchedule
污点,则该节点必须具有node-role.kubernetes.io/master=:NoSchedule
污点,该污点默认添加。
例如
apiVersion: v1
kind: Node
metadata:
annotations:
machine.openshift.io/machine: openshift-machine-api/ci-ln-62s7gtb-f76d1-v8jxv-master-0
machineconfiguration.openshift.io/currentConfig: rendered-master-cdc1ab7da414629332cc4c3926e6e59c
name: my-node
#...
spec:
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
#...
容忍度与污点匹配
如果operator
参数设置为Equal
key
参数相同;
value
参数相同;
effect
参数相同。
如果operator
参数设置为Exists
key
参数相同;
effect
参数相同。
以下污点内置于 OpenShift Container Platform 中
node.kubernetes.io/not-ready
:节点未就绪。这对应于节点状态Ready=False
。
node.kubernetes.io/unreachable
:节点控制器无法访问该节点。这对应于节点状态Ready=Unknown
。
node.kubernetes.io/memory-pressure
:节点存在内存压力问题。这对应于节点状态MemoryPressure=True
。
node.kubernetes.io/disk-pressure
:节点存在磁盘压力问题。这对应于节点状态DiskPressure=True
。
node.kubernetes.io/network-unavailable
:节点网络不可用。
node.kubernetes.io/unschedulable
:节点不可调度。
node.cloudprovider.kubernetes.io/uninitialized
:当节点控制器使用外部云提供程序启动时,此污点将设置在节点上以将其标记为不可用。云控制器管理器中的控制器初始化此节点后,kubelet 将移除此污点。
node.kubernetes.io/pid-pressure
:节点存在 PID 压力。这对应于节点状态PIDPressure=True
。
OpenShift Container Platform 没有设置默认的 pid.available |
您可以通过在Pod
规范或MachineSet
对象中指定tolerationSeconds
参数来指定 Pod 在被驱逐之前可以在节点上保持绑定状态的时间长度。如果向节点添加了具有NoExecute
效果的污点,则具有tolerationSeconds
参数的、不耐受该污点的 Pod 只有在该时间段到期后才会被驱逐。
apiVersion: v1
kind: Pod
metadata:
name: my-pod
#...
spec:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
tolerationSeconds: 3600
#...
在此示例中,如果此 Pod 正在运行但没有匹配的容忍度,则 Pod 将保持与节点绑定 3600 秒,然后被驱逐。如果在此之前移除了污点,则 Pod 不会被驱逐。
您可以在同一节点上设置多个污点,在同一 Pod 上设置多个容忍度。OpenShift Container Platform 按如下方式处理多个污点和容忍度:
处理 Pod 具有匹配容忍度的污点。
剩余的不匹配污点对 Pod 产生指示的效果。
如果至少存在一个具有NoSchedule
效果的不匹配污点,则 OpenShift Container Platform 无法将 Pod 调度到该节点。
如果没有具有NoSchedule
效果的不匹配污点,但至少存在一个具有PreferNoSchedule
效果的不匹配污点,则 OpenShift Container Platform 会尝试不将 Pod 调度到该节点。
如果至少存在一个具有NoExecute
效果的不匹配污点,则 OpenShift Container Platform 会将 Pod 从节点驱逐(如果它已经在节点上运行),或者 Pod 不会被调度到节点上(如果它尚未在节点上运行)。
不耐受污点的 Pod 会立即被驱逐。
耐受污点且未在其Pod
规范中指定tolerationSeconds
的 Pod 将永远保持绑定状态。
耐受污点并指定了tolerationSeconds
的 Pod 将保持绑定指定的时间量。
例如
向节点添加以下污点
$ oc adm taint nodes node1 key1=value1:NoSchedule
$ oc adm taint nodes node1 key1=value1:NoExecute
$ oc adm taint nodes node1 key2=value2:NoSchedule
Pod 具有以下容忍度
apiVersion: v1
kind: Pod
metadata:
name: my-pod
#...
spec:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
#...
在这种情况下,由于没有容忍度与第三个污点匹配,因此无法将 Pod 调度到节点。如果在添加污点时 Pod 已经在节点上运行,则 Pod 会继续运行,因为第三个污点是三个污点中唯一一个不被 Pod 容忍的污点。
按状态污点节点功能(默认启用)会自动对报告内存压力和磁盘压力等状态的节点添加污点。如果节点报告某个状态,则会添加污点,直到该状态清除。这些污点具有NoSchedule
效果,这意味着除非 Pod 具有匹配的容忍度,否则任何 Pod 都无法调度到该节点。
调度程序在调度 Pod 之前会检查节点上的这些污点。如果存在污点,则 Pod 将调度到其他节点。由于调度程序检查的是污点而不是实际的节点状态,因此您可以通过添加相应的 Pod 容忍度来配置调度程序忽略其中一些节点状态。
为了确保向后兼容性,守护程序集控制器会自动向所有守护程序添加以下容忍度:
node.kubernetes.io/memory-pressure
node.kubernetes.io/disk-pressure
node.kubernetes.io/unschedulable(1.10 或更高版本)
node.kubernetes.io/network-unavailable(仅限主机网络)
您还可以向守护程序集添加任意容忍度。
控制平面还会在具有 QoS 类别的 Pod 上添加 |
基于污点的驱逐功能(默认启用)会将 Pod 从遇到特定状态(例如not-ready
和unreachable
)的节点驱逐。当节点遇到这些状态之一时,OpenShift Container Platform 会自动向节点添加污点,并开始将 Pod 驱逐并重新调度到其他节点。
基于污点的驱逐具有NoExecute
效果,任何不耐受污点的 Pod 都会立即被驱逐,任何耐受污点的 Pod 永远不会被驱逐,除非 Pod 使用tolerationSeconds
参数。
tolerationSeconds
参数允许您指定 Pod 保持绑定到具有节点状态的节点的时间长度。如果在tolerationSeconds
时间段后状态仍然存在,则污点将保留在节点上,并且具有匹配容忍度的 Pod 将被驱逐。如果在tolerationSeconds
时间段之前状态清除,则具有匹配容忍度的 Pod 不会被移除。
如果您使用tolerationSeconds
参数且没有值,则由于节点未就绪和不可访问的状态,Pod 永远不会被驱逐。
OpenShift Container Platform 以限速的方式驱逐 Pod,以防止在诸如主节点与节点分区等场景中发生大规模 Pod 驱逐。 默认情况下,如果给定区域中超过 55% 的节点不健康,节点生命周期控制器会将该区域的状态更改为 更多信息,请参见 Kubernetes 文档中的驱逐限速。 |
OpenShift Container Platform 自动添加对node.kubernetes.io/not-ready
和 node.kubernetes.io/unreachable
的容忍,tolerationSeconds=300
,除非Pod
配置指定了任一容忍。
apiVersion: v1
kind: Pod
metadata:
name: my-pod
#...
spec:
tolerations:
- key: node.kubernetes.io/not-ready
operator: Exists
effect: NoExecute
tolerationSeconds: 300 (1)
- key: node.kubernetes.io/unreachable
operator: Exists
effect: NoExecute
tolerationSeconds: 300
#...
1 | 这些容忍确保默认的 Pod 行为是在检测到这些节点条件问题后保持绑定五分钟。 |
您可以根据需要配置这些容忍。例如,如果您有一个具有大量本地状态的应用程序,您可能希望在网络分区的情况下将 Pod 绑定到节点更长时间,从而允许分区恢复并避免 Pod 驱逐。
由 DaemonSet 生成的 Pod 会为以下污点创建NoExecute
容忍,且没有tolerationSeconds
node.kubernetes.io/unreachable
node.kubernetes.io/not-ready
因此,DaemonSet Pod 永远不会因为这些节点条件而被驱逐。
您可以向 Pod 添加容忍,向节点添加污点,以允许节点控制哪些 Pod 应该或不应该在其上调度。对于现有 Pod 和节点,您应该首先将容忍添加到 Pod,然后将污点添加到节点,以避免在您可以添加容忍之前 Pod 从节点中移除。
通过编辑Pod
规范以包含tolerations
部分来向 Pod 添加容忍。
apiVersion: v1
kind: Pod
metadata:
name: my-pod
#...
spec:
tolerations:
- key: "key1" (1)
value: "value1"
operator: "Equal"
effect: "NoExecute"
tolerationSeconds: 3600 (2)
#...
1 | 容忍参数,如污点和容忍组件表中所述。 |
2 | tolerationSeconds 参数指定 Pod 在被驱逐之前可以绑定到节点的时间长度。 |
例如
apiVersion: v1
kind: Pod
metadata:
name: my-pod
#...
spec:
tolerations:
- key: "key1"
operator: "Exists" (1)
effect: "NoExecute"
tolerationSeconds: 3600
#...
1 | Exists 运算符不接受value 。 |
此示例在node1
上放置一个污点,该污点具有键key1
、值value1
和污点效果NoExecute
。
使用以下命令并使用污点和容忍组件表中描述的参数向节点添加污点
$ oc adm taint nodes <node_name> <key>=<value>:<effect>
例如
$ oc adm taint nodes node1 key1=value1:NoExecute
此命令在node1
上放置一个污点,该污点具有键key1
、值value1
和效果NoExecute
。
如果您向控制平面节点添加 例如
|
Pod 上的容忍与节点上的污点匹配。具有任一容忍的 Pod 都可以调度到node1
上。
您可以使用计算主机组向节点添加污点。与MachineSet
对象关联的所有节点都将使用污点更新。容忍以与直接添加到节点的污点相同的方式响应由计算主机组添加的污点。
通过编辑Pod
规范以包含tolerations
部分来向 Pod 添加容忍。
Equal
运算符的 Pod 配置文件示例apiVersion: v1
kind: Pod
metadata:
name: my-pod
#...
spec:
tolerations:
- key: "key1" (1)
value: "value1"
operator: "Equal"
effect: "NoExecute"
tolerationSeconds: 3600 (2)
#...
1 | 容忍参数,如污点和容忍组件表中所述。 |
2 | tolerationSeconds 参数指定 Pod 在被驱逐之前绑定到节点的时间长度。 |
例如
Exists
运算符的 Pod 配置文件示例apiVersion: v1
kind: Pod
metadata:
name: my-pod
#...
spec:
tolerations:
- key: "key1"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 3600
#...
将污点添加到MachineSet
对象
编辑您要污点的节点的MachineSet
YAML,或者您可以创建一个新的MachineSet
对象。
$ oc edit machineset <machineset>
将污点添加到spec.template.spec
部分。
apiVersion: machine.openshift.io/v1beta1
kind: MachineSet
metadata:
name: my-machineset
#...
spec:
#...
template:
#...
spec:
taints:
- effect: NoExecute
key: key1
value: value1
#...
此示例放置一个污点,该污点在节点上具有键key1
、值value1
和污点效果NoExecute
。
将计算主机组缩减到 0。
$ oc scale --replicas=0 machineset <machineset> -n openshift-machine-api
或者,您可以应用以下 YAML 来缩放计算主机组。
|
等待机器被移除。
根据需要扩展计算主机组。
$ oc scale --replicas=2 machineset <machineset> -n openshift-machine-api
或者
$ oc edit machineset <machineset> -n openshift-machine-api
等待机器启动。污点将添加到与MachineSet
对象关联的节点。
如果您想将一组节点专供特定用户组使用,请向其 Pod 添加容忍。然后,向这些节点添加相应的污点。具有容忍的 Pod 允许使用被污点的节点或集群中的任何其他节点。
如果您想确保 Pod 只调度到那些被污点的节点,还可以向同一组节点添加标签,并向 Pod 添加节点亲和性,以便 Pod 只能调度到具有该标签的节点上。
要配置节点以便用户只能使用该节点
向这些节点添加相应的污点
例如
$ oc adm taint nodes node1 dedicated=groupName:NoSchedule
或者,您可以应用以下 YAML 来添加污点
|
通过编写自定义准入控制器向 Pod 添加容忍。
您可以创建一个使用节点选择器和容忍(设置为注释)的项目,以控制 Pod 到特定节点的放置。然后,在项目中创建的任何后续资源都将调度到具有与容忍匹配的污点的节点上。
已使用计算主机组或直接编辑节点向一个或多个节点添加了节点选择标签。
已使用计算主机组或直接编辑节点向一个或多个节点添加了污点。
创建Project
资源定义,在metadata.annotations
部分指定节点选择器和容忍。
project.yaml
文件示例kind: Project
apiVersion: project.openshift.io/v1
metadata:
name: <project_name> (1)
annotations:
openshift.io/node-selector: '<label>' (2)
scheduler.alpha.kubernetes.io/defaultTolerations: >-
[{"operator": "Exists", "effect": "NoSchedule", "key":
"<key_name>"} (3)
]
1 | 项目名称。 |
2 | 默认节点选择器标签。 |
3 | 容忍参数,如污点和容忍组件表中所述。此示例使用NoSchedule 效果,允许节点上现有的 Pod 保持不变,并使用Exists 运算符,该运算符不接受值。 |
使用oc apply
命令创建项目。
$ oc apply -f project.yaml
现在,在<project_name>
命名空间中创建的任何后续资源都应该调度到指定的节点上。
在一个集群中,如果只有一小部分节点拥有专用硬件,您可以使用污点和容忍来阻止不需要专用硬件的 Pod 使用这些节点,从而将这些节点留给需要专用硬件的 Pod。您还可以要求需要专用硬件的 Pod 使用特定的节点。
您可以通过向需要特殊硬件的 Pod 添加容忍,并对拥有专用硬件的节点添加污点来实现此目的。
确保拥有专用硬件的节点保留给特定的 Pod
向需要特殊硬件的 Pod 添加容忍。
例如
apiVersion: v1
kind: Pod
metadata:
name: my-pod
#...
spec:
tolerations:
- key: "disktype"
value: "ssd"
operator: "Equal"
effect: "NoSchedule"
tolerationSeconds: 3600
#...
使用以下命令之一对拥有专用硬件的节点添加污点
$ oc adm taint nodes <node-name> disktype=ssd:NoSchedule
或者
$ oc adm taint nodes <node-name> disktype=ssd:PreferNoSchedule
或者,您可以应用以下 YAML 来添加污点
|
您可以根据需要从节点中移除污点,从 Pod 中移除容忍。您应该先向 Pod 添加容忍,然后再向节点添加污点,以避免在您添加容忍之前 Pod 从节点中被移除。
移除污点和容忍
从节点移除污点
$ oc adm taint nodes <node-name> <key>-
例如
$ oc adm taint nodes ip-10-0-132-248.ec2.internal key1-
node/ip-10-0-132-248.ec2.internal untainted
要从 Pod 中移除容忍,请编辑Pod
规范以移除容忍
apiVersion: v1
kind: Pod
metadata:
name: my-pod
#...
spec:
tolerations:
- key: "key2"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 3600
#...