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 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
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 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub

kubeadm —— K8s 集群引导工具

一句话定义

kubeadm 不是 K8s 的"管理工具",而是集群安装工具:把一堆裸机/虚拟机变成可用的 K8s 集群。装完之后 kubeadm 就退场了,日常管理用 kubectl。

典型场景

训练营 Day1 用 kubeadm 做完整 K8s HA 集群(3 控制面 + 2 worker)。后续也用它:

  • Day1:kubeadm init 起第一个控制面
  • Day1:kubeadm join 把另外 4 个节点加进来
  • Day2:kubeadm token create 重新生成 join token
  • Day12:kubeadm certs renew all 续证书(默认有效期 1 年)
  • Day14:kubeadm upgrade 升级集群版本
  • 故障:kubeadm reset 把节点恢复到加群前状态

kubeadm 做的事 / 不做的事

✅ kubeadm 做

  • 装控制面:apiserver、controller-manager、scheduler、etcd(静态 pod 形式)
  • 生成 PKI(一整套 TLS 证书)
  • 配置 kubelet
  • 生成 admin.conf(管理员 kubeconfig)
  • 设置网络 / kube-proxy 基础

❌ kubeadm 不做

  • 不装 CNI 网络插件(Calico / Cilium / Flannel 要你自己 apply)
  • 不装 metrics-server、dashboard、ingress
  • 不管节点 OS(hostname、防火墙、swap、内核模块等要你自己搞定,Day0 干的)
  • 不管 high-availability load balancer(HA 控制面前面那个 VIP / HAProxy)

kubeadm 是"集群骨架",不是"开箱即用的产品"。骨架装完上面还要叠很多东西。


init —— 起第一个控制面

最小命令:

kubeadm init \
  --pod-network-cidr=10.244.0.0/16 \
  --service-cidr=10.96.0.0/12 \
  --apiserver-advertise-address=10.0.24.28
参数含义
--pod-network-cidrpod 用的 IP 段(CNI 决定,常见 10.244.0.0/16)
--service-cidrservice ClusterIP 段(默认 10.96.0.0/12,一般不动)
--apiserver-advertise-addressapiserver 监听的 IP(多网卡时必须明确)
--control-plane-endpointHA 用:VIP / 域名
--upload-certsHA 用:把控制面证书上传到 secret 供其它 cp 拉

跑完之后的输出

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run:
  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 10.0.24.28:6443 --token abc.def... \
    --discovery-token-ca-cert-hash sha256:...

You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:

  kubeadm join 10.0.24.28:6443 --token abc.def... \
    --discovery-token-ca-cert-hash sha256:... \
    --control-plane --certificate-key xxxx

这段输出存下来:里面有 worker join token 和 control-plane join 命令。后面要用。

init 之后必做:装 CNI

集群起来但 CoreDNS 一直 Pending。因为没 CNI。

# Cilium(推荐)
helm install cilium cilium/cilium -n kube-system

# 或 Calico
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27/manifests/calico.yaml

CNI 起来后 CoreDNS 才能跑、节点才会变 Ready。

init 之后做:admin.conf 拷贝

mkdir -p $HOME/.kube
cp /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

或者直接:

export KUBECONFIG=/etc/kubernetes/admin.conf

/etc/kubernetes/admin.conf 是 cluster-admin 凭证 —— 能干一切,千万别泄漏。


HA 控制面:--control-plane-endpoint

3 控制面 HA 模式:

# 第 1 个 cp 节点
kubeadm init \
  --control-plane-endpoint "k8s-api.local:6443" \    # ← VIP / 负载均衡 / 域名
  --upload-certs \                                     # ← 把证书上传到 secret
  --pod-network-cidr=10.244.0.0/16

--control-plane-endpoint 是关键:

  • 写VIP 或 LB 域名,不是某台机器的 IP
  • 所有 kubeconfig / 节点配置里 apiserver 都指向这个 endpoint
  • 第一个 cp 挂了,VIP 切到另一个 cp、其它节点无感

--upload-certs 把 PKI 上传到 kube-system 命名空间的 secret(24 小时有效),后续 cp 节点 join 时能下载。

其它 2 个 cp 节点加入

kubeadm join k8s-api.local:6443 \
  --token abc.def... \
  --discovery-token-ca-cert-hash sha256:... \
  --control-plane \                                    # ← 关键:作为控制面加入
  --certificate-key xxxx                                # ← upload-certs 给的 key

worker 节点加入

kubeadm join k8s-api.local:6443 \
  --token abc.def... \
  --discovery-token-ca-cert-hash sha256:...

不带 --control-plane 就是 worker。

VIP 怎么搞

kubeadm 不提供 VIP,要你自己:

  • 物理硬件:F5 / 硬件 LB
  • 云:cloud load balancer(AWS NLB、阿里云 SLB)
  • 自建:kube-vip、keepalived + haproxy

