主题
第一部分 数千节点架构设计与容量规划
"一个 100 节点的集群可以靠经验运维,一个 5000 节点的集群只能靠架构运维。"
当集群规模跨过千节点门槛,曾经"能用"的默认配置会一个个变成定时炸弹:etcd 写延迟开始拖垮整个控制平面,kube-proxy 的 iptables 规则膨胀到数十万次匹配,一次大批量发版就能把镜像仓库打到拒绝服务。本部分的目标只有一个:在你按下安装命令之前,就把 5 年后会踩到的坑填平。
适用版本:RKE2 v1.28+ / Kubernetes v1.28+。文中所有数据均标注前提,不确定处给出保守区间。
本部分导读
| 章节 | 主题 | 核心问题 |
|---|---|---|
| 第 1 章 | K8s 扩展性边界 | 单集群到底能撑多大? |
| 第 2 章 | 总体架构设计 | 控制平面和网络拓扑怎么画? |
| 第 3 章 | etcd 大规模设计 | 集群的"心脏"如何不先衰竭? |
| 第 4 章 | 网络架构选型 | CNI / kube-proxy / IP 规划怎么选? |
| 第 5 章 | DNS 与镜像基础设施 | 数千节点同时拉镜像、同时解析域名怎么办? |
| 第 6 章 | 容量规划方法论 | 用数字说话,不用感觉说话 |
| 第 7 章 | 分区与多集群方案 | 单集群 5000 节点之外怎么走? |
| 第 8 章 | 常见面试题 | 架构设计向 10 题(含答案要点) |
第 1 章 大规模集群的挑战与 K8s 扩展性边界
1.1 为什么"大规模"是一个质变问题
小规模集群到大规模集群,不是"数量变多",而是统计规律开始生效:
- 100 节点时,节点故障是"小概率事件";5000 节点时,按单节点年故障率 2% 估算,平均每天都有节点处于故障或修复状态。
- 100 节点时,一次发版滚动更新几百个 Pod 是分钟级;5000 节点、10 万 Pod 时,同样的操作可能持续数小时,期间的镜像拉取、DNS 查询、调度决策都会形成"惊群"(thundering herd)。
- 任何 O(n) 的组件行为(iptables 规则、Endpoints 对象、watch 广播)都会从"无感"变成"主瓶颈"。
注意事项:大规模集群的第一性原理——任何随节点数或 Pod 数线性增长的组件开销,都必须在大规模下被显式设计,不能依赖默认值。
1.2 K8s 官方扩展性数据与前提
Kubernetes 官方 Scalability SIG 给出的单集群支持上限(v1.28 时代依然沿用):
| 指标 | 官方上限 | 关键前提 |
|---|---|---|
| 节点数 | 5000 | 满足下列全部约束 |
| Pod 总数 | 150000 | 平均每节点 ≤ 100 Pod(非硬性,见第 6 章) |
| 容器总数 | 300000 | — |
| 每节点 Pod 数 | 100(推荐值,非硬上限) | 受 kubelet、CNI、IPAM 制约 |
| Namespace 数 | 10000 | — |
| Service 数 | 10000 | 使用 kube-proxy iptables 模式时显著收缩 |
| 每 Service 后端 Pod 数 | 5000 | Endpoints/EndpointSlice 广播开销 |
这些数字的隐藏前提必须记住:
- 这些上限互相耦合,不是"全部同时达到"。例如 5000 节点 + 每节点 100 Pod = 50 万 Pod,已超过 15 万上限——实际组合必须做取舍。
- 上限基于官方可扩展性测试环境(GCP 上控制平面高规格机型、万兆网络、本地 SSD etcd),裸金属 + 机械盘 etcd 的环境达不到。
- 上限是在官方 SLI/SLO(见 1.3)被满足的前提下定义的,不是"集群不挂"的极限。
最佳实践:生产规划时按官方上限的 60%~70% 作为单集群设计容量(即约 3000~3500 节点、10 万 Pod),为突发增长和组件退化留出余量。这也是为什么本书以"数千节点"(而非 5000 整)为标题。
1.3 SLI/SLO:用指标定义"扛得住"
大规模集群的容量结论必须建立在 SLI/SLO 之上,否则"能不能撑住"永远是口水仗。
SLI(Service Level Indicator):可测量的服务水平指标。 SLO(Service Level Objective):SLI 的目标阈值。
K8s 官方定义的核心 SLI/SLO:
| SLI | 官方 SLO | 说明 |
|---|---|---|
| API 调用延迟(mutating,如 create/update) | P99 ≤ 1s(单对象 ≤ 30 字节范围外的对象另行折算,实践中按 P99 ≤ 1s 记) | 不含 LIST/GET |
API 调用延迟(资源无关的 LIST,如 kubectl get pods 集群级) | P99 ≤ 30s | 大 LIST 允许慢 |
| API 调用延迟(namespace 内 LIST) | P99 ≤ 5s | — |
| Pod 启动延迟(无状态 Pod,从 create 到 Running,不含镜像拉取) | P99 ≤ 5s | 前提:镜像已预热、无调度排队之外的人为等待 |
实测这些 SLI 的手段:
bash
# 1) 通过 apiserver 的 Prometheus 指标看 API 延迟
# P99 mutating latency(在任一 server 节点执行)
kubectl get --raw /metrics | grep -E 'apiserver_request_duration_seconds' | head
# 更实用的方式:查询 Prometheus
# histogram_quantile(0.99,
# sum(rate(apiserver_request_duration_seconds_bucket{verb=~"POST|PUT|PATCH|DELETE"}[5m]))
# by (le, resource))
# 2) 通过 kubelet 指标看 Pod 启动延迟
# histogram_quantile(0.99,
# sum(rate(kubelet_pod_start_duration_seconds_bucket[5m])) by (le))注意事项:RKE2 默认已将 apiserver、scheduler、controller-manager、etcd 以静态 Pod 形式暴露 metrics(注意 scheduler / controller-manager 在较新版本中只绑定在节点 127.0.0.1,需要通过 ServiceMonitor + 代理或修改
--bind-address才能被集群内 Prometheus 抓取,改绑定地址务必配合 NetworkPolicy 限制访问来源)。
1.4 扩展性瓶颈全景图
大规模集群的瓶颈按"通常最先撞墙"的顺序排列:
┌─────────────────────────────────────┐
│ 用户 / CI / 控制器 │
└───────────────┬─────────────────────┘
│ 全部 API 流量
▼
瓶颈② kube-apiserver ── CPU/内存/inflight 限流/watch 扇出
│ 读写
▼
瓶颈① etcd ──────────── 磁盘 fsync 延迟 / DB 8GB / watch 压力
▲
┌───────────────────────────────┼───────────────────────┐
│ │ │
瓶颈③ kube-scheduler 瓶颈④ kubelet × N 瓶颈⑥ CoreDNS
调度吞吐 ~数百 Pod/s 单节点 Pod 密度/PLEG 查询 QPS 爆炸
│
瓶颈⑤ 网络
iptables 规则膨胀 / conntrack / CNI IPAM| 瓶颈 | 典型症状 | 根因 | 本书章节 |
|---|---|---|---|
| etcd | apply request took too long、leader 切换频繁 | 磁盘 fdatasync 慢、DB 膨胀、compaction 风暴 | 第 3 章 |
| apiserver | 429(TooManyRequests)、Timeout or aborted while handling | inflight 限流、watch 扇出、大 LIST | 第 2、6 章 |
| scheduler | Pod 长时间 Pending 但资源充足 | 调度吞吐不足、调度器插件退化 | 第 6 章 |
| kubelet | PLEG is not healthy、容器启动慢 | 单节点 Pod 过密、磁盘/容器运行时压力 | 第 6 章 |
| 网络 | Service 变更生效慢、conntrack 表满 | iptables 线性匹配、规则爆炸 | 第 4 章 |
| DNS | 解析超时、CoreDNS OOM | 每节点 QPS 过高、上游级联 | 第 5 章 |
| 镜像 | 大批量发版时拉取超时 | registry 带宽/连接数打满 | 第 5 章 |
最佳实践:大规模集群排障的第一张图就画上面这张——先定位瓶颈在哪一层,再决定优化动作。不要凭直觉先调 etcd 参数。
1.5 单一大集群 vs 多集群(舰队):决策框架
这是数千节点规模下最重要的一个架构决策,必须在动工前拍板。
| 维度 | 单一大集群(3000~5000 节点) | 多集群舰队(如 10 × 500 节点) |
|---|---|---|
| 资源利用率 | 高(大池子碎片少,装箱率高) | 较低(每集群需独立预留 buffer) |
| 爆炸半径 | 大(etcd/apiserver 故障影响全部业务) | 小(故障域隔离) |
| 运维对象数 | 1 套控制平面 | N 套控制平面 + 1 套管理层 |
| 跨集群服务发现/网络 | 不需要 | 需要(Submariner / ServiceExport / 全局 Ingress 等) |
| 调度复杂度 | 单调度域,亲和性简单 | 需联邦调度(Karmada 等)或应用层路由 |
| 升级风险 | 一次升级牵动全局,灰度难 | 可逐集群灰度 |
| 团队/多租户隔离 | 依赖 Namespace + RBAC(软隔离) | 物理级硬隔离 |
| 扩展性天花板 | 官方 5000 节点,实际建议 ≤3500 | 理论无上限 |
| 镜像/DNS/监控基础设施 | 一套(压力集中) | 每集群一套或分层共享 |
决策框架(按优先级回答 4 个问题):
- 是否有硬隔离需求?(合规、强多租户、不同安全等级)→ 有则多集群,争论结束。
- 单一故障域能否接受全局停摆? → 不能接受则多集群。
- 业务是否需要跨地域部署? → 跨地域必然多集群(etcd 对 RTT 敏感,跨 AZ 单集群要求 RTT ≤ ~10ms 才稳妥,见第 3 章)。
- 规模是否超过 ~3500 节点? → 超过则多集群。
4 个问题都答"否"(同机房、同安全域、强资源共享诉求、3000 节点以内),单一大集群才是合理选择。
注意事项:不要落入"为做多集群而做多集群"的陷阱。多集群把单集群的容量问题换成了管理问题——需要舰队管理平台(Rancher / Karmada / Fleet)、统一的观测面、跨集群发布流水线。第 7 章详述。
1.6 本章小结
- 记住三个数:5000 节点 / 15 万 Pod / 30 万容器是官方天花板,生产按 6~7 折规划。
- 用官方 SLI/SLO(API P99、Pod 启动 P99)作为容量验收标准。
- 瓶颈全景图:etcd → apiserver → scheduler/kubelet → 网络/DNS,排障按图索骥。
- 单集群 vs 多集群用 4 问决策框架,先有结论再画架构。
第 2 章 数千节点总体架构设计
2.1 控制平面拓扑:3 / 5 / 7 节点 etcd 仲裁
etcd 基于 Raft,成员数为奇数以优化仲裁(quorum)。容忍故障数 = (n-1)/2:
| 成员数 | 仲裁数 | 容忍同时故障 | 写延迟 | 适用规模 | 建议 |
|---|---|---|---|---|---|
| 3 | 2 | 1 | 最低 | ≤ 1500 节点 | 小规模起步可选 |
| 5 | 3 | 2 | 略增 | 1500~5000 节点 | 数千节点生产推荐 |
| 7 | 4 | 3 | 明显增大 | 超大规模/跨 AZ | 仅在需要跨 3 AZ 各部署多成员时考虑 |
为什么不是"越多越好":Raft 每次写都要仲裁多数确认,成员越多:
- 写延迟越高(等待更多节点 fsync 返回);
- leader 选举更慢、消息扇出更大;
- 运维面(备份、升级、扩容)更复杂。
最佳实践:数千节点单机房集群用 5 成员 etcd;跨 3 AZ 且每 AZ 都要容灾时用 7(2+2+3 分布)。永远不要为"安全感"上 9 节点。
2.2 独立 etcd 节点 vs 混合部署
RKE2 原生把 etcd 与 server(控制平面组件)部署在一起,但通过 --disable-apiserver --disable-controller-manager --disable-scheduler 可以构造纯 etcd 节点,实现角色分离:
| 方案 | 优点 | 缺点 | 适用 |
|---|---|---|---|
| 混合部署(etcd + apiserver 同机) | 省机器、拓扑简单、RKE2 默认路径 | 故障耦合:一台机器挂=两份控制平面容量同时损失;apiserver CPU 尖峰会拖慢 etcd 磁盘 I/O 调度 | ≤ 数百节点 |
| 独立 etcd 节点(推荐) | etcd 独占 NVMe 与内存,性能可预测;apiserver 可独立水平扩缩;故障域清晰 | 多 2 台机器(3+2 vs 3);RKE2 需拆分 server 角色部署 | 数千节点必选 |
独立 etcd 的 RKE2 部署要点:
yaml
# /etc/rancher/rke2/config.yaml —— 纯 etcd 节点(共 5 台)
disable-apiserver: true
disable-controller-manager: true
disable-scheduler: true
node-name: etcd-01
node-ip: 10.10.0.11yaml
# /etc/rancher/rke2/config.yaml —— 纯控制平面节点(共 3~5 台,无 etcd)
disable-etcd: true
server: https://etcd-01:9345
node-name: cp-01
node-ip: 10.10.0.21注意事项:拆分角色后,首个引导节点必须是 etcd 节点(
cluster-init: true或作为首个 server);加入顺序与 token 约定与常规多 server 一致。disable-etcd的控制平面节点仍需能直连所有 etcd 节点的 2379 端口,防火墙策略不要照搬默认文档。
2.3 apiserver 水平扩展与负载均衡
2.3.1 apiserver 是无状态的,但客户端连接不是
apiserver 本身无状态(状态全在 etcd),可以任意水平扩缩。但:
- kubelet、controller 与 apiserver 之间是长连接 + watch,HTTP/2 多路复用下单个 TCP 连接承载大量请求;
- LB 只在连接建立时做负载均衡决策,连接一旦建立就不再迁移;
- 结果:节点重启、证书轮换、LB 漂移都会造成"全部连接挤在某一台 apiserver 上"。
缓解手段:
- 客户端侧:kubelet 设置
rotateCertificates(RKE2 默认启用)之外,更关键的是让客户端定期重连——kubelet 无此配置,但 apiserver 侧可用--goaway-chance主动断开:
yaml
# /etc/rancher/rke2/config.yaml(控制平面节点)
kube-apiserver-arg:
- "goaway-chance=0.001" # 每个请求约 0.1% 概率收到 GOAWAY,促使客户端重连扩散
- "max-requests-inflight=800" # 按规格调整,见第 6 章
- "max-mutating-requests-inflight=400"- LB 侧:使用支持"最小连接数"调度的 LB,而不是轮询(RR 对长连接毫无意义)。
2.3.2 LB 选型对比
| 方案 | 原理 | 优点 | 缺点 | 大规模适用性 |
|---|---|---|---|---|
| 硬件 LB(F5/NetScaler) | 专用设备 L4 转发 | 性能极高、企业已有、运维成熟 | 贵、配置在 K8s 体系外 | 大型企业首选 |
| HAProxy + Keepalived | 软件 L4 + VRRP 漂移 VIP | 免费、灵活、可观测(stats 页) | 需自运维;VIP 漂移有秒级中断 | 数千节点主流选择 |
| kube-vip | 节点内 VIP/BGP 宣告 | 无需外部设备、云原生 | ARP 模式二层受限;BGP 模式依赖交换机 | 中小规模、无外部 LB 环境 |
| 云厂商 LB(SLB/NLB) | 托管 | 免运维 | 仅云上 | 公有云场景 |
HAProxy + Keepalived 参考配置(6443 端口):
# /etc/haproxy/haproxy.cfg(两台 LB 各一份,Keepalived 负责 VIP 漂移)
global
log /dev/log local0
maxconn 100000
defaults
mode tcp
timeout connect 5s
timeout client 300s # watch 长连接,client/server 超时要足够长
timeout server 300s
frontend k8s-api
bind 10.10.0.100:6443
default_backend k8s-api-backend
backend k8s-api-backend
balance leastconn # 关键:长连接场景用最少连接,不用 roundrobin
option tcp-check
tcp-check connect port 6443
# RKE2 apiserver 健康检查端点:/livez(或 /healthz),需忽略自签证书
tcp-check send "GET /livez HTTP/1.1\r\nHost:\ 10.10.0.100\r\nConnection:\ close\r\n\r\n"
tcp-check expect rstring "200 OK"
server cp-01 10.10.0.21:6443 check inter 3s fall 2 rise 2
server cp-02 10.10.0.22:6443 check inter 3s fall 2 rise 2
server cp-03 10.10.0.23:6443 check inter 3s fall 2 rise 2注意事项:
- 健康检查必须查
/livez(进程存活)而非仅 TCP 通——但要意识到 apiserver 过载时/livez也可能变慢,可加verbose参数或用/readyz做更严格的摘流。实践中推荐:LB 用/livez保活,/readyz由监控系统报警,避免过载时 LB 摘流引发雪崩(把流量全压到剩下的实例上)。- RKE2 的 agent 加入走的是
server: https://<VIP>:9345(supervisor 端口),9345 也需要挂 LB 或指向任一 server;生产建议 6443 与 9345 都过 VIP。timeout client/server一定要 ≥ 最长 watch 周期,否则 watch 被 LB 静默掐断,表现为客户端周期性重连风暴。
2.4 故障域设计与拓扑标签
数千节点集群必须显式建模故障域,否则 scheduler 的打散能力形同虚设。
故障域层级(典型三层):
Region(地域)
└── Zone / AZ(机房/可用区)—— 故障域:供电、制冷、核心网络
└── Rack(机架) —— 故障域:ToR 交换机、PDU
└── Host(节点)K8s 内置拓扑标签:
| 标签 | 含义 | 用途 |
|---|---|---|
topology.kubernetes.io/region | 地域 | 多地域集群、PV 拓扑感知 |
topology.kubernetes.io/zone | 可用区/机房 | Pod 反亲和打散、拓扑感知路由 |
kubernetes.io/hostname | 主机 | 默认可用 |
机架级不是内置标签,RKE2 注册节点时自定义:
yaml
# /etc/rancher/rke2/config.yaml(agent 节点)
node-label:
- "topology.kubernetes.io/zone=az1"
- "failure-domain.kubernetes.io/rack=rack-a07"
- "node-role.kubernetes.io/ingress=true"应用侧用 topologySpreadConstraints 跨机架/机房打散:
yaml
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway # 大规模下建议软约束,硬约束易引发 Pending
labelSelector:
matchLabels: { app: payment }
- maxSkew: 2
topologyKey: failure-domain.kubernetes.io/rack
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels: { app: payment }最佳实践:大规模集群里
whenUnsatisfiable: ScheduleAnyway优于DoNotSchedule——硬约束在节点故障潮(rack 断电后重启几十个节点)时会制造大量 Pending Pod,软约束+监控 skew 更稳。
2.5 参考架构图:生产级数千节点 RKE2 集群
下图为一个 ~3000 节点、三网分离(管理网/业务网/存储网)、独立 etcd 的生产参考架构:
┌──────────────────────────────┐
│ 运维入口: Rancher Manager │
│ (独立小集群, 见第 7 章) │
└──────────────┬───────────────┘
│ 管理网 10.10.0.0/16
┌────────────────────────────────┼────────────────────────────────┐
│ ▼ │
│ ┌──────────────────────┐ │
│ │ VIP 10.10.0.100 │ ← Keepalived VRRP │
│ │ HAProxy-1 HAProxy-2│ (2 台 LB) │
│ └──────────┬───────────┘ │
│ 6443/9345 │ leastconn │
│ ┌───────────┬──────────┼──────────┬───────────┐ │
│ ▼ ▼ ▼ ▼ ▼ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ cp-01 │ │ cp-02 │ │ cp-03 │ 纯控制平面节点 │
│ │apiserver│ │apiserver│ │apiserver│ (disable-etcd) │
│ │sched/cm│ │sched/cm│ │sched/cm│ 16C32G ×3~5 │
│ └───┬────┘ └───┬────┘ └───┬────┘ │
│ │ etcd client 2379 │ │
│ ┌────┴─────────┬──┴───────┬┴───────────┬───────────┐ │
│ ▼ ▼ ▼ ▼ ▼ │
│ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │
│ │etcd-01│ │etcd-02│ │etcd-03│ │etcd-04│ │etcd-05│ 独立 etcd│
│ │ NVMe │ │ NVMe │ │ NVMe │ │ NVMe │ │ NVMe │ 8C16G │
│ │ 跨rack│ │ 跨rack│ │ 跨rack│ │ 跨rack│ │ 跨rack│ 跨机架 │
│ └───────┘ └───────┘ └───────┘ └───────┘ └───────┘ │
│ 2380 peer (Raft) 全网状互联, 延迟 < 10ms │
│════════════════════ 管理网 / 控制平面 ════════════════════│
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 业务网 10.20.0.0/16 (25G×2 bond) │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │worker ×N│ │worker ×N│ ... │worker ×N│ │ │
│ │ │ Calico │ │ Calico │ │ Calico │ │ │
│ │ │kube-proxy│ │kube-proxy│ │kube-proxy│ │ │
│ │ │NodeLocal│ │NodeLocal│ │NodeLocal│ │ │
│ │ │ DNSCache│ │ DNSCache│ │ DNSCache│ │ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │
│ └───────┼───────────┼──────────────────┼──────────┘ │
│ │ Pod 流量 (BGP/VXLAN) │ │
│ ┌───────▼───────────▼──────────────────▼──────────┐ │
│ │ CoreDNS ×8~12 Ingress GW ×6 MetalLB │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 存储网 10.30.0.0/16 (独立物理网, Ceph/NFS) │ │
│ │ worker 第三块网卡直连, 与业务网物理隔离 │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ┌───────────── 共享基础设施 ─────────────┐ │
│ │ Harbor HA ×2 (+Dragonfly P2P 见第5章) │ │
│ │ Prometheus(分片)/Loki/Alertmanager │ │
│ │ NTP / 外部 DNS / 堡垒机 │ │
│ └───────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────┘三网分离要点:
| 网络 | 承载流量 | 网卡建议 | 理由 |
|---|---|---|---|
| 管理网 | apiserver/etcd/SSH/监控采集 | 10G | etcd 与 apiserver 通信延迟敏感 |
| 业务网 | Pod/Service/Ingress 南北东西流量 | 25G×2 bond | 业务带宽主体 |
| 存储网 | Ceph/Longhorn/NFS 数据面 | 25G 独立 VLAN 或物理网 | 存储 I/O 尖峰不挤占业务 |
RKE2 侧配合:node-ip 指定管理网 IP(apiserver/etcd 通信用),advertise-address 同理;CNI(Calico)的 IP_AUTODETECTION_METHOD 指向业务网卡,存储网卡不进 K8s 路由表。
2.6 本章小结
- etcd 5 成员、独立部署、跨机架放置,是数千节点的控制平面基线。
- LB 用 HAProxy+Keepalived(或企业现有 F5),
leastconn+/livez+ 长超时三件套。 - apiserver 配
goaway-chance解决长连接不均。 - 故障域标签 + 软约束 topologySpreadConstraints,让打散在故障潮下依然成立。
- 三网分离:管理/业务/存储各走各的网卡。
2.7 注意事项 / 最佳实践速查
- ✅ 控制平面节点全部打上
node-role.kubernetes.io/control-plane污点(RKE2 默认),业务 Pod 绝不调度上去。 - ✅ etcd 节点、cp 节点分散在 ≥3 个机架、≥2 路供电。
- ❌ 不要把 9345 只指向单台 server——新增 agent 加入时该 server 宕机就全员卡住。
- ❌ 不要在 LB 上对 6443 做 TLS 终止再转发(apiserver 证书体系不允许中间人,除非重新签发并配置
tls-san与 SNI 透传——直接 TCP 透传最省事)。
第 3 章 etcd 大规模设计
3.1 etcd 性能模型:它为什么会成为第一瓶颈
etcd 是强一致的 Raft KV 存储。每个写请求的路径:
client → leader 接收 → 写 WAL (fsync 到盘) → 广播给 follower
→ 多数派各自写 WAL (fsync) 并应答 → leader 提交
→ 应用到 boltdb (周期性 fsync) → 响应 client关键结论:
- 写延迟 ≈ 磁盘 fsync 延迟 + 网络 RTT 中的较大者。任何一环退化,整个集群的所有写操作(创建 Pod、更新 Endpoint、节点心跳 Lease……)全部变慢。
- etcd 是单线程应用 MVCC 数据到 boltdb 的,读可以并发、写串行化,因此 CPU 核数超过 ~8 后收益骤减,单核性能与磁盘性能远比核数重要。
etcd 自身暴露的关键指标(etcd_debugging_mvcc_db_total_size_in_bytes、etcd_disk_wal_fsync_duration_seconds、etcd_network_peer_round_trip_time_seconds)是大规模集群必采指标。
3.2 硬件要求:fdatasync 延迟是金标准
etcd 官方用 fdatasync 的 P99 延迟作为磁盘是否合格的判据:
| 磁盘类型 | 典型 fdatasync P99 | 是否适合 etcd |
|---|---|---|
| 机械盘 (HDD) | 10~100ms+ | ❌ 禁止 |
| SATA SSD | 1~10ms | ⚠️ 仅限小规模 |
| 企业级 NVMe SSD | 0.1~1ms | ✅ 数千节点必选 |
| 公有云 gp3/io2 等保证 IOPS 的云盘 | 0.5~2ms | ✅ 云上可用 |
用 fio 自测(采购验收时必须跑):
bash
# 安装 fio 后,模拟 etcd 的写模式测 99 分位 fdatasync 延迟
fio --rw=write --ioengine=sync --fdatasync=1 \
--directory=/var/lib/rancher/rke2/server/db \
--size=100m --bs=2300 --name=etcdbench
# 关注输出中 clat 的 99.00th 分位:
# < 10ms → 勉强可用(< 数百节点)
# < 2ms → 可用于千节点级
# < 1ms → 数千节点理想同时通过 etcd 指标在线监控:
promql
# WAL fsync P99(应 < 10ms,告警阈值常用 50ms)
histogram_quantile(0.99,
sum(rate(etcd_disk_wal_fsync_duration_seconds_bucket[5m])) by (le, instance))
# raft 提交延迟
histogram_quantile(0.99,
sum(rate(etcd_disk_backend_commit_duration_seconds_bucket[5m])) by (le, instance))
# 成员间 RTT(同机房应 < 10ms)
histogram_quantile(0.99,
sum(rate(etcd_network_peer_round_trip_time_seconds_bucket[5m])) by (le, To))3.3 DB 大小、quota 与碎片整理
3.3.1 8GB 上限与 quota-backend-bytes
- etcd 默认 DB quota 为 2GB,官方支持的最大值为 8GB(超过 8GB 官方明确不保证可靠性)。
- K8s 场景下 DB 大小 ≈ 所有对象总大小 × (1 + 碎片率)。数千节点、10 万 Pod 的集群,etcd DB 常见 2~4GB(含碎片)。
- 大规模集群建议把 quota 提到 8GB 上限,为突发对象增长留缓冲:
yaml
# /etc/rancher/rke2/config.yaml(etcd 节点)
etcd-arg:
- "quota-backend-bytes=8589934592" # 8GB
- "auto-compaction-mode=periodic"
- "auto-compaction-retention=8h" # 见 3.3.2超过 quota 的症状:apiserver 返回 etcdserver: mvcc: database space exceeded,集群只读(可删不可写),这是大规模集群最经典的故障之一。
3.3.2 compaction 与 defrag:一对必须理解的组合拳
| 概念 | 作用 | 触发方式 | 影响 |
|---|---|---|---|
| Compaction(压缩) | 丢弃旧版本 key,释放逻辑空间 | RKE2 由 apiserver 周期性触发(默认每 5 分钟 compact 到最近的周期点);etcd 侧 auto-compaction 兜底 | 过程有 I/O 开销;compact 期间延迟毛刺 |
| Defrag(碎片整理) | 重建 boltdb 文件,释放物理磁盘空间 | 必须手动/定时任务执行(etcdctl defrag),不会自动发生 | defrag 期间该成员阻塞读写(秒级~十秒级),必须逐成员滚动执行 |
关键认知:compact 不缩盘,只有 defrag 缩盘。K8s 删除 10 万个 Pod 后,etcd DB 文件不会变小,只是内部出现空洞。
滚动 defrag 脚本(先 follower 后 leader):
bash
#!/bin/bash
# defrag-etcd.sh —— 对 RKE2 嵌入式 etcd 逐成员碎片整理
ETCDCTL="etcdctl --cacert=/var/lib/rancher/rke2/server/tls/etcd/server-ca.crt \
--cert=/var/lib/rancher/rke2/server/tls/etcd/client.crt \
--key=/var/lib/rancher/rke2/server/tls/etcd/client.key \
--endpoints=https://127.0.0.1:2379"
# 1. 找出当前 leader,最后处理
LEADER=$($ETCDCTL endpoint status --write-out=json \
| jq -r '.[] | select(.Status.header.member_id == .Status.leader) | .Endpoint')
# 2. 逐成员 defrag(注意:RKE2 嵌入式 etcd 每成员需在各自节点上执行,
# 或用 --endpoints 指向对应成员;生产建议做成 cron + 分布式锁)
for EP in $($ETCDCTL endpoint status --write-out=json | jq -r '.[].Endpoint'); do
[ "$EP" = "$LEADER" ] && continue
echo "defrag $EP"
etcdctl --endpoints="$EP" --cacert=... --cert=... --key=... defrag
sleep 60 # 等该成员追上 raft 日志
done
echo "defrag leader $LEADER last"注意事项:defrag 期间该成员停止响应,5 成员集群滚动执行是安全的;3 成员集群 defrag 会短暂只剩 2 成员(恰好等于 quorum,再抖一下就丢仲裁),3 成员集群的 defrag 要放在业务低峰并加强监控。
3.3.3 事件历史与 watch 压力
- K8s 的 watch 机制依赖 etcd 的 revision 历史。compaction 间隔决定"客户端最多能回看多久的历史"。
- apiserver 默认每 5 分钟 compact 一次。后果:watch 断线超过 compact 窗口的客户端会收到
410 Gone(too old resource version),被迫全量 relist。 - 大规模集群里,一个失控控制器(informer 配置错误、网络分区恢复)发起的全量 relist 风暴是 apiserver 过载的常见原因。
缓解:
yaml
# apiserver 侧:限制 LIST 的分页,强制大 LIST 走分页
kube-apiserver-arg:
- "default-watch-cache-size=1000" # 大集群可适度调大 watch cache
# 客户端侧(自研控制器):informer 必须设置 ResourceVersion 续传、
# 避免全量 List;巧用 metadata-only informer 降低对象体积监控 watch 压力:
promql
# 各资源类型的 watch cache 大小与 watch 连接数
sum(apiserver_watch_events_total) by (resource)
sum(apiserver_current_inflight_requests) by (request_kind)
# relist 风暴信号:LIST 请求 QPS 突增
sum(rate(apiserver_request_total{verb="LIST"}[5m])) by (resource)3.4 备份策略
RKE2 内置 etcd 快照,开箱即用但默认参数不适合大规模:
yaml
# /etc/rancher/rke2/config.yaml(etcd 节点)
etcd-snapshot-schedule-cron: "0 */2 * * *" # 每 2 小时(默认 12 小时太稀疏)
etcd-snapshot-retention: 12 # 保留 24 小时窗口
etcd-s3: true # 快照自动上传 S3 兼容存储
etcd-s3-endpoint: "minio.infra.local:9000"
etcd-s3-bucket: "rke2-etcd-snapshots"
etcd-s3-access-key: "xxx"
etcd-s3-secret-key: "xxx"手动快照与校验:
bash
# 立即打快照
rke2 etcd-snapshot save --name manual-$(date +%F-%H%M)
# 列出快照
rke2 etcd-snapshot list
# 恢复演练(每季度必做!在隔离环境)
rke2 server --cluster-reset \
--cluster-reset-restore-path=/var/lib/rancher/rke2/server/db/snapshots/<快照名>备份策略矩阵:
| 层级 | 手段 | RPO | 说明 |
|---|---|---|---|
| L1 | RKE2 定时快照(本地) | 2h | 快速回滚,防误操作 |
| L2 | 快照同步到 S3/MinIO(异地) | 2h | 防机房级灾难 |
| L3 | 声明式备份(GitOps 全量 manifest) | 提交时 | 集群可重建的最终保障 |
最佳实践:etcd 快照恢复的是"数据",恢复不了"信任"——大规模集群恢复演练要包含 LB、证书、node 重新加入的完整剧本。没演练过的备份等于没有备份。
3.5 本章小结
- etcd 写延迟 = max(磁盘 fsync, 网络 RTT);NVMe 是硬门槛,fio 验收 P99 < 1~2ms。
- quota 提到 8GB;compact(逻辑)与 defrag(物理)分工记牢,defrag 滚动执行。
- watch/relist 风暴是大规模特有杀手,监控 LIST QPS。
- 快照 2h 一次 + S3 异地 + 季度恢复演练。
第 4 章 网络架构选型
4.1 CNI 在数千节点下的选型对比
RKE2 内置支持 Canal(默认)、Calico、Cilium、Multus 等。大规模下的核心差异在于转发路径和状态同步机制:
| CNI | 数据面 | 控制面状态同步 | 数千节点适用性 | 说明 |
|---|---|---|---|---|
| Canal(Flannel VXLAN + Calico Policy) | VXLAN(内核 flannel.1) | 每个节点 watch 全量 Node/Pod 元数据 | ⚠️ 可用但非最优 | RKE2 默认;VXLAN 封包有 ~50B 开销与 MTU 损失 |
| Calico VXLAN | VXLAN | 同上,Calico 可用 Typha 做 fanout 代理 | ✅ 可用(必须开 Typha) | 兼容性好,排障简单 |
| Calico BGP | 纯路由(无封装) | BGP 路由反射器(Route Reflector) | ✅ 裸金属数千节点主流 | 无 overlay 开销;需交换机/RR 配合 |
| Cilium(eBPF) | eBPF(native routing 或 VXLAN/Geneve) | 内置 kvstore 或 CRD 模式 + 可替代 kube-proxy | ✅ 性能上限最高 | NetworkPolicy/可观测性最强;内核要求 ≥ 4.19,建议 5.x |
| Flannel host-gw | 静态路由 | 简单 | ⚠️ 二层受限 | 仅适合扁平二层网络 |
| kube-OVN | OVN/OpenFlow | OVN 南北向 DB | ✅ 可用 | 功能全(VPC/QoS),复杂度也高 |
关键扩展性机制——状态扇出:
默认模式下,每个节点的 CNI agent 都直连 apiserver watch 全量 Node/Pod 信息。3000 节点 = 3000 条 watch 长连接扇出全量事件,apiserver 压力巨大。两派的解法:
- Calico → Typha:apiserver ← Typha(3~5 副本)← 所有 calico-node。Typha 把扇出收敛到个位数连接。超过 ~100 节点就应启用。
yaml
# Calico 启用 Typha(HelmChartConfig 方式,RKE2 体系内)
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: rke2-calico
namespace: kube-system
spec:
valuesContent: |-
typha:
enabled: true
replicas: 3 # 每 ~200 节点 1 副本,上限 20 副本- Cilium → 无此问题:CRD 模式下状态对象化 + eBPF map 本地决策;且可用
--kube-proxy-replacement=strict彻底移除 kube-proxy(见 4.3)。
BGP 模式的路由反射器拓扑(Calico 大规模标配):
┌─────────────┐ ┌─────────────┐
│ RR-1 (ToR │ │ RR-2 (独立 │ RR = BGP Route Reflector
│ 交换机) │ │ 服务器) │ 每个 node 只与 RR 建 BGP 会话
└──────┬──────┘ └──────┬──────┘ 避免 3000×3000 全互联
│ iBGP │
┌───────────┼─────────────────┼───────────┐
▼ ▼ ▼ ▼
node-1 node-2 ...... node-2999 node-3000
(每节点宣告自己的 Pod CIDR /26 或 /27 路由)4.2 Pod CIDR 与 IPAM 规划
数千节点 × 每节点数十~上百 Pod,IP 地址规划错误是最痛且最难改的架构失误(改 cluster-cidr 约等于重建集群)。
4.2.1 规划原则
- 容量按终态规划:节点数终值 × 每节点 Pod 上限 × 1.5(冗余)。
- 避开现有网段:
10.0.0.0/8、172.16.0.0/12、192.168.0.0/16与企业内网、云上 VPC、IDC 网段的冲突要逐一排查,包括未来可能互联的网络。 - Service CIDR 独立:service-cidr 不需要太大(/16 给 6.5 万 Service 绰绰有余),但同样不能重叠。
4.2.2 计算案例(3000 节点终态)
| 参数 | 取值 | 计算 |
|---|---|---|
| 节点终值 | 3000(规划到 4096) | — |
| 每节点 Pod 上限 | 128 | 见第 6 章 |
| Pod IP 总需求 | 4096 × 128 = 524,288 | ≈ 52 万 |
| 单节点掩码 | /25(128 地址,126 可用) | 每节点一个 /25 |
| 节点块总数 | 4096 × /25 = /13 | — |
| cluster-cidr 选择 | 10.12.0.0/13(524,288 地址) | 刚好用尽;保守用 /12(如 10.64.0.0/12 含 104 万) |
| service-cidr | 10.13.0.0/16(示例小集群值;大集群建议避开 10.12.0.0/13 所在范围) | 6.5 万 Service |
RKE2 配置:
yaml
# /etc/rancher/rke2/config.yaml
cluster-cidr: 10.64.0.0/12 # 给终态留 2 倍余量
service-cidr: 10.96.0.0/16
cluster-dns: 10.96.0.10yaml
# Calico 侧:节点块大小(IPPool blockSize)
# blockSize=25 → 每节点 /25,126 个 Pod IP
# 注意:blockSize 越小,BGP 宣告的路由条数越多(每节点一条)
# /25 → 4096 条节点路由,对 RR 无压力;/27 → 路由表更碎注意事项:
- Cilium/Calico 原生 routing 模式下 Pod IP 直接从底层可达,Pod CIDR 不能与企业内任何需要访问 Pod 的网段重叠;VXLAN 模式下可放宽(外部看到的是节点 IP)。
- 规划文档必须沉淀(IPAM 登记表),数千节点集群后期合并/互联时,CIDR 冲突是头号拦路虎。
4.3 kube-proxy:iptables / IPVS / eBPF
这是大规模集群教科书级的瓶颈点(本仓库 metaLB/ 目录有专题深挖,此处给结论)。
4.3.1 iptables 模式为什么在大规模下失效
kube-proxy iptables 模式把每个 Service 的每个后端翻译成若干条 iptables 规则,包转发是线性匹配:
| 规模 | 规则条数(估算) | 后果 |
|---|---|---|
| 1000 Service × 平均 3 后端 | ~1~2 万条 | 无感 |
| 5000 Service × 平均 5 后端 | 5~10 万条 | 首包延迟显著、规则更新(Endpoints 变化)整表重建耗时秒级~十秒级、更新期间转发抖动 |
| 大 Endpoints 频繁变动 | 规则重写 QPS 高 | conntrack 抖动、CPU softirq 飙高 |
更糟的是:每条规则同步是全量重写(iptables-save/restore),Service 越多每次越慢,越慢期间 Pod 增删越多——恶性循环。
4.3.2 IPVS 模式
IPVS 用哈希表存 Service→后端映射,查找 O(1),规则增量更新:
yaml
# /etc/rancher/rke2/config.yaml(本仓库 rke2/ 目录实测配置)
kube-proxy-arg:
- "proxy-mode=ipvs"
- "ipvs-scheduler=lc" # least-connection,长连接业务友好;默认 rr节点内核需加载模块(RKE2 会自动加载大部分,建议固化):
bash
cat > /etc/modules-load.d/ipvs.conf <<EOF
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
ip_vs_lc
nf_conntrack
EOFIPVS 大规模下的残留问题:conntrack 表压力依旧存在(iptables/IPVS 都依赖 conntrack),需要调大并监控:
bash
# 当前用量与上限
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
# 数千节点 + 高密度节点建议 nf_conntrack_max ≥ 2000000,并缩短非活跃 UDP 超时
sysctl -w net.netfilter.nf_conntrack_max=20971524.3.3 eBPF(Cilium kube-proxy replacement)
- Service 查找、负载均衡、conntrack 全部在 eBPF map 中完成,完全绕过 iptables/conntrack 主路径;
- 支持 Maglev 一致性哈希(连接保持)、DSR(直接服务端返回)、XDP 加速;
- 代价:学习曲线陡、内核版本要求高(建议 ≥ 5.10 LTS 内核,Rocky 9 默认 5.14 可用)、排障工具链换成
ciliumCLI 与 Hubble。
选型结论表:
| 集群规模 | 推荐数据面 | 备注 |
|---|---|---|
| < 500 节点 | 任意(Canal+iptables 也能跑) | 简单优先 |
| 500~3000 节点 | Calico(VXLAN 或 BGP) + Typha + IPVS | 稳妥主流 |
| 3000~5000 节点或高密度 Service | Cilium eBPF(替代 kube-proxy) 或 Calico BGP + IPVS | 性能上限优先 |
4.4 NetworkPolicy 在大规模下的考量
- 策略本身也是 CNI 数据面的状态:数千节点 × 数千条策略,Calico 会编译成每个节点的 iptables/ipset(注意又回到 iptables 匹配问题——但 policy 规则通常远少于 Service 规则);Cilium 则在 eBPF map 中,膨胀代价低得多。
- 全集群默认拒绝 + 按需放行是安全基线,但默认拒绝规则会作用到每个 Pod,注意 DNS(kube-dns)、NodeLocal DNSCache(169.254.20.10 与上游 10.96.0.10)必须显式放行,否则大面积解析故障。
- 策略变更的传播延迟随节点数增长,Calico 开 Typha 后约秒级;变更后务必有自动化拨测验证。
yaml
# 大规模集群 NetworkPolicy 基线示例:default ns 默认拒绝,放行 DNS
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: default
spec:
podSelector: {}
policyTypes: [Ingress, Egress]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: default
spec:
podSelector: {}
policyTypes: [Egress]
egress:
- to:
- namespaceSelector:
matchLabels: { kubernetes.io/metadata.name: kube-system }
ports:
- { protocol: UDP, port: 53 }
- { protocol: TCP, port: 53 }4.5 Service 与 Endpoints 的数量上限
- 官方上限 10000 Service;使用 IPVS/eBPF 后可以突破,但 Endpoints 扇出成为新瓶颈:每个 Endpoints 对象变化要推给所有节点的 kube-proxy watch。
- K8s v1.21+ 的 EndpointSlice(默认开启)把大 Service 的后端切成 ≤100 个/片,扇出量按片计算,是大规模必须依赖的机制——确认没有老旧组件直接消费 Endpoints API。
- 超大 Service(>5000 后端)尽量避免;业务上改用分片 Service + 客户端选择。
4.6 本章小结
- CNI 二选一:稳妥选 Calico(+Typha,裸金属优先 BGP),性能上限选 Cilium eBPF。
- IP 规划按终态 ×1.5~2 预留,/12 起步不丢人,CIDR 冲突才丢人。
- 超过千节点 Service 规模,kube-proxy 用 IPVS 或直接 eBPF 替代;conntrack 上限同步调大。
- NetworkPolicy 全默认拒绝基线 + DNS 放行;EndpointSlice 必须全程生效。
第 5 章 DNS 与镜像基础设施
5.1 CoreDNS 水平扩展
默认 2 副本 CoreDNS 在数千节点集群里是裸奔。容量估算经验值(保守):
- 每 Pod 平均 DNS QPS 按 2~5 估算,10 万 Pod ≈ 20 万~50 万 QPS 集群总查询量;
- 单副本 CoreDNS(2C 限值)实测约 2~5 万 QPS(取决于响应大小、缓存命中率);
- → 需要 8~20 副本,跨节点反亲和部署。
yaml
# CoreDNS 扩副本(RKE2 通过 HelmChartConfig 或直接改 deployment)
kubectl -n kube-system scale deployment rke2-coredns-rke2-coredns --replicas=12注意三件事:
- autoscaler 模式:大规模建议用
cluster-proportional-autoscaler(按节点数线性扩副本):
yaml
# ladder 模式:每 64 节点 1 副本,最低 8,最高 24
data:
ladder: |-
{
"coresToReplicas": [],
"nodesToReplicas":
[
[1, 8],
[512, 10],
[1024, 12],
[2048, 16],
[4096, 24]
]
}CoreDNS Service 只有少量 ClusterIP:kube-dns Service 后端 12 个 Pod,IPVS/eBPF 会把单节点 DNS 请求均衡到全部副本,没问题;但要确认
ndots:5带来的搜索域展开(每个外部域名先查 5 次集群内域)——大规模集群可引导业务镜像用 FQDN 尾点(example.com.)或调dnsConfig.ndots。反亲和与 PDB:12 副本必须跨节点、跨机架打散,并配 PodDisruptionBudget(minAvailable: 50%),否则一次节点维护窗口可能同时带走多个 DNS 副本引发解析雪崩。
5.2 NodeLocal DNSCache:大规模下的必选项
即使有 20 副本 CoreDNS,仍然存在结构性问题:
- DNS 默认走 UDP + conntrack:每个节点的 DNS 查询都占 conntrack 条目,高密度节点上 DNS 是 conntrack 打满的头号元凶之一;
- 跨节点网络跳转增加延迟与故障面;
- CoreDNS 副本重启/调度期间,部分节点解析抖动。
NodeLocal DNSCache 以 DaemonSet 在每节点起本地缓存(监听 169.254.20.10),Pod 的 DNS 查询优先命中本节点:
优化前:Pod ──(conntrack/跨节点)──▶ CoreDNS ──▶ 上游
优化后:Pod ──▶ 本节点 nodelocaldns (169.254.20.10)
│ 缓存未命中
▼ (TCP 向上游,规避 conntrack UDP 抖动)
CoreDNS ──▶ 上游部署要点(RKE2 环境):
bash
# 官方 manifest 模板渲染(关键变量):
# __PILLAR__DNS__SERVER__ = kube-dns ClusterIP(如 10.96.0.10)
# __PILLAR__LOCAL__DNS__ = 169.254.20.10
# __PILLAR__DNS__DOMAIN__ = cluster.local
kubectl apply -f nodelocaldns.yaml
# kubelet 需指向本地 DNS(RKE2 config.yaml,所有节点):
# cluster-dns: 169.254.20.10
# 注意:修改 cluster-dns 需要滚动重启节点或重建 Pod 才全量生效收益(经验值,视业务 DNS 密度而定):
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 集群内域名解析 P99 | 5~30ms | <1ms(本地缓存命中) |
| CoreDNS 副本数需求 | N | N/3 ~ N/5(缓存吸收大部分 QPS) |
| conntrack UDP 条目 | 高 | 显著下降(nodelocaldns 向上游用 TCP) |
注意事项:NodeLocal DNSCache 与 NetworkPolicy 的交互是经典坑——默认拒绝策略会阻断 Pod 到 169.254.20.10 的流量(它不在任何 namespace 内)。Cilium/Calico 需用 CIDR 型 egress 规则放行 169.254.20.10/32 的 53 端口。
5.3 镜像仓库架构:扛住数千节点同时拉镜像
场景量化:一次大版本滚动更新 3000 节点,假设镜像层 1.5GB、窗口 10 分钟 → 需要聚合带宽 3000×1.5GB/600s = 7.5 GB/s = 60 Gbps。单 registry 无论如何扛不住。必须分层架构:
┌──────────────────────┐
│ Harbor 主站 (HA×2) │ ← 推送/CI 写入、元数据、漏洞扫描
│ 对象存储后端 (S3) │
└──────────┬───────────┘
│ 预分发/同步
┌────────────────┼────────────────┐
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌────────────┐
│ Harbor 副本│ │ Harbor 副本│ │ Dragonfly │ ← P2P 层
│ (机房A) │ │ (机房B) │ │ 超级节点 ×3 │
└─────┬─────┘ └─────┬─────┘ └─────┬──────┘
│ │ │ P2P 分发
┌─────┴───────────────┴────────────────┴──────┐
│ 3000 worker:containerd 拉取 │
│ - 配置 registry mirror(就近副本) │
│ - 或运行 dfdaemon,P2P 互传镜像层 │
└─────────────────────────────────────────────┘5.3.1 Harbor 高可用要点
- 无状态组件(core/registry/portal)×2 挂 LB;PostgreSQL/Redis 外置高可用;registry 存储用 S3 兼容对象存储(不要用本地盘,否则副本间还要同步镜像数据);
- 开启 镜像代理缓存项目(proxy cache)缓存上游(Docker Hub 等),避免数千节点穿透到公网;
- GC 与漏洞扫描任务错开业务高峰——大规模仓库的 Trivy 全量扫描能把 DB 打满。
5.3.2 P2P 分发:Dragonfly / Kraken
| 方案 | 现状 | 特点 |
|---|---|---|
| Dragonfly(CNCF Graduated) | 活跃,推荐 | dfdaemon 驻节点做 P2P;超级节点(seed peer)做回源与种子;支持 containerd 集成 |
| Kraken(Uber 开源) | 维护趋缓 | 类似架构,tracker+agent |
Dragonfly 与 RKE2(containerd)集成思路:containerd 的 registry 配置把 Harbor 指向本机 dfdaemon 代理端口,dfdaemon 负责 P2P 拉取与回源:
toml
# /etc/rancher/rke2/registries.yaml(RKE2 私有 registry 配置)
mirrors:
harbor.infra.local:
endpoint:
- "http://127.0.0.1:65001" # dfdaemon 代理端口
- "https://harbor.infra.local" # P2P 不可用时回退直连
configs:
harbor.infra.local:
auth:
username: xxx
password: xxx收益:热点镜像层由节点间互传,回源流量与节点数近似解耦(从 O(n) 降到 O(1)~O(log n)),60Gbps 的洪峰可压到源站 <5Gbps。
5.3.3 不用 P2P 的保守替代
- Harbor 副本分层(每机房/每故障域一套代理缓存项目),RKE2
registries.yaml的 mirror endpoint 按节点所在机房配置就近副本; - 配合镜像预热(DaemonSet 预拉取大镜像)和滚动更新限速(
maxUnavailable调小),把瞬时带宽需求摊平。
最佳实践:无论用不用 P2P,发布系统必须实现"镜像预分发后再滚动"的两阶段发布;
imagePullPolicy: IfNotPresent+ 明确的镜像 tag(禁用:latest)。
5.4 本章小结
- CoreDNS 按节点数线性扩(autoscaler),12~24 副本 + 反亲和 + PDB。
- NodeLocal DNSCache 在千节点以上视为必选,注意 NetworkPolicy 放行 169.254.20.10。
- 镜像面:Harbor HA(S3 后端)+ 分层 mirror,洪峰场景上 Dragonfly P2P;发布侧两阶段预分发。
第 6 章 容量规划方法论
6.1 控制平面规格估算表
基于官方可扩展性测试数据与社区生产经验(前提:NVMe etcd、万兆网、对象大小中位数 ~1KB 级别、无失控控制器),给出保守估算:
| 节点规模 | apiserver 实例 | 单实例 CPU/内存 | etcd 成员 | etcd 单实例 CPU/内存/盘 | 说明 |
|---|---|---|---|---|---|
| ≤ 500 | 3 | 4C / 8~16GB | 3 | 2~4C / 8GB / 50GB NVMe | 可混合部署 |
| 500~1500 | 3 | 8C / 16~32GB | 3~5 | 4C / 16GB / 100GB NVMe | 建议 etcd 独立 |
| 1500~3000 | 3~5 | 16C / 32~64GB | 5 | 4~8C / 16~32GB / 200GB NVMe | 角色全分离 |
| 3000~5000 | 5 | 32C / 64~128GB | 5 | 8C / 32GB / 500GB NVMe | 需精细化调优 |
apiserver 内存的经验公式(粗算,供预留用):
apiserver 内存 ≈ 基数(2GB) + watch cache 对象总大小 × 1.5~2
≈ 2GB + (对象数 × 对象平均大小) × 1.7
例:15 万 Pod × 3KB + 其它对象 ≈ 0.7GB 原始 → watch cache ≈ 1.2GB
再加 inflight 请求缓冲、序列化开销、波动余量 → 单实例 16~32GB 合理调整 apiserver 限流与缓存:
yaml
# /etc/rancher/rke2/config.yaml(3000 节点参考值)
kube-apiserver-arg:
- "max-requests-inflight=800" # 默认 400
- "max-mutating-requests-inflight=400" # 默认 200
- "default-watch-cache-size=2000" # 大集群调大 watch cache
- "goaway-chance=0.001"
- "event-ttl=2h" # 大规模集群 Event 是 etcd 体积大户注意事项:
max-requests-inflight不是越大越好——它的意义是在 apiserver 过载时快速失败(429)保护 etcd,调太大等于拆掉了保险丝。配套手段是 APF(API Priority and Fairness,v1.20+ 默认 Beta 并启用),用FlowSchema给系统组件(kubelet、scheduler)保留独立队列,防止某个失控控制器饿死节点心跳。
6.2 节点密度规划:110 Pod 上限的改与不改
kubelet 默认 maxPods: 110。RKE2 同样默认 110。改不改?
| 每节点 Pod 数 | 前提 | 风险 |
|---|---|---|
| ≤ 110(默认) | 无 | 最稳妥,官方测试基线 |
| 110~150 | CNI IPAM 块匹配(/25=126)、kubelet 资源充足、镜像预热 | PLEG 延迟上升,需监控 |
| > 200 | 官方无测试背书;IP 块 /24;事件/watch/iptables 全链路放大 | 不推荐,除非有专项压测 |
RKE2 调整:
yaml
# /etc/rancher/rke2/config.yaml(worker)
kubelet-arg:
- "max-pods=128"
- "kube-api-qps=50" # 大集群每个 kubelet 的 QPS 要控制(默认 5/10 已偏小,
- "kube-api-burst=100" # 但无限制上调会让 3000 个 kubelet 打爆 apiserver)关键乘数效应:3000 节点 × kube-api-qps=50 理论上限 = 15 万 QPS 打向 apiserver——所以 kubelet QPS 宁小勿大,节点 Ready 抖动时(如雷暴断电后批量恢复)心跳风暴是真实事故场景。默认值(QPS 5/burst 10)在大多数场景足够,节点 Lease 心跳间隔由 --node-status-update-frequency(默认 10s)与 Lease 续约(默认 40s)控制,与 QPS 共同决定心跳总量。
单节点 kubelet 压力点清单:
| 资源 | 默认/常见值 | 大规模建议 |
|---|---|---|
| maxPods | 110 | ≤ 128~150,配合 CNI 块 |
| 容器运行时 | containerd | 限制 max_concurrent_downloads(默认 3,批量调度时保护磁盘) |
| 镜像 GC | imageGCHighThreshold 85% | 高密度节点降到 70~75%,留缓冲 |
| 日志 | 容器日志按 10Mi×5 | 严控 stdout 洪峰业务(logrotate 风暴会拖死节点磁盘 IO) |
| 系统预留 | system-reserved/kube-reserved | 生产必配,防止 Pod 把节点资源吃干导致 kubelet/SSHD 失联 |
yaml
kubelet-arg:
- "max-pods=128"
- "system-reserved=cpu=500m,memory=1Gi"
- "kube-reserved=cpu=500m,memory=2Gi"
- "eviction-hard=memory.available<500Mi,nodefs.available<10%"
- "image-gc-high-threshold=75"
- "image-gc-low-threshold=65"
- "container-log-max-size=10Mi"
- "container-log-max-files=3"6.3 增长预留原则
- 控制平面:按 18 个月终态规模 × 1.3 预留(etcd 盘、apiserver 内存可纵向扩,但机房机位不一定能加)。
- 网络/IP:CIDR 按终态 × 1.5~2(见 4.2),这是唯一不可事后扩容的维度,给最足。
- 业务容量:集群可分配资源(allocatable)利用率日常控制在 60~70%,保留故障转移空间——一个 rack(~40 节点)宕机时,其负载要能塞进剩余节点。
- N+1 机架冗余:按"任意一个机架整体丢失,集群仍满足 SLO"做容量验算。
6.4 完整测算案例:3000 节点集群
输入条件:终态 3000 worker;平均每节点 100 Pod(30 万上限内取 30 万的一半以下,实际 10 万 Pod 业务基线 + 5 万峰值余量);裸金属,单机房 3 个供电分区,每分区 8 个机架。
6.4.1 控制平面测算
| 项 | 取值 | 依据 |
|---|---|---|
| etcd | 5 成员,8C/32GB/500GB NVMe×2(RAID1),跨 3 供电分区 5 机架 | 6.1 表;fdatasync P99 < 1ms 采购验收 |
| 控制平面 | 5 台,32C/64GB,disable-etcd | LB leastconn 均匀分担 |
| LB | 2 台 HAProxy+Keepalived,4C/8GB,10G | 纯 L4 转发,CPU 余量 10 倍 |
| apiserver 参数 | inflight 800/400,watch cache 2000 | 6.1 |
| etcd quota | 8GB;快照 2h/次 × 12 份 + S3 | 3.3、3.4 |
6.4.2 网络与 IP 测算
| 项 | 取值 | 计算 |
|---|---|---|
| Pod IP 需求 | 3000 × 128 = 384,000 | maxPods=128 |
| cluster-cidr | 10.64.0.0/12(1,048,576 地址) | 需求 × 2.7,富余 |
| 节点块 | /25(126 可用)× 3000 块 | Calico blockSize=25 |
| service-cidr | 10.96.0.0/16 | 6.5 万 Service |
| Service 数上限 | 规划 ≤ 8000 | 官方 1 万的 80% |
| CNI | Calico BGP + Typha×6 + 2 台 RR | 每 500 节点 1 Typha 副本 |
| kube-proxy | IPVS,conntrack_max=2M | 4.3 |
| DNS | NodeLocal + CoreDNS 16 副本 | 5.1、5.2 |
6.4.3 节点与机架测算
| 项 | 取值 |
|---|---|
| worker 规格 | 32C/256GB(通用池)+ 128C/1TB(大数据池,单独节点池/标签) |
| 机架分布 | 3000 / 24 机架 = 125 台/机架,每机架 ≤ 40% 单机柜功率 |
| N+1 验算 | 丢 1 机架 = 丢 125 节点(4.2%)→ 业务 requests 利用率需 ≤ 65%,✅ |
| 同时维护上限 | 每窗口 ≤ 1 机架(PDB + ClusterAutoscaler/人工节奏控制) |
6.4.4 基础设施测算
| 项 | 取值 |
|---|---|
| Harbor | 2 站点 HA + S3 后端;发布峰值按 3000 节点 × 1.5GB / 30min = 2.5GB/s 镜像拉取预算 → Dragonfly P2P 兜底 |
| 监控 | Prometheus 分片(按 namespace 哈希)+ 长周期存储(VictoriaMetrics/Thanos);节点 exporter 3000 个 target,采集间隔 30s |
| 日志 | 每节点 100 Pod × 1MB/s 峰值 → 集群峰值 ~100GB/s 级别不现实,必须在应用侧限流 + 采样,采集侧 Loki/ES 按热点业务配额制 |
6.4.5 验收 SLI 清单(上线前压测)
bash
# 用 perf-tests/clusterloader2 做官方密度压测(规模缩减到预算内)
git clone https://github.com/kubernetes/perf-tests
# 例:300 节点抽样的 density 测试,外推 SLI 余量| SLI | 目标 | 验收方式 |
|---|---|---|
| API mutating P99 | ≤ 1s | Prometheus histogram |
| Namespace LIST P99 | ≤ 5s | 同上 |
| Pod 启动 P99 | ≤ 5s(镜像预热) | kubelet 指标 |
| etcd WAL fsync P99 | ≤ 10ms(目标 ≤ 2ms) | etcd 指标 |
| DNS 解析 P99 | ≤ 10ms | nodelocaldns 指标 + 拨测 |
6.5 本章小结
- 容量规划 = 查表(6.1)→ 定密度(6.2)→ 乘冗余(6.3)→ 案例验算(6.4)→ SLI 验收(6.4.5)。
- 三个不可事后补救的决策:CIDR、etcd 磁盘选型、故障域标签体系——动工前冻结。
- kubelet 参数有乘数效应,任何 per-node QPS 调整都要 × 节点数重新审视。
第 7 章 分区与多集群方案
7.1 单集群之外的出路:什么时候必须拆分
回顾 1.5 的决策框架,当以下任一成立时进入多集群设计:
- 规模 > ~3500 节点(生产保守线);
- 跨地域/跨机房且 RTT > 10ms(etcd 无法跨地域延展);
- 硬隔离(安全合规、租户、环境:生产/预发/测试天然分集群);
- 爆炸半径管控(金融级业务按业务线拆分集群)。
拆分维度(可组合):
| 维度 | 示例 | 优点 | 代价 |
|---|---|---|---|
| 按地域 | 北京/上海/深圳各一集群 | 就近接入、故障域隔离 | 跨地域服务发现 |
| 按业务线 | 交易/搜索/推荐分集群 | 爆炸半径小、权责清晰 | 共享中间件需跨集群 |
| 按环境 | prod/staging/dev | 变更隔离 | 环境漂移风险 |
| 按硬件代际 | GPU 集群独立 | 驱动/内核版本解耦 | 池子变小 |
7.2 多集群管理技术选型速览
| 方案 | 类型 | 定位 | 与 RKE2 的契合度 |
|---|---|---|---|
| Rancher Manager + Fleet | 管理面 + GitOps | 集群生命周期管理 + 多集群应用分发 | ★★★★★(RKE2 同门) |
| Karmada(CNCF) | 联邦调度 | 跨集群工作负载编排、故障转移 | ★★★★(与发行版无关) |
| Clusternet(CNCF Sandbox) | 应用分发 | 侧重子集群应用下发、访客集群免凭据 | ★★★ |
| Open Cluster Management (OCM) | 管理面 | Red Hat 系多集群管理 | ★★★ |
| vCluster 等虚拟集群 | 租户隔离 | 在宿主集群内开虚拟控制平面 | 隔离粒度介于 ns 与集群之间 |
注意 kubefed(Federation v2)已归档,新选型不要入坑。Karmada 是其事实继任者。
7.3 Rancher Fleet 管理多 RKE2 集群
Rancher 体系下,Fleet 是内置的多集群 GitOps 引擎(持续交付),与 RKE2 集群注册(cluster registration/agent)天然集成:
┌────────────────────────────────────┐
│ Rancher Manager (HA) │
│ ┌──────────┐ ┌───────────────┐ │
│ │ Cluster │ │ Fleet │ │
│ │ Manager │ │ Controller │ │
│ └────┬─────┘ └───────┬───────┘ │
└───────┼─────────────────┼──────────┘
│ 注册隧道(agent) │ GitOps 下发
┌──────────┼────────┐ │
▼ ▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐
│RKE2-01│ │RKE2-02│ │RKE2-03│ ... 数十~数百个下游集群
│(prod) │ │(prod) │ │(edge) │
└───────┘ └───────┘ └───────┘Fleet 的 GitRepo 按 label 匹配集群组(ClusterGroup),典型用法:
yaml
# fleet.yaml(Git 仓库中,描述"这批配置下发到哪些集群")
targetCustomizations:
- name: prod-large
clusterSelector:
matchLabels:
env: prod
scale: large
helm:
values:
corednsReplicas: 16
- name: edge
clusterSelector:
matchLabels:
env: edge
helm:
values:
corednsReplicas: 2用 Fleet 管理什么(建议边界):
- ✅ CNI/CoreDNS/NodeLocal DNS/监控 agent/安全基线等"集群级底座组件"——全部 GitOps 化;
- ✅ NetworkPolicy 基线、PSA 标签、ResourceQuota 模板;
- ⚠️ 业务应用:业务团队有自己的 CD 流水线时,Fleet 只负责底座,避免两套发布系统打架。
7.4 Rancher Manager 自身的大规模部署
管理数百个下游 RKE2 集群时,Rancher Manager 自己就是瓶颈:
| 项 | 建议 |
|---|---|
| 部署位置 | 独立的专用小集群(3 server RKE2/k3s,绝不与管理对象同集群——管理面挂了不能连自救入口都没有) |
| 规格 | 每节点 8C/32GB 起步;下游集群 > 100 或节点总数 > 5 万时 16C/64GB,并拆分多个 Rancher 实例按域分管 |
| etcd | 独立 NVMe;Rancher 把大量 CRD(Cluster、Catalog、Token 等)写入 etcd,watch 数量随下游集群数暴涨 |
| 数据库注意 | Rancher 无外部 DB,一切在 etcd——Rancher 集群的 etcd 快照策略与第 3 章同标准执行 |
| 网络 | 下游 agent 与 Manager 之间是出站长连接(WebSocket 隧道),出口带宽按 下游集群数 × ~1Mbps 余量规划 |
| 升级 | 先升 Manager 再分批升下游;用 Fleet/节点池分批控制节奏 |
最佳实践:Rancher 管理面遵循"三个分离"——与业务集群分离部署、与业务账号体系分离(独立 IdP 组)、与业务变更窗口分离。
7.5 多集群下必须补齐的能力清单
单集群拥有的能力,多集群都要回答"跨集群怎么办":
| 能力 | 单集群 | 多集群方案 |
|---|---|---|
| 服务发现 | Service/DNS | 全局 DNS(如按集群子域 svc.cluster-01.global)、mcs-api(ServiceExport/Import)、或服务网格多集群 |
| 流量入口 | Ingress ×1 | 全局负载(GSLB/Anycast)+ 每集群本地 Ingress |
| 身份 | RBAC | 统一 IdP(OIDC/LDAP)+ 各集群 RoleBinding 模板化下发 |
| 观测 | 一套 Prometheus | 分层:每集群本地 Prometheus → 全局 Thanos/VictoriaMetrics 汇聚 |
| 发布 | helm/kustomize | Fleet/ArgoCD ApplicationSet/Karmada |
| 策略 | NetworkPolicy/OPA | Gatekeeper + Fleet 统一下发,审计汇聚 |
7.6 本章小结
- 拆分先定维度(地域/业务/环境),再选管理面(RKE2 生态首选 Rancher + Fleet)。
- Rancher Manager 部署在独立小集群,自身按第 3 章标准做 etcd 保障。
- 多集群 = 单集群能力 × N + 全局层(发现/入口/身份/观测/策略)——预算表里别漏掉全局层成本。
第 8 章 常见面试题(架构设计向)
以下 10 题覆盖数千节点 RKE2/K8s 架构面试的高频考点,每题给出考察意图与答案要点。
Q1:K8s 单集群的官方扩展性上限是多少?生产上你会按多少规划,为什么?
考察点:是否知道上限的前提条件,而非背数字。 答案要点:5000 节点 / 15 万 Pod / 30 万容器 / 1 万 Service / 每节点 100 Pod(推荐)。前提:高规格控制平面、NVMe etcd、低 RTT、官方 SLI/SLO 达标。生产按 60~70%(约 3000~3500 节点)规划,为突发增长、组件退化、故障转移留余量;且各上限互相耦合不能同时打满。
Q2:设计一个 3000 节点的 RKE2 集群,控制平面怎么部署?
考察点:拓扑决策能力。 答案要点:etcd 5 成员独立部署(disable-apiserver 等三参数构造纯 etcd 节点),跨 3 个供电分区/5 个机架,NVMe(fdatasync P99 < 1~2ms 验收),quota 8GB;apiserver 3~5 台 disable-etcd 节点,前端 HAProxy+Keepalived VIP(leastconn + /livez 检查 + 长超时),apiserver 配 goaway-chance 解决长连接不均;9345/6443 都挂 LB。
Q3:为什么 kube-proxy 的 iptables 模式在大规模下会失效?怎么解决?
考察点:对转发面复杂度的理解。 答案要点:Service 规则线性匹配 O(n),5000 Service 时规则 5~10 万条;Endpoints 变化触发全量规则重写,重写耗时随规则数增长,期间转发抖动;conntrack 压力同步放大。解决:IPVS(哈希 O(1) + 增量更新,本仓库 rke2/ 目录即 proxy-mode=ipvs 实测配置),或 Cilium eBPF 完全替代 kube-proxy;同时调大 nf_conntrack_max 并监控。
Q4:一次大版本发布,3000 节点同时拉镜像,镜像仓库被打爆,架构上怎么预防?
考察点:分发链路设计。 答案要点:① Harbor HA(S3 后端)+ 多机房代理缓存副本分层;② 大规模洪峰上 P2P(Dragonfly,dfdaemon 节点互传,回源流量与节点数解耦);③ 发布流程两阶段:先 DaemonSet 预分发镜像,再限速滚动(控制 maxUnavailable);④ 禁用 :latest、IfNotPresent;⑤ RKE2 registries.yaml 配置就近 mirror endpoint。
Q5:etcd DB 到了 8GB 上限怎么办?compact 和 defrag 的区别是什么?
考察点:etcd 运维深度。 答案要点:compact 丢弃旧版本 key 释放逻辑空间(apiserver 每 5 分钟周期触发),不缩物理文件;defrag 重建 boltdb 释放磁盘空间,需手动滚动执行(先 follower 后 leader),期间该成员阻塞读写。达到 quota 后集群只读(database space exceeded):应急→手动 compact + defrag + 确认无超限后 etcdctl alarm disarm;预防→quota 提 8GB、控制 Event 留存(event-ttl)、监控 etcd_mvcc_db_total_size 在 50% 告警。
Q6:NodeLocal DNSCache 解决了什么问题?为什么大规模集群几乎是必选?
考察点:DNS 链路的结构性瓶颈。 答案要点:解决三个问题——① UDP DNS 查询占用 conntrack 条目,高密度节点 conntrack 打满的头号来源;② 跨节点解析的延迟与故障面;③ CoreDNS 副本抖动的影响面。机制:DaemonSet 本地缓存(169.254.20.10),向上游走 TCP。注意坑:NetworkPolicy 需放行该 link-local 地址;修改 cluster-dns 需重建 Pod 生效。
Q7:3000 节点集群,apiserver 收到大量 429,你的排查与处置思路?
考察点:控制平面保护机制(inflight 限流 + APF)。 答案要点:先定位来源——apiserver_current_inflight_requests 看读写占用、apiserver_request_total 按 user/verb/resource 维度找出大户(常见:失控控制器 relist 风暴、批量 Job、节点批量恢复心跳);短期处置:确认 max-requests-inflight 保险丝未被盲目调大,用 APF FlowSchema 保障系统组件(kubelet lease、scheduler)队列优先;根治:修复失控客户端(informer 续传、退避)、大 LIST 改分页/watch-cache、必要时横向扩 apiserver 实例。
Q8:单集群到 5000 节点之后怎么走?对比联邦与"管理面 + 多集群"两条路线。
考察点:多集群视野。 答案要点:联邦路线(Karmada):跨集群调度与故障转移能力强,适合"同一业务跨集群弹性"场景,但引入新的控制面与调度语义。管理面路线(Rancher + Fleet):集群间不强耦合,按地域/业务/环境拆分,GitOps 统一下发底座,全局层补齐服务发现(GSLB/mcs-api)、观测汇聚、统一身份。实践中以管理面路线为主,仅在确有跨集群编排诉求时叠加 Karmada。kubefed 已归档,不选型。
Q9:给你一块新采购的服务器做 etcd,如何验证它是否合格?
考察点:是否知道 etcd 的性能判据。 答案要点:核心指标是 fdatasync P99 延迟(官方明确以 99 分位 fsync 延迟作为磁盘适配标准)。用 fio 模拟 etcd 写模式(--rw=write --ioengine=sync --fdatasync=1 --bs=2300),P99 < 1ms 理想、< 2ms 可用、> 10ms 拒绝;同时验证:NVMe 企业级(掉电保护)、独立盘不与业务混部、上线后用 etcd_disk_wal_fsync_duration_seconds_bucket 持续监控 P99,50ms 触发告警。
Q10:设计集群的故障域与打散策略,机架断电这种场景如何保证业务 SLO?
考察点:容量规划与拓扑调度的结合。 答案要点:① 节点注册时打全拓扑标签(zone/rack/hostname,RKE2 node-label);② 工作负载用 topologySpreadConstraints 跨 zone 和 rack 打散,大规模下用 ScheduleAnyway 软约束避免故障潮时大面积 Pending;③ 容量上做 N+1 机架冗余验算——任意一机架(如 125 节点)整体丢失,剩余节点能承接其负载,日常 requests 利用率 ≤ 65%;④ 控制平面组件(etcd 5 成员、CoreDNS、Typha)自身跨机架反亲和 + PDB;⑤ 维护窗口限定单窗口 ≤ 1 机架。
附录 A:本部分关键默认值与推荐值速查
| 参数 | 默认值 | 数千节点推荐值 | 位置 |
|---|---|---|---|
| etcd quota-backend-bytes | 2GB | 8GB | etcd-arg |
| etcd 快照 | 12h × 5 份 | 2h × 12 份 + S3 | etcd-snapshot-* |
| kubelet max-pods | 110 | ≤ 128~150 | kubelet-arg |
| apiserver inflight | 400 / 200(mutating) | 800 / 400(配合 APF) | kube-apiserver-arg |
| goaway-chance | 0 | 0.001 | kube-apiserver-arg |
| kube-proxy 模式 | iptables | ipvs / eBPF 替代 | kube-proxy-arg |
| nf_conntrack_max | 内核默认(常 26 万级) | ≥ 200 万 | sysctl |
| CoreDNS 副本 | 2 | 按节点数 8~24 + NodeLocal | HelmChartConfig |
| Calico Typha | 关 | 开,每 ~200 节点 1 副本 | HelmChartConfig |
附录 B:参考检查清单(架构评审用)
- [ ] 单集群 vs 多集群决策已用 4 问框架评审并留档
- [ ] etcd 独立部署、5 成员、跨 3 供电分区、NVMe fio 验收报告
- [ ] LB:leastconn + /livez + client/server 超时 ≥ 300s
- [ ] cluster-cidr / service-cidr 与企业全部现存及规划网段无冲突(IPAM 登记表)
- [ ] CNI 选型含状态扇出方案(Typha 或 Cilium)
- [ ] kube-proxy:ipvs 或 eBPF;conntrack 上限与监控
- [ ] NodeLocal DNSCache + NetworkPolicy 放行 169.254.20.10
- [ ] Harbor HA(S3 后端)+ mirror 分层 + P2P 预案 + 两阶段发布
- [ ] 故障域标签 + topologySpreadConstraints 软约束 + N+1 机架验算
- [ ] SLI/SLO 验收指标全部接入监控并演练过告警
- [ ] etcd 快照恢复季度演练记录
下一部分预告:第二部分《安装与配置:从单机到数千节点的 RKE2 工程化落地》将基于本仓库
rke2/目录的真实脚本与配置,讲解自动化装机、配置管理、证书轮换与离线部署。