AI Infra 训练营
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
HiHuo 主站
GitHub
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
HiHuo 主站
GitHub
  • Day 0 · 环境与硬件

    • Day 0:5 节点裸 Ubuntu → K8s 装机基线
  • Week 1:K8s 内核 + 周边基础设施

    • Day 1:3 CP HA 集群 + CNI 选型 + DNS 调优
    • Day 2: 控制面 deep dive + etcd 内核 + chaos drill
    • Day 3: CRD + Operator (kubebuilder 从 0 写)
    • Day 4: Storage 主线 + Cilium 二探
    • Day 5: Volume Expansion + 安全主线
    • Day 6: 调度 + 观测主线 + Day 2 遗留修复
    • Day 7: Harbor + ArgoCD + Cilium Service Mesh
  • Week 2:制品 + GitOps + AI Infra + 综合

    • Day 8 主线 — AI Infra: GPU + k3s + vLLM + Qwen2.5
    • Day 8 主线 — AI Infra 尝试 1 (跨 WAN GPU 加入主集群)
    • Day 8 (alt) — AlertManager 真接入 + PrometheusRule 实战
    • Day 8: CI Infrastructure — Gitea + Jenkins + Kaniko
    • Day 9: Triton + GPU Metrics + 推理性能对比
    • Day 10: MIG + 量化 + HPA Custom Metrics
    • Day 11: AI Agent 业务端到端 — 把 Day 1-10 全部串起来
    • Day 12: 灾难恢复 + 生产事故注入
    • Day 13: LLM Operator + 联邦 + Mesh + RAG
    • Day 14: CKA/CKS 真题演练 + 14 天 Bootcamp 终极总结

Day 2: 控制面 deep dive + etcd 内核 + chaos drill

目标: 把 Day 1 起的 K8s 集群从"能用"升级到"懂内核 + 敢搞挂 + 能修回"。 耗时: 3-5 小时(主要是阅读 + 配置 + 实验,不等镜像) 风险: chaos 操作可能搞挂集群,snapshot save 必须先做 才能 restore


0. TL;DR

  1. apiserver static pod(Day 2.A): 读 /etc/kubernetes/manifests/kube-apiserver.yaml 30+ flag,启用 audit 看 K8s API 所有调用
  2. etcd 内核(Day 2.B): raft 选主 / MVCC revision / compact 压缩 / defrag 空间回收 / snapshot save+restore
  3. chaos drill(Day 2.C): kill 1 etcd 看选主 → kill 2 etcd quorum loss → 从 snapshot 恢复 → 完整 postmortem

1. 学习目标 + 闭环输出

能秒答:

  • "apiserver 启动顺序是什么?为什么 health probe 失败重启不影响 etcd?"
  • "etcd raft 选主 timeout 默认多少?"
  • "MVCC compact vs defrag 区别?"
  • "K8s 控制面节点全挂能恢复吗?数据在哪里?"

能动手做:

  • 写 audit policy 看到任何 kubectl 操作的完整 audit log
  • etcdctl 操作集群成员
  • snapshot save + 模拟全集群挂掉 → restore 重建

产出物:

  • 一份 audit-policy.yaml(生产可用)
  • 一份 etcd backup(scp 到本地一份)
  • chaos drill 完整 postmortem 文档

2. 整体流程

Day 2.A apiserver/admission/audit
        ↓
        启用 audit → 看到 kubectl 操作真实 log
        ↓
Day 2.B etcd internals
        ↓
        endpoint status → MVCC revision → compact → defrag → snapshot save
        ↓
Day 2.C chaos
        ↓
        kill etcd-cp-1 (1 down) → 选主 → 集群继续
        ↓
        kill etcd-cp-2 (quorum loss 2/3 down) → apiserver 拒写 → 恢复
        ↓
        极端: 3 个 etcd 全删 → 从 snapshot restore (灾难恢复演练)

3. Day 2.A — apiserver / admission / audit (详见第 10 节)

