集群部署¶
这一章把「装集群」拆成可验证的四步:装包、初始化控制平面、安装 CNI、加入工作节点。仓库提供了 Ansible 版本,我们也给出等价的手工命令,方便你理解每一步到底改了什么。
你将学到¶
- 仓库
ansible-k8s-install的完整使用流程 - kubeadm 初始化时每个关键参数的作用
- Flannel / Calico / Cilium 三种 CNI 的安装差异
- 初始化后必须完成的 8 项验收
- 集群重置与常见初始化失败的排查
部署方式¶
| 方式 | 适合 | 优点 | 代价 |
|---|---|---|---|
| Ansible playbook | 重复搭建、多节点 | 一条命令完成 | 需要理解 inventory |
| 手工 kubeadm | 第一次学习、排错 | 每一步可见 | 命令较多 |
| kind / minikube | 本地体验 | 最快 | 无法模拟真实节点 |
本章先讲 Ansible,再给出手工对照。两种方式不要混用:Ansible 会执行 kubeadm reset -f,把已有集群清掉。
方式一:Ansible 一键部署¶
1. 准备控制机¶
在 master01 或一台能 SSH 到所有节点的机器上:
sudo apt-get update
sudo apt-get install -y git ansible
git clone https://github.com/iKubernetes/learning-k8s.git
cd learning-k8s/ansible-k8s-install
确认控制机能免密 SSH 到四台节点:
for ip in 192.168.10.6 192.168.10.11 192.168.10.12 192.168.10.13; do
ssh -o BatchMode=yes "$ip" 'hostname' || echo "FAILED: $ip"
done
2. 修改节点地址¶
编辑 cluster-install.sh 顶部的四个变量:
MASTER_IP='192.168.10.6'
NODE_01_IP='192.168.10.11'
NODE_02_IP='192.168.10.12'
NODE_03_IP='192.168.10.13'
脚本会追加 inventory
cluster-install.sh 使用 cat >> /etc/ansible/hosts 追加主机记录。重复执行会产生重复条目。第二次执行前,先清理 /etc/ansible/hosts 中旧的 [master] / [nodes] 段。
3. 安装基础组件¶
这一步会:
- 安装 Ansible;
- 生成
/etc/ansible/hosts; - 执行
install-kubeadm.yaml,在所有节点安装 containerd、kubeadm、kubelet、kubectl,并完成系统预配置。
执行完后先不要急着初始化,检查一遍:
预期每台节点都输出版本号与 active。
4. 初始化控制平面并安装 CNI¶
仓库为三种 CNI 各准备了一个 playbook,只选一个执行:
默认使用 VXLAN 隧道;可在 playbook 的 vars 中调整:
Calico 支持三种组合:
| mode | tunnel_protocol | 效果 |
|---|---|---|
| tunneling | VXLAN | VXLAN 隧道,通用性最好 |
| tunneling | IPIP | IPIP 隧道,部分云网络更友好 |
| routing | IPIP | BGP 路由 + 跨子网 IPIP |
关键变量:
Cilium 默认使用 VXLAN,并可替换 kube-proxy。若使用 kube-proxy replacement,初始化时必须加:
Cilium 的详细模式选择见 CNI 网络。
5. 重启并验收¶
等待 1–2 分钟,然后在 master01 上:
预期:
NAME STATUS ROLES AGE VERSION
k8s-master01.magedu.com Ready control-plane 66s v1.31.0
k8s-node01.magedu.com Ready <none> 52s v1.31.0
k8s-node02.magedu.com Ready <none> 52s v1.31.0
k8s-node03.magedu.com Ready <none> 52s v1.31.0
方式二:手工 kubeadm 对照¶
如果你想理解 Ansible 做了什么,可以在 master01 上按下面顺序执行。
1. 初始化控制平面¶
sudo kubeadm init \
--control-plane-endpoint=k8s-master01.magedu.com \
--apiserver-advertise-address=192.168.10.6 \
--kubernetes-version=v1.31.0 \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/12 \
--image-repository=registry.aliyuncs.com/google_containers \
--upload-certs
参数说明:
| 参数 | 作用 | 注意 |
|---|---|---|
--control-plane-endpoint |
控制平面统一入口 | 后续加 master 必须一致 |
--apiserver-advertise-address |
API Server 对外地址 | 多网卡时务必指定 |
--pod-network-cidr |
Pod 网段 | 必须与 CNI 配置一致 |
--service-cidr |
Service 网段 | 不要与节点网段重叠 |
--image-repository |
镜像仓库 | 国内环境常用阿里云 |
--upload-certs |
上传证书供其他 master 使用 | 单 master 可省略 |
成功后会输出三件事,务必保存:
kubeadm join ... --token ...(工作节点加入)kubeadm join ... --control-plane ... --certificate-key ...(控制平面加入)kubectl配置命令
2. 配置 kubectl¶
mkdir -p "$HOME/.kube"
sudo cp /etc/kubernetes/admin.conf "$HOME/.kube/config"
sudo chown "$(id -u):$(id -g)" "$HOME/.kube/config"
kubectl get nodes
此时节点是 NotReady,因为还没有 CNI,这是正常的。
3. 安装 CNI¶
以 Calico 为例:
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.0/manifests/calico.yaml
如果 Pod CIDR 不是 192.168.0.0/16,先下载文件并修改 CALICO_IPV4POOL_CIDR,再 apply。
4. 加入工作节点¶
在每台 worker 上执行 init 输出的 join 命令:
sudo kubeadm join k8s-master01.magedu.com:6443 \
--token <token> \
--discovery-token-ca-cert-hash sha256:<hash>
Token 默认 24 小时过期。过期后重新生成:
初始化后的 8 项验收¶
不要只看 kubectl get nodes。逐项确认:
# 1. 节点状态
kubectl get nodes -o wide
# 2. 系统组件
kubectl get pods -n kube-system -o wide
# 3. CoreDNS 是否就绪
kubectl get deploy -n kube-system coredns
# 4. CNI Pod
kubectl get pods -n kube-system | grep -E 'calico|cilium|flannel'
# 5. 集群信息
kubectl cluster-info
# 6. 组件健康
kubectl get --raw='/readyz?verbose'
# 7. DNS 解析
kubectl run dnstest --image=busybox:1.36 --rm -it --restart=Never -- \
nslookup kubernetes.default
# 8. 跨节点 Pod 网络
kubectl create deploy nettest --image=nginx:1.27 --replicas=4
kubectl get pods -o wide
跨节点验证:
# 在一个 Pod 里访问另一个节点上的 Pod IP
kubectl run client --image=busybox:1.36 --rm -it --restart=Never -- \
wget -qO- --timeout=3 http://<另一个节点的PodIP>
部署后的必要附件¶
集群可用后,按需安装:
- MetalLB:为 LoadBalancer Service 提供地址
- ingress-nginx:七层入口
- StorageClass:OpenEBS 或 NFS CSI
- metrics-server:
kubectl top与 HPA - Prometheus:监控
- Kuboard:可视化面板
重置集群¶
实验环境建议保留重置脚本,随时推倒重来:
手工重置:
sudo kubeadm reset -f
sudo rm -rf /etc/cni/net.d /var/lib/cni /var/lib/kubelet /var/lib/etcd
sudo rm -rf "$HOME/.kube"
sudo reboot
reset 会删除数据
kubeadm reset 会移除本地 etcd 数据与 kubelet 状态。生产环境执行前必须确认 etcd 已备份,且节点已从负载均衡中摘除。
常见问题¶
| 现象 | 原因 | 处理 |
|---|---|---|
init 卡在 waiting for kubelet |
kubelet 起不来 / cgroup 配置错 | journalctl -u kubelet -n 100 |
节点 NotReady |
CNI 未装或 Pod CIDR 不匹配 | 检查 CNI Pod 日志与 podCIDR |
CoreDNS Pending |
CNI 未就绪 | 等 CNI Running,或检查污点 |
join 报 token 过期 |
token 默认 24h | kubeadm token create --print-join-command |
| 加入后节点名重复 | 主机名相同 | 修改 /etc/hostname 并重启 kubelet |
kubectl 连不上 6443 |
API Server 未起 / 防火墙 | crictl ps、ss -lntp、检查证书 |
Calico Pod CrashLoop |
Pod CIDR 与 calico 配置冲突 | 修改 CALICO_IPV4POOL_CIDR 后重装 |
| 多网卡选错地址 | kubelet 用了错误 IP | 指定 --node-ip 并重启 kubelet |
进阶挑战¶
- 用
kubeadm config print init-defaults生成配置文件,改用配置文件方式初始化。 - 增加第二个 control-plane 节点,验证
--control-planejoin 与证书上传。 - 把 CNI 从 Flannel 换成 Calico,记录需要清理哪些残留(CNI 配置、路由、iptables)。
- 用
kubeadm certs check-expiration查看证书有效期,规划升级。
小结¶
- Ansible 负责重复性,kubeadm 负责控制平面;理解 kubeadm 参数比记住 playbook 更重要。
- CNI 必须与
--pod-network-cidr一致,这是最常见的「节点 NotReady」原因。 - 部署完成不等于可用,8 项验收至少跑一遍。