1.4. 集群部署
这一章把「装集群」拆成可验证的四步:装包、初始化控制平面、安装 CNI、加入工作节点。仓库提供了 Ansible 版本,我们也给出等价的手工命令,方便你理解每一步到底改了什么。
- 层级:
L1 · 入门
- 难度:
入门
- 预计:
40 分钟
- 前置:
环境与工具
1.4.1. 你将学到
仓库
ansible-k8s-install的完整使用流程kubeadm 初始化时每个关键参数的作用
Flannel / Calico / Cilium 三种 CNI 的安装差异
初始化后必须完成的 8 项验收
集群重置与常见初始化失败的排查
1.4.2. 部署方式
方式 |
适合 |
优点 |
代价 |
|---|---|---|---|
Ansible playbook |
重复搭建、多节点 |
一条命令完成 |
需要理解 inventory |
手工 kubeadm |
第一次学习、排错 |
每一步可见 |
命令较多 |
kind / minikube |
本地体验 |
最快 |
无法模拟真实节点 |
本章先讲 Ansible,再给出手工对照。两种方式不要混用:Ansible 会执行 kubeadm reset -f,把已有集群清掉。
1.4.3. 方式一:Ansible 一键部署
1.4.3.1. 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
1.4.3.2. 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] 段。
1.4.3.3. 3. 安装基础组件
chmod +x cluster-install.sh
./cluster-install.sh
这一步会:
安装 Ansible;
生成
/etc/ansible/hosts;执行
install-kubeadm.yaml,在所有节点安装 containerd、kubeadm、kubelet、kubectl,并完成系统预配置。
执行完后先不要急着初始化,检查一遍:
ansible all -m shell -a 'kubeadm version -o short; systemctl is-active containerd'
预期每台节点都输出版本号与 active。
1.4.3.4. 4. 初始化控制平面并安装 CNI
仓库为三种 CNI 各准备了一个 playbook,只选一个执行:
1.4.3.4.1. Flannel
ansible-playbook install-k8s-flannel.yaml
默认使用 VXLAN 隧道;可在 playbook 的 vars 中调整:
k8s_version: "v1.31.0"
pod_cidr: "10.244.0.0/16"
service_cidr: "10.96.0.0/12"
mode: "tunneling" # tunneling / routing
tunnel_protocol: "vxlan"
vxlan_directrouting: "false"
image_repo: "registry.aliyuncs.com/google_containers"
1.4.3.4.2. Calico
ansible-playbook install-k8s-calico.yaml
Calico 支持三种组合:
mode |
tunnel_protocol |
效果 |
|---|---|---|
tunneling |
VXLAN |
VXLAN 隧道,通用性最好 |
tunneling |
IPIP |
IPIP 隧道,部分云网络更友好 |
routing |
IPIP |
BGP 路由 + 跨子网 IPIP |
关键变量:
k8s_version: "v1.31.0"
pod_cidr: "10.244.0.0/16"
pod_cidr_block_size: "24"
service_cidr: "10.96.0.0/12"
mode: "tunneling"
tunnel_protocol: "IPIP"
image_repo: "registry.aliyuncs.com/google_containers"
1.4.3.4.3. Cilium
ansible-playbook install-k8s-cilium.yaml
Cilium 默认使用 VXLAN,并可替换 kube-proxy。若使用 kube-proxy replacement,初始化时必须加:
--skip-phases=addon/kube-proxy
Cilium 的详细模式选择见 CNI 网络。
1.4.3.5. 5. 重启并验收
ansible-playbook reboot-system.yaml
等待 1–2 分钟,然后在 master01 上:
kubectl get nodes -o wide
kubectl get pods -n kube-system
预期:
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
1.4.4. 方式二:手工 kubeadm 对照
如果你想理解 Ansible 做了什么,可以在 master01 上按下面顺序执行。
1.4.4.1. 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
参数说明:
参数 |
作用 |
注意 |
|---|---|---|
|
控制平面统一入口 |
后续加 master 必须一致 |
|
API Server 对外地址 |
多网卡时务必指定 |
|
Pod 网段 |
必须与 CNI 配置一致 |
|
Service 网段 |
不要与节点网段重叠 |
|
镜像仓库 |
国内环境常用阿里云 |
|
上传证书供其他 master 使用 |
单 master 可省略 |
成功后会输出三件事,务必保存:
kubeadm join ... --token ...(工作节点加入)kubeadm join ... --control-plane ... --certificate-key ...(控制平面加入)kubectl配置命令
1.4.4.2. 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,这是正常的。
1.4.4.3. 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。
1.4.4.4. 4. 加入工作节点
在每台 worker 上执行 init 输出的 join 命令:
sudo kubeadm join k8s-master01.magedu.com:6443 \
--token <token> \
--discovery-token-ca-cert-hash sha256:<hash>
Token 默认 24 小时过期。过期后重新生成:
kubeadm token create --print-join-command
1.4.5. 初始化后的 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>
1.4.6. 部署后的必要附件
集群可用后,按需安装:
MetalLB:为 LoadBalancer Service 提供地址
ingress-nginx:七层入口
StorageClass:OpenEBS 或 NFS CSI
metrics-server:
kubectl top与 HPAPrometheus:监控
Kuboard:可视化面板
1.4.7. 重置集群
实验环境建议保留重置脚本,随时推倒重来:
ansible-playbook reset-kubeadm.yaml
手工重置:
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 已备份,且节点已从负载均衡中摘除。
1.4.8. 常见问题
现象 |
原因 |
处理 |
|---|---|---|
|
kubelet 起不来 / cgroup 配置错 |
|
节点 |
CNI 未装或 Pod CIDR 不匹配 |
检查 CNI Pod 日志与 |
CoreDNS |
CNI 未就绪 |
等 CNI Running,或检查污点 |
|
token 默认 24h |
|
加入后节点名重复 |
主机名相同 |
修改 |
|
API Server 未起 / 防火墙 |
|
Calico Pod |
Pod CIDR 与 calico 配置冲突 |
修改 |
多网卡选错地址 |
kubelet 用了错误 IP |
指定 |
1.4.9. 进阶挑战
用
kubeadm config print init-defaults生成配置文件,改用配置文件方式初始化。增加第二个 control-plane 节点,验证
--control-planejoin 与证书上传。把 CNI 从 Flannel 换成 Calico,记录需要清理哪些残留(CNI 配置、路由、iptables)。
用
kubeadm certs check-expiration查看证书有效期,规划升级。
1.4.10. 小结
Ansible 负责重复性,kubeadm 负责控制平面;理解 kubeadm 参数比记住 playbook 更重要。
CNI 必须与
--pod-network-cidr一致,这是最常见的「节点 NotReady」原因。部署完成不等于可用,8 项验收至少跑一遍。