调度、容量与资源治理 Hands-on
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
本文缩写(英文全称与中文含义)
| 缩写 | 英文全称/名称 | 中文含义 |
|---|---|---|
| AZ | Availability Zone | 可用区 |
| CPU | Central Processing Unit | 中央处理器 |
| GKE | Google Kubernetes Engine | Google 托管 Kubernetes 服务 |
| HPA | Horizontal Pod Autoscaler | Pod 水平自动扩缩容器 |
| KEDA | Kubernetes Event-driven Autoscaling | Kubernetes 事件驱动自动扩缩容 |
| OOM | Out Of Memory | 内存不足 |
| PDB | Pod Disruption Budget | Pod 中断预算,约束自愿驱逐 |
| SLA | Service Level Agreement | 服务等级协议 |
| SLO | Service Level Objective | 服务等级目标 |
| VPA | Vertical Pod Autoscaler | Pod 垂直自动扩缩容器 |
前置:业务基线、Metrics Server、跨节点/真实多 AZ 容量。数值为实验起点,生产取压测与历史指标结果。
1. 建立资源与故障预算#
kubectl top nodes
kubectl top pods -n orders --containers
kubectl describe nodes
kubectl -n orders get hpa,pdb,resourcequota,limitrange
kubectl get nodes -L topology.kubernetes.io/zone,pool调度主要看 requests/allocatable,不看瞬时空闲 CPU。limits 可能导致 CPU throttling/OOM;节点 MemoryPressure/磁盘压力还会驱逐 Pod。Guaranteed/Burstable/BestEffort 不等于业务 SLA,PDB 也不保护节点硬故障。
容量公式至少包含:最大业务副本+sidecar+DaemonSet+发布 surge+故障余量;Quota 不能恰好只覆盖当前副本。已有 团队配额按此修正。
2. 跨故障域放置#
保存 placement.yaml,要求业务节点有真实 zone 标签且至少三个可用故障域:
spec:
template:
spec:
nodeSelector: {pool: application}
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels: {app.kubernetes.io/name: orders-api}
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels: {app.kubernetes.io/name: orders-api}kubectl -n orders patch deployment orders-api --type=strategic --patch-file placement.yaml
kubectl -n orders rollout status deployment/orders-api --timeout=5m
kubectl -n orders get pods -l app.kubernetes.io/name=orders-api -o widezone 使用软约束允许故障降级,但不保证严格均匀;硬约束更严格,可能在故障后阻止调度。选择要写进 SLO 与容量评审。toleration 只是允许进入有 taint 的节点,不保证会选中它;专用池同时需要 selector/affinity。
3. 一次安全节点维护#
选只有可迁移业务的节点,先检查 emptyDir/本地卷与 singleton:
export NODE='REPLACE_APPLICATION_NODE'
kubectl get pods -A --field-selector "spec.nodeName=$NODE" -o wide
kubectl cordon "$NODE"
kubectl drain "$NODE" --ignore-daemonsets --timeout=15m若 emptyDir 阻塞,先确认数据可丢弃再单独决定是否用 --delete-emptydir-data;不默认加 --force 或 --disable-eviction。PDB 阻塞时查健康副本、拓扑、Quota、扩容上限;超时保持 cordon 并调查,不直接强驱。
kubectl -n orders get pods,pdb,hpa
kubectl uncordon "$NODE"持续业务流量下验证延迟、错误率、排队时间和副本分布;恢复节点后 Kubernetes 不会自动将已有 Pod 均匀搬回。
4. HPA 与 VPA#
HPA 实作见 Metrics Server/HPA,事件扩容见 KEDA;同一 workload 只允许一个 HPA 所有者。VPA 先用推荐模式。
自建环境尚无 VPA 时,固定官方 release 安装;GKE 使用托管 VPA,不重复安装:
export VPA_TAG='vertical-pod-autoscaler-REPLACE_VERSION'
git clone --depth 1 --branch "$VPA_TAG" https://github.com/kubernetes/autoscaler.git autoscaler-source
cd autoscaler-source/vertical-pod-autoscaler
# 先审阅 deploy 清单和安装脚本,确认镜像、资源、RBAC、证书及版本兼容。
./hack/vpa-up.sh
kubectl -n kube-system get deploy | rg vpa
cd ../..
kubectl get crd verticalpodautoscalers.autoscaling.k8s.io控制器健康后保存 vpa.yaml:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata: {name: orders-api, namespace: orders}
spec:
targetRef: {apiVersion: apps/v1, kind: Deployment, name: orders-api}
updatePolicy: {updateMode: 'Off'}
resourcePolicy:
containerPolicies:
- containerName: api
minAllowed: {cpu: 100m, memory: 128Mi}
maxAllowed: {cpu: '2', memory: 2Gi}
controlledResources: [cpu, memory]kubectl apply --dry-run=server -f vpa.yaml
kubectl apply -f vpa.yaml
kubectl -n orders describe vpa orders-api覆盖完整业务周期观察推荐,将结果与 p95、OOM/throttling 对照再调整 Git 中 requests。不要把依赖 requests 的 CPU HPA 与自动修改 CPU requests 的 VPA 无评估叠加。
平台可给关键服务创建自定义 PriorityClass,使用 preemptionPolicy: Never 先验证排队优先级;不借用 system-node-critical 给普通业务“插队”。退出实验恢复 Git 配置,不删除团队正式 Quota。