运维实战

Kubernetes 调度与弹性:Requests、QoS、亲和性、HPA 与 PDB

从资源请求和 QoS 开始,掌握污点容忍、亲和性、拓扑分布、HPA 自动扩缩与 PDB 可用性保护。

TY
Tycho
技术博主
• 2026-09-19 • 18 分钟阅读 • 5 次浏览
Kubernetes 调度与弹性:Requests、QoS、亲和性、HPA 与 PDB

实验基线:Kubernetes v1.37.0、kubectl v1.37.0。先在测试环境执行,记录变更前状态与回滚点;生产集群不得直接照抄节点地址、网段、存储类或资源额度。

调度器看 requests,不看平均使用率

CPU request 是调度与 HPA 利用率分母,memory limit 触发超限时容器会被 OOMKill。先用监控观测峰值和工作集,再设置请求与限制;完全不设资源会让容量规划和故障隔离失效。

kubectl top nodes
kubectl top pods -A --containers
kubectl describe node <node>
kubectl get pod <pod> -n lab -o jsonpath='{.status.qosClass}'

把硬约束与软偏好分开

nodeSelector与 required affinity 是硬条件,条件不满足会 Pending;preferred affinity 是软偏好。污点阻止不匹配的 Pod,容忍度只允许调度,并不强制选择该节点。跨故障域均匀部署使用 topologySpreadConstraints。

HPA 与 PDB 的边界

kubectl autoscale deployment web -n lab --cpu-percent=60 --min=2 --max=10
kubectl get hpa -n lab -w
kubectl describe hpa web -n lab

CPU HPA 依赖 Metrics API 和容器 CPU request;指标缺失时不要盲目调阈值。PDB 只约束节点排空等自愿中断,不阻止节点宕机,也不替代多副本。若 Deployment 只有一个副本却设置 minAvailable: 1,节点维护会被阻塞。

调优闭环

  1. 记录延迟、吞吐、错误率与资源曲线。
  2. 设置保守 requests/limits,进行稳定负载测试。
  3. 再调整副本、HPA behavior、调度分布。
  4. 每次只改一类变量,验证扩容速度与缩容抖动。

用可观测数据设置 requests

至少采集一个完整业务周期,区分稳定负载、发布峰值和异常流量。CPU requests 可参考稳定期高分位并保留启动余量;内存 requests 关注 working set,limits 必须高于可信峰值。随后在压测中观察 throttling、OOM、节点可分配量和业务延迟。

kubectl top pod -n lab --containers
kubectl get pod -n lab -o custom-columns='NAME:.metadata.name,CPU-REQ:.spec.containers[*].resources.requests.cpu,MEM-REQ:.spec.containers[*].resources.requests.memory,CPU-LIM:.spec.containers[*].resources.limits.cpu,MEM-LIM:.spec.containers[*].resources.limits.memory'
kubectl describe node <node> | sed -n '/Allocated resources:/,$p'

调度约束实战

topologySpreadConstraints:
- maxSkew: 1
  topologyKey: topology.kubernetes.io/zone
  whenUnsatisfiable: DoNotSchedule
  labelSelector: {matchLabels: {app: web}}
affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        topologyKey: kubernetes.io/hostname
        labelSelector: {matchLabels: {app: web}}

zone 分布是硬约束,节点反亲和是软偏好:既保证故障域,又避免小集群因节点不足完全无法调度。上线前用 kubectl describe pod确认 Pending 原因。

HPA v2 示例与验证

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata: {name: web, namespace: lab}
spec:
  scaleTargetRef: {apiVersion: apps/v1, kind: Deployment, name: web}
  minReplicas: 2
  maxReplicas: 10
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
  metrics:
  - type: Resource
    resource:
      name: cpu
      target: {type: Utilization, averageUtilization: 60}

验证 Metrics API、CPU requests 和负载发生器后,观察 desiredReplicas、扩容时间与缩容稳定窗口。扩不动时检查最大副本、节点容量和调度约束;抖动时检查指标噪声和 behavior。

PDB 与节点维护

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata: {name: web, namespace: lab}
spec:
  minAvailable: 2
  selector: {matchLabels: {app: web}}

先确认副本为 3 且跨节点分布,再测试 kubectl drain。PDB 不限制 Deployment 自身滚动更新,也不保护非自愿宕机;容量不足时它可能让 drain 长时间阻塞。

扩缩容三层边界

  • HPA 调整 Pod 副本;需要可靠指标与 requests。
  • VPA 调整/建议 requests;可能通过重建 Pod 生效,不应与 HPA 同时争夺同一资源维度。
  • 节点自动扩缩容根据不可调度 Pod 和节点利用情况调整节点池;它不会修复错误的硬亲和或 PVC 拓扑。

负载验证步骤

  1. 确认 Metrics API:kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes。
  2. 记录初始副本、CPU 和延迟。
  3. 从集群内产生可控请求,不直接冲击生产入口。
  4. 观察 HPA current/desired、Deployment 副本和 Pending 事件。
  5. 停止负载,确认稳定窗口后逐步缩容。
kubectl get hpa web -n lab -w
kubectl get deployment web -n lab -w
kubectl get events -n lab --sort-by=.metadata.creationTimestamp

若 desired 增长但副本 Pending,问题在容量或调度;若指标 unknown,检查 Metrics API、容器 requests 和采集链;若副本增加但延迟不降,瓶颈可能在数据库或串行临界区。

可复现记录模板

每次实验记录:集群版本、容器运行时、CNI/CSI 版本、命名空间、使用的 YAML Git 提交、开始与结束时间。命令输出至少保留对象状态、事件、关键日志和回滚结果。文中的占位符必须替换成自己的值,生产执行前应由第二人复核。

故障处理原则

  1. 先缩小影响面,不删除现场。
  2. 按对象状态—事件—日志—依赖顺序收集证据。
  3. 提出可证伪假设,一次只改变一个变量。
  4. 验证恢复后清理临时权限、调试 Pod、端口转发和测试数据。

完成检查

  • 命令退出码为 0,目标对象状态与预期一致。
  • 保存执行前后 YAML、事件与关键日志,确认没有把测试命名空间以外的对象改动。
  • 故障演练完成后执行清理或回滚,再进行下一章。

官方资料

TY

Tycho

热爱分享技术知识,帮助开发者成长。

评论 (0)

评论功能当前已关闭
暂无评论,快来抢沙发吧!