深色模式
控制平面性能调优
摘要:本文面向需要把单集群规模推到数百至数千节点的 SRE / 平台工程师,讲解控制平面四大组件(kube-apiserver、etcd、kube-scheduler、kube-controller-manager)的性能瓶颈、可调参数、失败模式与回滚方案。覆盖版本:Kubernetes v1.28+。
适用版本与前提
- Kubernetes:v1.28+(文中
policy/v1、APF 行为以 v1.28 为准;部分默认值为社区常用口径,详见下文标注) - 工具:
kubectl、etcdctl(或etcdutl)、crictl - 前提:已具备控制平面节点 root / sudo 权限,且 etcd 已配置定期快照备份
背景与问题
控制平面是集群的"大脑",所有写操作(Pod 创建、扩缩容、状态更新)都经过它。当控制平面成为瓶颈时,典型症状是:kubelet 节点状态上报延迟、Pod 调度变慢、kubectl 命令 P99 延迟飙升、etcd leader 频繁切换。官方文档明确指出,etcd 对网络和磁盘 I/O 高度敏感,任何资源饥饿都会导致 heartbeat 超时、集群不稳定、无 leader 可选举,进而无法调度新 Pod(见参考资料 [1])。
版本相关
本文给出的 --max-requests-inflight=400、--max-mutating-requests-inflight=200 等"默认值"多为社区常用口径,且自 APF(API Priority and Fairness)默认开启后这些参数含义已变为"总并发上限之上限"。生产前请用 kube-apiserver -h | grep max-requests-inflight 核对你版本的真实默认值。
核心概念
控制平面请求链路上每个环节都可能成为瓶颈:
架构与原理
kube-apiserver
apiserver 本身无状态,瓶颈集中在:并发请求排队、watch-cache 命中率、序列化开销、与 etcd 的往返延迟。自 v1.18 起默认开启 APF(特性门 APIPriorityAndFairness),把请求按 FlowSchema/PriorityLevelConfiguration 分队列,避免单个租户把整集群写能力打满。
etcd
etcd 是 leader-based 强一致 KV 存储,是真正的写瓶颈。每次写需 leader 落盘并复制到多数派。官方要求生产至少 5 成员、运行在专用机器、使用 SSD(见参考资料 [2])。
生产实践:apiserver 调优
以下为大规模集群常见的静态 Pod 清单参数片段(kubeadm 部署路径 /etc/kubernetes/manifests/kube-apiserver.yaml):
yaml
apiVersion: v1
kind: Pod
metadata:
name: kube-apiserver
namespace: kube-system
spec:
containers:
- name: kube-apiserver
image: registry.k8s.io/kube-apiserver:v1.28.0
command:
- kube-apiserver
# 提升读请求并发上限(社区常用默认 400,大集群建议上调)
- --max-requests-inflight=2000
# 提升写请求并发上限(社区常用默认 200)
- --max-mutating-requests-inflight=1000
# 为高频资源预热 watch 缓存,降低 etcd 压力
- --watch-cache-sizes=nodes#1000,pods#5000,replicasets#1000
# 目标内存,影响本地缓存规模;需与节点内存匹配
- --target-ram-mb=8192
# 缩短事件保留,减少 etcd 中 event 对象体积
- --event-ttl=1h
# 启用优先级与公平性(v1.28 默认开启,显式声明便于审计)
- --enable-priority-and-fairness=true1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
调整边界
并发上限并非越大越好:每个在途请求占用 apiserver 内存与 goroutine,过高会触发 OOM 或拖慢单个请求。应结合 apiserver 的 apiserver_current_inflight_requests 指标与节点内存做容量评估,按 20%~30% 步长灰度上调并观察 P99。
生产实践:etcd 调优
yaml
# etcd 成员(独立节点)关键参数示例,仅示意
# 实际通过 systemd unit 或 static Pod 传递
etcd:
# 周期性压缩历史,避免 MVCC 膨胀
auto-compaction-mode: periodic
auto-compaction-retention: "1h"
# 配额,超出触发告警并拒绝写
quota-backend-bytes: 8589934592 # 8 GiB1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
配套运维动作:
bash
# 查看 db 大小与碎片率(需 ETCDCTL_API=3)
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
endpoint status --write-out=table
# 碎片整理(会短暂阻塞写,务必在低峰期、确认有备份后执行)
ETCDCTL_API=3 etcdctl defrag1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
生产危险
etcdctl defrag 与成员替换会短暂影响写可用性与集群稳定性,必须在维护窗口、已确认快照可用、且已通知业务方后执行。多成员集群请逐个 defrag,避免同时重启多数派。
官方建议在大规模集群把 Event 对象存到独立的 etcd 实例(见参考资料 [1] 的 etcd storage 段落),以隔离事件写放大对主存储的影响。
生产实践:节点密度与 kubelet 通信
单节点 Pod 数直接影响控制平面负载。官方大集群约束为每节点 ≤110 Pod、总数 ≤150,000 Pod(见参考资料 [1])。kubelet 默认每 10s 上报节点状态,5000 节点即 ~500 次/秒写请求;可调:
yaml
# /var/lib/kubelet/config.yaml(节点级,需滚动重启 kubelet)
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
nodeStatusUpdateFrequency: 20s
nodeStatusReportFrequency: 5m1
2
3
4
5
2
3
4
5
版本相关
nodeStatusReportFrequency 于较新版本引入,旧版本仅有 nodeStatusUpdateFrequency。调大上报间隔会延长节点异常的发现时延,需与监控告警 SLO 权衡。
验证
bash
# apiserver 在途请求与排队
kubectl get --raw /metrics | grep apiserver_current_inflight_requests
kubectl get --raw /metrics | grep apiserver_request_terminations_total # APF 限流计数
# etcd 健康与延迟
ETCDCTL_API=3 etcdctl endpoint health --cluster
kubectl get --raw /metrics | grep etcd_disk_wal_fsync_duration_seconds # fsync P99
# 调度吞吐
kubectl get --raw /metrics | grep scheduler_pending_pods1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
回滚与清理
参数回滚步骤
- 修改前备份清单:
cp /etc/kubernetes/manifests/kube-apiserver.yaml /backup/ - 用 Git 记录变更,便于
kubectl不可用时直接还原文件 - kubelet 会自动重启被修改的 static Pod(约数十秒生效)
- 若 apiserver 起不来:通过节点控制台还原备份并
systemctl restart kubelet - 观察
kubectl get componentstatuses(旧)/ 直接 curl 健康端点确认恢复
故障排查
| 现象 | 可能根因 | 排查点 |
|---|---|---|
| kubectl 偶发 429 | APF 限流 | apiserver_request_terminations_total |
| etcd leader 频繁切换 | 磁盘/网络抖动、CPU 争抢 | etcd_disk_wal_fsync_duration_seconds、节点负载 |
| 调度延迟高 | 节点数多、全量打分 | percentageOfNodesToScore、调度器 profile |
| apiserver OOM | --target-ram-mb 与实际不符 | 节点内存、watch 对象数 |
安全与合规
- etcd 等同集群 root 权限,仅 apiserver 应通过 TLS 访问,禁止暴露公网(见参考资料 [2])
- 调优
--max-*-inflight不削弱认证/授权,切勿为性能关闭 RBAC 或匿名认证 - 修改控制平面组件属于生产变更,必须走审批与维护窗口
性能、容量与成本
成本权衡
纵向扩容控制平面(更大 CPU/内存、本地 NVMe)通常比横向扩 apiserver 更简单且收益直接;etcd 必须用专用节点 + SSD,不能用廉价共享盘。多成员 etcd(5 个)带来 2 倍冗余成本,但是满足 quorum 与可用性的最低推荐(见参考资料 [2])。
常见坑
- 把
--event-ttl调得过小导致事件过早丢失,排障无据 - 只调 apiserver 不调 etcd,写瓶颈依旧
- 节点密度盲目拉高到数百 Pod/节点,kubelet 与 CNI 成为新瓶颈
[未实测,需按实际 CNI/内核验证] - 关闭 APF 以求"更高吞吐",反而让单租户拖垮全集群
参考资料
- [1] Kubernetes 官方文档 - Considerations for large clusters,访问日期:2026-10-08。https://kubernetes.io/docs/setup/best-practices/cluster-large/
- [2] Kubernetes 官方文档 - Operating etcd clusters for Kubernetes,访问日期:2026-10-08。https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/
- [3] Kubernetes 官方文档 - kube-apiserver 参考,访问日期:2026-10-08。https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/
- [4] etcd 官方硬件建议,访问日期:2026-10-08。https://etcd.io/docs/current/op-guide/hardware/