训练营 Day1 用 kube-vip:3 个控制面之间选举一个持有 VIP,挂了自动 failover。


token 管理

看现有 token

kubeadm token list
# TOKEN          TTL         EXPIRES               USAGES
# abc.def...     23h         2026-05-28T13:23:00   authentication,signing

默认 token TTL 24 小时。过了就 join 不了新节点。

重新生成

kubeadm token create
# new.token.value...

kubeadm token create --print-join-command
# kubeadm join 10.0.24.28:6443 --token ... --discovery-token-ca-cert-hash sha256:...

--print-join-command 直接生成可以复制粘贴的 join 命令,强烈推荐用这个。

永久 token(不要在生产用)

kubeadm token create --ttl=0
# 0 = 永不过期;只在实验环境用

删 token

kubeadm token delete abc.def...

证书续期:certs renew

kubeadm 集群默认所有证书 1 年有效(除了 etcd CA 是 10 年)。过期的话整个集群挂。

看证书状态

kubeadm certs check-expiration

# CERTIFICATE                EXPIRES                  RESIDUAL TIME
# admin.conf                 May 27, 2027 10:00 UTC   364d
# apiserver                  May 27, 2027 10:00 UTC   364d
# apiserver-etcd-client      May 27, 2027 10:00 UTC   364d
# apiserver-kubelet-client   May 27, 2027 10:00 UTC   364d
# controller-manager.conf    May 27, 2027 10:00 UTC   364d
# etcd-healthcheck-client    May 27, 2027 10:00 UTC   364d
# etcd-peer                  May 27, 2027 10:00 UTC   364d
# etcd-server                May 27, 2027 10:00 UTC   364d
# front-proxy-client         May 27, 2027 10:00 UTC   364d
# scheduler.conf             May 27, 2027 10:00 UTC   364d

生产至少每半年跑一次 check。

续期

kubeadm certs renew all                              # 续所有
kubeadm certs renew apiserver                        # 续单个

# 续完要重启控制面 pod 让新证书生效
systemctl restart kubelet                            # kubelet 会重建静态 pod

# 或者手动重启容器
crictl ps | grep -E "kube-apiserver|controller-manager|scheduler" \
  | awk '{print $1}' | xargs -r crictl stop
# kubelet 自动拉起新的,加载新证书

CKA / CKS 必考题。Day12 演练。

自动续期:kubelet RotateCertificates

kubelet 自己的证书可以自动续:

# /var/lib/kubelet/config.yaml
rotateCertificates: true
serverTLSBootstrap: true

控制面证书自动续:kubeadm upgrade 时会续。


reset —— 把节点拆干净

kubeadm reset
# 提示输入 y 确认;删 manifests、etcd、kubelet 配置等

kubeadm reset -f                # 不提示

reset 只删 kubeadm 创建的东西。要彻底清干净:

kubeadm reset -f

# 清 CNI 残留
rm -rf /etc/cni/net.d
ip link delete cni0 2>/dev/null
ip link delete flannel.1 2>/dev/null
ip link delete cilium_* 2>/dev/null

# 清 iptables / ipvs
iptables -F && iptables -X
iptables -t nat -F && iptables -t nat -X
iptables -t mangle -F && iptables -t mangle -X
ipvsadm -C 2>/dev/null

# 清 kubelet 残留状态
rm -rf /var/lib/cni/
rm -rf /var/lib/kubelet/
rm -rf /etc/kubernetes/
rm -rf $HOME/.kube/

Day1 init 失败了排错时常做这个全套,否则一堆残留状态混进新集群。


upgrade —— 升集群版本

整体流程(详见 Day14):

# 第 1 步:升 kubeadm 包本身(每个节点)
apt-mark unhold kubeadm
apt-get install -y kubeadm=1.29.3-1.1
apt-mark hold kubeadm

# 第 2 步:在第一个 cp 节点看升级计划
kubeadm upgrade plan
# 显示能升到哪个版本

# 第 3 步:在第一个 cp 节点真升
kubeadm upgrade apply v1.29.3

# 第 4 步:其它 cp 节点
kubeadm upgrade node

# 第 5 步:升 kubelet(每个节点)
apt-mark unhold kubelet kubectl
apt-get install -y kubelet=1.29.3-1.1 kubectl=1.29.3-1.1
apt-mark hold kubelet kubectl
systemctl daemon-reload && systemctl restart kubelet

# 第 6 步:worker 节点
kubeadm upgrade node                     # 在 worker 上跑
# 然后同样升 kubelet

严格规则:

  • 一次只升一个 minor 版本(1.28 → 1.29,不能直接 1.28 → 1.30)
  • 控制面必须比 worker 不低于一个 minor(control plane 永远 ≥ worker)
  • 升级前先备份 etcd(详见 etcdctl.md)

