在Kubernetes集群管理中,有时我们需要将某些节点(例如硬件配置特殊、运行关键控制平面组件或计费模式昂贵的节点)隔离出来,只允许特定的、经过授权的关键应用部署在其上。防止普通应用随意占用这些“系统核心节点”的最佳实践是使用污点(Taints)和容忍度(Tolerations)。
本文将通过一个实操示例,演示如何给特定的节点打上污点,并配置关键应用的容忍度,实现节点的有效隔离。
1. 概念速览:污点与容忍度
- 污点 (Taint): 应用于节点,表达该节点不希望被Pod调度。污点通常包含 Key、Value 和 Effect 三部分。
- 容忍度 (Toleration): 应用于Pod,表达该Pod能够“容忍”节点上的某些污点,从而可以被调度到带有相应污点的节点上。
常见的 Effect 类型有:
1. NoSchedule: Pod不会被调度到该节点,除非它容忍该污点。(最常用于隔离)
2. PreferNoSchedule: 尽量不调度,但系统资源紧张时仍有可能调度。
3. NoExecute: Pod不仅不会被调度到该节点,如果节点已经运行了Pod,不容忍该污点的Pod会被驱逐。
2. 实操步骤:隔离系统核心节点
假设我们有一个名为 system-core-node-01 的关键节点,我们希望只有标注为“关键系统组件”的Pod才能访问它。
步骤 2.1:为核心节点添加污点
我们使用 kubectl taint 命令,给节点打上一个 Key 为 critical-system,Value 为 reserved,Effect 为 NoSchedule 的污点。
# 假设你的核心节点名称为 system-core-node-01
kubectl taint nodes system-core-node-01 critical-system=reserved:NoSchedule
# 验证污点是否添加成功
kubectl describe node system-core-node-01 | grep Taints
# 输出应类似:Taints: critical-system=reserved:NoSchedule
现在,任何没有配置容忍度的Pod都无法被调度到 system-core-node-01 上。
步骤 2.2:验证普通应用的调度失败
创建一个普通的 Nginx Pod,它没有配置任何容忍度。
****standard-pod.yaml****:
apiVersion: v1
kind: Pod
metadata:
name: standard-nginx-app
spec:
containers:
- name: nginx
image: nginx:latest
部署后,查看其状态:
kubectl apply -f standard-pod.yaml
kubectl describe pod standard-nginx-app | grep -i Events -A 5
你会看到类似以下的事件信息,表明调度器因污点而无法找到合适的节点:
Warning FailedScheduling default-scheduler 0/X nodes are available: 1 node(s) had untolerated taint {critical-system: reserved}.
步骤 2.3:配置关键应用的容忍度
现在我们创建一个关键的监控组件 Pod,它需要部署在核心节点上。我们必须在其 Pod 定义中添加相应的 tolerations 字段。
****critical-pod.yaml****:
apiVersion: v1
kind: Pod
metadata:
name: critical-monitoring-agent
spec:
# 关键:添加容忍度配置
tolerations:
- key: "critical-system"
operator: "Equal"
value: "reserved"
effect: "NoSchedule"
# 可选:如果希望Pod只在核心节点上运行,可以配合 nodeSelector 或 nodeAffinity 使用
nodeSelector:
kubernetes.io/hostname: system-core-node-01
containers:
- name: agent
image: busybox
command: ["sleep", "3600"]
部署关键应用:
kubectl apply -f critical-pod.yaml
# 验证调度结果
kubectl get pod critical-monitoring-agent -o wide
由于该 Pod 容忍了 critical-system=reserved:NoSchedule 这个污点,它将能够成功地被调度到 system-core-node-01 上,而普通应用则会被排除在外。
3. 清理与解除隔离
当不再需要节点隔离时,可以使用 kubectl taint 命令配合减号 – 来移除污点:
kubectl taint nodes system-core-node-01 critical-system=reserved:NoSchedule-
# 验证污点已被移除
kubectl describe node system-core-node-01 | grep Taints
# 输出应为:Taints: <none>
汤不热吧