4. Day 2.B — etcd 内核 (详见第 10 节)

5. Day 2.C — chaos drill (详见第 10 节)


10. 实时执行日志(Lab Notebook, 6 维度)

(开干后填,跟 Day0/Day1 同格式)


Op A: apiserver 启用 audit (生产必做)

What — kubeadm 默认 不开 audit log。生产必须开,记录所有 API 调用,排查安全事件 / 调试客户端必备。

audit-policy.yaml(4 级 level: None / Metadata / Request / RequestResponse):

apiVersion: audit.k8s.io/v1
kind: Policy
omitStages: ["RequestReceived"]
rules:
# 1. 高频低价值的 noise 不记 (configmap/endpoint/event get-list-watch)
- level: None
  resources:
  - group: ""
    resources: ["configmaps","endpoints","events"]
  - group: "coordination.k8s.io"
    resources: ["leases"]
  verbs: ["get","list","watch"]
# 2. 系统 SA 自查 不记
- level: None
  users: ["system:kube-proxy","system:kube-scheduler","system:kube-controller-manager"]
  verbs: ["get","list","watch"]
# 3. Secret 写操作记 full RequestResponse (含 body)
- level: RequestResponse
  resources:
  - group: ""
    resources: ["secrets"]
  verbs: ["create","update","patch","delete"]
# 4. 默认 Metadata 级别
- level: Metadata

patch apiserver manifest 加 4 个 flag + 2 个 hostPath volume:

- --audit-policy-file=/etc/kubernetes/audit-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit.log
- --audit-log-maxage=7         # 保留 7 天
- --audit-log-maxbackup=3      # rotate 3 个
- --audit-log-maxsize=100      # 单文件 100MB 切

Why —

  • audit log 是 K8s 安全合规第一公民 (PCI/SOC2/HIPAA 都要)
  • Secret 写 RequestResponse 因为是高敏感数据,审计强需求(查 谁在 什么时候 改了 什么)
  • 同时要排除高频低价值的查 (configmap/endpoint/leases) 防 log 爆炸
  • log rotate 防盘满
  • audit policy 4 级 trade-off:
    • None: 不记 (噪音过滤)
    • Metadata: user / verb / resource / name / namespace / code (最常用)
    • Request: + request body (改变记录,但 GET 请求看不到回参)
    • RequestResponse: + response body (完整,占盘最大)

Actual —

  • audit.log 立刻有数据,200K 后涨到 5MB+
  • Secret 写日志带 base64-encoded body: "requestObject":{"password":"dG9wc2VjcmV0"} = "topsecret"
  • ConfigMap 写记 Metadata 不带 body
  • 发现 system:anonymous 大量 get(haproxy + Cilium 健康检查未带 token,K8s anonymous auth 默认开)

Lesson —

  1. kubeadm 不开 audit,生产必加。面试常问 "K8s 怎么排查谁在什么时候改了某个 Secret?" → audit log RequestResponse
  2. system:anonymous 高频 get 是潜在安全隐患: kubelet/haproxy 健康探针不带 token,被允许 anonymous get,这本身不严重但暴露了 K8s 默认开 anonymous auth。生产关掉 --anonymous-auth=false,改用 token 健康检查
  3. audit-log 落盘性能影响: 高 QPS 集群下 audit log 占 IO 5-10%,生产需要 SSD + 单独盘 + log rotate 严格
  4. 生产 audit 进阶: 用 fluent-bit 把 audit.log 转发到 Elasticsearch / Splunk,便于查询;落盘只做 short retention
  5. 修改 static pod manifest 不需要 systemctl restart kubelet: kubelet 监听 /etc/kubernetes/manifests/ 目录,改 yaml 文件 ~10s 内自动 reconcile。面试常问"static pod 怎么自动重启" → kubelet 文件系统 watch

Op B: etcd 内核 (raft / MVCC / compact / defrag / snapshot)

What — etcd 是 K8s "唯一真实状态" 存储。理解它就理解了 K8s 的 ACID 边界。