init 之后的健康检查 checklist

# 1. 节点 Ready
kubectl get nodes
# m1   Ready    control-plane   ...

# 2. 控制面静态 pod
kubectl get pods -n kube-system
# kube-apiserver-m1, kube-controller-manager-m1, kube-scheduler-m1, etcd-m1, kube-proxy-xxx, coredns-xxx

# 3. etcd 健康
kubectl exec -n kube-system etcd-m1 -- etcdctl \
  --cacert /etc/kubernetes/pki/etcd/ca.crt \
  --cert /etc/kubernetes/pki/etcd/server.crt \
  --key /etc/kubernetes/pki/etcd/server.key \
  endpoint health

# 4. 证书 OK
kubeadm certs check-expiration

# 5. CNI 起来(CoreDNS Running,不是 Pending)
kubectl get pod -n kube-system -l k8s-app=kube-dns

静态 pod manifest 位置

kubeadm 把控制面装成静态 pod(kubelet 直接管,不经 apiserver):

/etc/kubernetes/manifests/
├── etcd.yaml
├── kube-apiserver.yaml
├── kube-controller-manager.yaml
└── kube-scheduler.yaml

改这里的 yaml → kubelet 自动重启对应 pod。

举个例子:apiserver 加个 admission plugin:

vim /etc/kubernetes/manifests/kube-apiserver.yaml
# 改 --enable-admission-plugins
# 保存退出 → 几秒后 apiserver 自动重启加载新参数

重大陷阱:写错了 yaml → kubelet 起不来 apiserver → 控制面挂 → kubectl 不能用。修法:物理 console 登节点、改回 yaml、kubelet 自动恢复。

训练营 Day3 / Day4 经常改这些 yaml。改前 backup:cp /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/kas.yaml.bak。


常见踩坑

坑 1:init 失败,常见原因

[ERROR Swap]: running with swap on is not supported. Please disable swap
[ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: ...
[ERROR CRI]: container runtime is not running

修:

# 关 swap
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab

# 内核模块 / 参数
modprobe br_netfilter
echo "br_netfilter" > /etc/modules-load.d/k8s.conf
cat > /etc/sysctl.d/k8s.conf <<'EOF'
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system

# containerd 起来
systemctl enable --now containerd
crictl info     # 验证

坑 2:CRI 配置不对,kubelet 起不来

containerd 装完默认配置可能不工作。生成默认配置 + 改 cgroup driver:

mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
# 改 SystemdCgroup = true
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
systemctl restart containerd

K8s 1.22+ 强制 cgroup driver = systemd。

坑 3:join 之后节点 NotReady

NAME   STATUS     ROLES    AGE   VERSION
m4     NotReady   <none>   1m    v1.28.0

99% 是 CNI 没装。看 kubelet 日志:

journalctl -u kubelet -n 50 | grep -i 'network\|cni'
# cni plugin not initialized

装 CNI:

kubectl apply -f https://...calico.yaml
# 几十秒后节点变 Ready

坑 4:第二台 cp join 报"discovery-token-ca-cert-hash 错误"

token 过期了。在 cp1 重新生成:

kubeadm token create --print-join-command
# 拿到新的 join 命令

# 如果是 cp 加入,还要新 cert key
kubeadm init phase upload-certs --upload-certs
# 给你新的 certificate-key

# 拼成完整命令
kubeadm join ... --token <new> --discovery-token-ca-cert-hash <new> \
  --control-plane --certificate-key <new>

坑 5:reset 之后再 join 报"already exists"

reset 没清干净 iptables / CNI 残留。见上面"reset 清理脚本"。

坑 6:以为可以跳版本升级

kubeadm upgrade apply v1.30.0    # 当前 v1.28.x
# 报错:can only upgrade by one minor version

必须 1.28 → 1.29 → 1.30 一步一步。

坑 7:证书续完不重启控制面

kubeadm certs renew all
# 续完了,但 apiserver 还在用内存里旧证书
kubectl get nodes
# x509: certificate has expired

续完必须重启控制面 pod。改 manifest 时间戳 + kubelet 会自动重启:

touch /etc/kubernetes/manifests/kube-apiserver.yaml
# 或干脆
systemctl restart kubelet

坑 8:init 时 --apiserver-advertise-address 没指定,挑了错的网卡

多网卡机器(公网 IP + 内网 IP)kubeadm 可能选公网 IP 作 advertise,集群内通信不通。

多网卡必须显式指定内网 IP:

kubeadm init --apiserver-advertise-address=10.0.24.28 ...

关联命令

  • kubectl —— 集群装完之后日常用
  • crictl —— kubelet 找不到镜像 / 容器没起时排错
  • etcdctl —— 备份 etcd、升级前必做
  • systemctl —— 管 kubelet 服务
  • journalctl —— 看 kubelet / containerd 日志
在 GitHub 上编辑此页