为什么 Kubernetes 自动扩缩容器会互相打架(以及为什么解决方案必须是自主的)
Kubernetes 里管“该开几个副本”和“每个副本该给多少 CPU/内存”的其实是好几套独立工具:HPA 按 CPU 百分比增减副本,VPA 按历史用量调整资源申请,KEDA 按 Kafka 队列积压决定副本数,Karpenter 按声明资源申请新机器。问题是它们各自跑各自的循环,看到的都是局部信息,还同时改同一批配置字段。比如 VPA 把 CPU 申请调小,HPA 的分母就跟着变小,同样的流量会被算成利用率超高,于是猛加副本,结果副本越来越多、每个越来越小,互相把对方越推越远;KEDA 加副本、HPA 又按低 CPU 减回来;GitOps 看到副本数和 Git 不一致还会把它改回去。作者认为水平和垂直扩缩本来就是一道联立方程,应该由一个统一控制面同时看 CPU、队列、延迟、节点价格和 Git 配置,一起给出副本数和资源申请。文中也提到生产集群 CPU 平均利用率只有约 8%,但这些方案的落地细节和可用性文中没有说明。
文中可用工具
- HPA根据 CPU 等运行时指标增减 Pod 副本数
- VPA根据历史用量调整容器的 CPU/内存申请
- KEDA根据 Kafka 等外部事件源的队列积压决定副本数
- Karpenter为 Pending 的 Pod 按声明资源申请节点
- Cluster Autoscaler在有 Pod 无法调度时扩缩节点池
- Argo CD按 Git 仓库内容同步集群状态并检测漂移
- FluxGitOps 工具,按版本控制强制集群基线状态
- Helm用 values 声明副本数和资源规格