ETCDCTL='kubectl -n kube-system exec etcd-k8s-cp-1 -- etcdctl
  --cacert=/etc/kubernetes/pki/etcd/ca.crt
  --cert=/etc/kubernetes/pki/etcd/server.crt
  --key=/etc/kubernetes/pki/etcd/server.key
  --endpoints=https://127.0.0.1:2379'

# 1. raft 状态 (leader / term)
$ETCDCTL endpoint status -w table
$ETCDCTL member list -w table

# 2. MVCC revision
$ETCDCTL endpoint status -w json | jq '.[0].Status.header.revision'

# 3. compact 历史 (释放 logical history)
$ETCDCTL compact $CURRENT_REV

# 4. defrag 物理空间回收
$ETCDCTL defrag --cluster

# 5. snapshot save (灾难恢复前置)
$ETCDCTL snapshot save /var/lib/etcd/snapshot-day2.db
$ETCDCTL snapshot status /var/lib/etcd/snapshot-day2.db -w table

Actual 输出关键:

endpoint status:
| ENDPOINT     | ID    | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
|cp-1:2379     |e4dd...| 12 MB   | false     | 23        | 156162     |
|cp-2:2379     |c144...| 12 MB   | false     | 23        | 156162     |
|cp-3:2379     |953b...| 12 MB   | true      | 23        | 156162     |  ← leader

snapshot:
| HASH     | REVISION | TOTAL KEYS | TOTAL SIZE |
| ae0dc55f | 126876   | 521        | 2.1 MB     |

Why (etcd 5 个核心概念) —

概念一句话
Raftetcd 的分布式一致性算法,leader 接所有写,follower 同步。quorum = N/2+1 (3 节点 quorum=2,容忍 1 故障; 5 节点 quorum=3,容忍 2 故障)
MVCC (Multi-Version Concurrency Control)etcd 不覆盖写,每次写产生新 revision。revision 是 cluster-wide 单调递增 int64,K8s 用它实现 watch / resource version 一致性
Compact删除 revision X 之前的所有历史,释放 logical 空间。不影响磁盘,只是 BoltDB 内部标记为 free
Defrag物理重组 BoltDB 文件,释放 compact 后的 free space。整个 etcd 写 IO 暂停几秒,大集群 1-5 分钟。生产: 错峰跑 + 一次一个 member
Snapshot save在 line consistency 下导出整个 keyspace 到二进制文件,2-10MB 起步,大集群可能几 GB。snapshot restore 时 cluster 必须 down,从 snapshot 重启 3 个新 member

Lesson —

  1. etcd 容忍 N/2 故障: 3 节点 → 容忍 1; 5 节点 → 容忍 2; 7 节点 → 容忍 3。生产默认 3 节点足够,7 节点反而慢(同步 latency 增)
  2. MVCC revision 是全局单调,K8s resourceVersion 直接用它。kubectl get ... -w 用 resourceVersion 做断点续 watch
  3. etcd db 默认上限 2GB (--quota-backend-bytes),超了拒写。大集群必须调到 8GB,同时调高 compact 频率
  4. compact + defrag 是 2 套机制:compact 删 history (logical),defrag 重组文件 (physical)。先 compact 再 defrag 才有用
  5. snapshot save 是冷备,在 leader 上做最快(避免 cross-node 流量)。生产: cron 每天 + 异地存储 (S3/对象存储)
  6. defrag --cluster 串行处理 3 个 member,每次 1-3 秒。单 member defrag 会让该 member 短暂 unresponsive,raft 可能切 leader

Op C: chaos drill (kill etcd / quorum loss / 恢复)

What — 演练 etcd 故障三个阶段。static pod 杀法: mv /etc/kubernetes/manifests/etcd.yaml /root/(kubelet 检测到 manifest 没了,~10s 内停 pod)。恢复: mv 回来。

