Kubernetes容器编排中,Pod调度策略直接决定集群资源利用率和应用可用性。默认调度器基于资源请求和节点空闲情况分配Pod,但在实际DevOps实践中,往往需要更精细的调度控制。Pod亲和性、反亲和性和污点容忍机制提供了多维度的调度约束能力,本文从配置语法到实战场景逐一拆解。
Kubernetes调度机制基础与nodeSelector
Kubernetes调度器在创建Pod时,依次经过预选和优选两个阶段。预选阶段过滤不满足硬性条件的节点,优选阶段对剩余节点打分排序。nodeSelector是最基础的节点选择方式,通过键值对匹配节点标签。
apiVersion: v1
kind: Pod
metadata:
name: frontend-pod
spec:
nodeSelector:
disktype: ssd
zone: east
containers:
- name: nginx
image: nginx:1.25
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1000m"
memory: "1Gi"
nodeSelector逻辑简单但不灵活,只支持AND逻辑且无法表达偏好。生产环境中更多使用nodeAffinity和Pod亲和性实现复杂调度需求。
节点亲和性配置:硬约束与软偏好
nodeAffinity分为requiredDuringSchedulingIgnoredDuringExecution(硬约束)和preferredDuringSchedulingIgnoredDuringExecution(软偏好)。硬约束类似nodeSelector,不满足则Pod保持Pending状态;软偏好是评分偏好,调度器尽量满足但不保证。
apiVersion: v1
kind: Pod
metadata:
name: api-server
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- amd64
- key: node-role
operator: In
values:
- worker
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
preference:
matchExpressions:
- key: zone
operator: In
values:
- east
- weight: 20
preference:
matchExpressions:
- key: ssd
operator: In
values:
- "true"
containers:
- name: app
image: myapp:v2.1
operator支持In、NotIn、Exists、DoesNotExist、Gt、Lt六种匹配方式。weight取值1-100,调度器在优选阶段将各软偏好的权重得分累加,选择总分最高的节点。
Pod亲和性与反亲和性实战
Pod亲和性(podAffinity)让Pod倾向于调度到已有特定Pod的节点上,反亲和性(podAntiAffinity)则相反。这在CI/CD流水线部署中非常实用——同一应用的多副本分散到不同节点避免单点故障。
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-backend
spec:
replicas: 4
selector:
matchLabels:
app: web-backend
template:
metadata:
labels:
app: web-backend
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-backend
topologyKey: kubernetes.io/hostname
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- redis-cache
topologyKey: kubernetes.io/hostname
containers:
- name: web
image: webapp:v3.0
上述配置实现两个目标:4个web-backend副本强制分散到不同节点(反亲和性硬约束);同时尽量调度到运行redis-cache的节点上(亲和性软偏好),减少网络延迟。topologyKey定义拓扑域,kubernetes.io/hostname表示以节点为单位,topology.kubernetes.io/zone表示以可用区为单位。
Taints和Tolerations污点容忍机制
污点(Taint)标记在节点上,排斥未配置容忍的Pod。容忍(Toleration)配置在Pod上,允许调度到带污点的节点。这套机制常用于专用节点隔离,如GPU节点仅调度AI推理服务、监控节点仅调度Prometheus。
# 给节点打污点
kubectl taint nodes gpu-node-01 dedicated=gpu:NoSchedule
# Pod配置容忍
apiVersion: v1
kind: Pod
metadata:
name: ml-inference
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
- key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
containers:
- name: model-server
image: tensorflow/serving:latest
resources:
limits:
nvidia.com/gpu: 1
effect三种取值:NoSchedule(不调度新Pod,已有Pod不受影响)、PreferNoSchedule(尽量不调度,软约束)、NoExecute(驱逐已有不容忍Pod)。tolerationSeconds仅在NoExecute下生效,表示Pod在被驱逐前还能容忍多久,常用于故障应急响应场景,给应用一个优雅退出窗口。
监控告警体系与调度状态检查
调度策略上线后需要纳入监控告警体系。关键指标包括Pending Pod数量、调度延迟、节点资源分配率。通过kubectl命令快速排查调度问题:
# 查看Pod调度失败原因
kubectl get pod web-backend-0 -o wide
kubectl describe pod web-backend-0 | grep -A 10 Events
# 检查节点污点
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
# 查看节点标签
kubectl get nodes --show-labels
# 检查Pod分布情况
kubectl get pod -o wide -l app=web-backend
describe命令的Events段落是排查调度问题的第一线索。常见错误信息:FailedScheduling表示没有节点满足约束条件,0/6 nodes are available可能因为资源不足、污点排斥或亲和性冲突。在混沌工程实践中,可通过混沌测试验证调度策略在节点故障场景下的表现——手动cordon一个节点观察Pod是否按预期重新调度到其他节点。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-rong-qi-bian-pai-jin-jie-pod-qin-he-xing-diao-du/