Kubernetes 编排(02):Pod 调度与资源——requests/limits、QoS、亲和性、污点容忍、HPA
更新时间:2026-09-01。本文是
cloud/kubernetes/K8s 编排第 02 篇,接 K8s 核心概念。Pod 调度是 K8s 的核心能力。理解 requests/limits 如何影响调度,QoS 如何保证服务质量,污点容忍如何控制 Pod 放置,才能正确管理集群资源。
本文要回答的问题
- requests 和 limits 有什么区别?调度时看 requests 还是 limits?
- QoS 等级(Guaranteed/Burstable/BestEffort)怎么决定?驱逐时先驱逐谁?
- 节点亲和性和污点容忍是什么?怎么控制 Pod 放到哪个节点?
- HPA 水平自动扩缩容怎么配置?
一、requests 和 limits
yaml
# requests:调度承诺,调度器保证 Pod 至少能拿到这么多资源
# limits:使用上限,Pod 不能超过这个限制
resources:
requests:
cpu: "100m" # 请求 0.1 核 CPU
memory: "128Mi" # 请求 128 MiB 内存
limits:
cpu: "500m" # 最多用 0.5 核 CPU
memory: "256Mi" # 最多用 256 MiB 内存调度器工作方式:
- 调度时看 requests:节点可用资源总和 >= Pod requests 总和
- 运行时看 limits:CPU 限制(cgroup CFS 配额),内存限制(超过限制 OOM kill)
- 一个节点上(Pod requests 总和)不能超过节点容量
CPU 和内存的区别:
- CPU:可压缩资源,超过 limits 会限流(throttle),Pod 变慢,但不会 kill
- 内存:不可压缩资源,超过 limits 会 OOM kill
经验:
- 生产环境一定要设置 requests 和 limits
- limits 通常比 requests 大一些,允许突发
- 不要设置 limits 太大,否则节点资源浪费
二、QoS 等级
yaml
# QoS 等级由 requests 和 limits 决定
# 1. Guaranteed(最高优先级,驱逐时最后被驱逐)
# 条件:所有容器 requests == limits
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "100m"
memory: "128Mi"yaml
# 2. Burstable(中等优先级)
# 条件:至少一个容器 requests < limits
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"yaml
# 3. BestEffort(最低优先级,驱逐时最先被驱逐)
# 条件:不设置 requests 和 limits
resources: {}驱逐顺序(节点资源不足时):
- 先驱逐 BestEffort
- 再驱逐 Burstable(超过 requests 的 Pod)
- 最后驱逐 Guaranteed(不超过 requests 的 Pod 不会被驱逐)
经验: 核心服务设置 Guaranteed,非核心服务设置 Burstable,测试服务设置 BestEffort。
三、节点亲和性
yaml
# 节点亲和性:强制或偏好 Pod 跑到特定节点
# 硬亲和性(required):必须满足,调度器强制
# 软亲和性(preferred):尽量满足,不满足也行
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disk-type
operator: In
values:
- ssd
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: zone
operator: In
values:
- us-east-1节点标签:
bash
# 给节点打标签
kubectl label node node1 disk-type=ssd
kubectl label node node2 zone=us-east-1四、污点和容忍
yaml
# 污点(Taint):节点标记,阻止 Pod 调度过来
# 容忍(Toleration):Pod 允许被调度到有污点的节点
# 给节点加污点
kubectl taint nodes node1 disk-type=ssd:NoSchedule
# 容忍:Pod 容忍这个污点,可以调度过来
spec:
tolerations:
- key: "disk-type"
operator: "Equal"
value: "ssd"
effect: "NoSchedule"污点效果:
NoSchedule:不调度 Pod 过来,已运行的 Pod 不受影响PreferNoSchedule:尽量不调度,但不是强制NoExecute:不调度 + 已运行的 Pod 会被驱逐
经验: 污点用于控制特殊节点(GPU 节点、SSD 节点、专用节点),容忍用于让特定 Pod 使用这些节点。
五、HPA(水平自动扩缩容)
yaml
# HPA 根据 CPU/内存使用率自动伸缩 Pod 数量
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # CPU 使用率超过 70% 扩容
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80HPA 工作原理:
- 每隔 15 秒采集 Pod 的 CPU/内存使用率
- 计算目标副本数:
当前副本数 * (当前使用率 / 目标使用率) - 如果目标副本数 > 当前副本数,扩容
- 如果目标副本数 < 当前副本数,缩容
HPA 注意事项:
- Pod 必须设置 requests(HPA 使用的百分比是基于 requests 算的)
- 扩容时更新增量,缩容时冷却时间(默认 5 分钟)
- 适合响应 HTTP 流量的无状态应用
六、常见坑对照
| 坑 | 现象 | 对策 |
|---|---|---|
| 没设置 requests 和 limits | Pod 使用全部节点资源,其他 Pod 被饿死 | 所有 Pod 必须设置 requests 和 limits |
| CPU 设置太大 | 调度器认为节点资源不够,Pod 一直 Pending | 合理设置 requests,不要超过节点容量 |
| HPA 不生效 | Pod 资源使用率一直不触发 | 确认 Pod 设置了 requests |
| 污点导致 Pod 调度失败 | Pod 一直 Pending | 检查节点污点,添加正确容忍 |
相关与延伸
下一篇:Service 与 Ingress——ClusterIP/NodePort/LoadBalancer、Ingress 控制器、DNS;K8s 核心概念,见 K8s 核心概念。
一句话总结
K8s Pod 调度与资源:requests 是调度承诺(保证调度),limits 是使用上限(防止滥用);QoS 等级:Guaranteed(requests == limits,最优先)、Burstable、BestEffort(最优先被驱逐);节点亲和性控制 Pod 调度到特定节点,污点容忍阻止/允许 Pod 调度到特定节点;HPA 根据 CPU/内存使用率自动伸缩 Pod 数量,Pod 必须设置 requests 才能用 HPA;核心服务设置 Guaranteed,非核心服务设置 Burstable,测试服务设置 BestEffort。