# 阶段 1: kill cp-1 etcd
ssh m1 'mv /etc/kubernetes/manifests/etcd.yaml /root/etcd-cp1.yaml.bak'

# 阶段 2: 再 kill cp-2 etcd (quorum loss)
ssh m2 'mv /etc/kubernetes/manifests/etcd.yaml /root/etcd-cp2.yaml.bak'

# 阶段 3: 恢复
ssh m1 'mv /root/etcd-cp1.yaml.bak /etc/kubernetes/manifests/etcd.yaml'
ssh m2 'mv /root/etcd-cp2.yaml.bak /etc/kubernetes/manifests/etcd.yaml'

Actual 数据:

阶段etcd upquorumapiserver 行为
0 (baseline)3/3OKkubectl 正常
1 (kill cp-1)2/3OK (2 >= quorum 2)kubectl 仍正常 ✅
2 (kill cp-2)1/3LOSS (1 < 2)kubectl get nodes → Error: etcdserver: request timed out ❌
3 (恢复)3/3OKkubectl 全恢复 + raft term 24 (+1)

Why —

  • 3 节点 etcd raft quorum = 2,kill 1 仍有 leader+1 follower 形成 quorum
  • kill 2 后剩 1,单节点不能形成 quorum(raft 设计:必须多数同意才能 commit),apiserver 读还可能 stale OK,写一定 timeout
  • 恢复后 etcd 自动 catch up(从 leader 拉缺失的 log entries),term 增 1 因为期间没 leader 触发 election

Lesson —

  1. kubeadm + static pod 让"杀 etcd"很简单: 移走 manifest 文件即可,不像 systemd unit 要 stop。面试常问"K8s 静态 Pod 是什么" → kubelet 直接管理的 Pod,不通过 apiserver,manifest 文件在 /etc/kubernetes/manifests/
  2. 3 节点 etcd 是真 HA 起步: 容忍 1 节点失败 + 正常运维(滚动升级一台一台来)。5 节点容忍 2,但同步开销大,不是默认推荐
  3. quorum loss 场景的处理:
    • 先尝试恢复 etcd member (重启 / 修网络 / 加节点)
    • 真的恢复不了 → 从 snapshot restore + 全集群重建 etcd raft cluster
    • 期间 apiserver 写 unavailable,但 worker 节点上的 Pod 继续运行(kubelet 缓存了 spec)
    • 数据面 (Pod 业务流量) 不受 quorum loss 影响,只是 control plane 停摆。面试金句
  4. etcd disaster recovery 完整流程:
    1. snapshot save (在 chaos 之前已经做了)
    2. 集群挂 → 决定从 snapshot restore
    3. 在某节点 etcdctl snapshot restore (生成 new etcd data dir, force-new-cluster)
    4. 改 etcd manifest 指向 new data dir + 单节点 cluster
    5. 启动单节点,验证 apiserver 能连
    6. 加新 etcd member(2nd / 3rd 从 etcd 自动 sync)
  5. K8s 控制面 vs 数据面 解耦: chaos 时数据面 (业务 Pod) 仍跑,这是 K8s 设计的精髓。节点级 kubelet 本地有 Pod spec cache,不依赖 etcd 也能维持

Day 2 — 阶段总结

✅ apiserver static pod 启用 audit (Metadata + Secret RequestResponse 级别) ✅ etcd 内核 5 概念都跑了真实命令 (raft / MVCC / compact / defrag / snapshot) ✅ snapshot save 2.1MB 521 keys 备份完成 ✅ chaos 三阶段 drill (1/3 down OK, 2/3 down quorum loss, 恢复 term +1) ✅ K8s 数据面 vs 控制面 解耦概念真实验证


🏆 Day 1 + Day 2 完成

5 节点 K8s 集群 + 完整生产姿势,所有踩坑面试金矿都进 MD。

在 GitHub 上编辑此页
Prev
Day 1:3 CP HA 集群 + CNI 选型 + DNS 调优
Next
Day 3: CRD + Operator (kubebuilder 从 0 写)