调度、容量与资源治理 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 wide

zone 使用软约束允许故障降级,但不保证严格均匀;硬约束更严格,可能在故障后阻止调度。选择要写进 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。

参考:资源管理、拓扑分散、VPA。

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