K8s集群部署实验笔记:4节点Kubernetes v1.32.13 + Calico v3.29.3
实验日期 :2026年5月23日
环境 : 4台ECS (Ubuntu 24.04.4 LTS)
目标:使用kubeadm部署生产级Kubernetes集群 (1 Master + 3 Worker)
一、架构概览
┌─────────────────────────────────────────────────────────┐
│ K8s Cluster (v1.32.13) │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Control Plane Node │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │kube-apiser│ │kube-contr│ │kube-sched│ │ │
│ │ │ ver │ │oller-mgr │ │uler │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ ┌──────────┐ ┌──────────────────────┐ │ │
│ │ │ etcd │ │ kubelet + kube-proxy│ │ │
│ │ └──────────┘ └──────────────────────┘ │ │
│ │ 192.168.0.61 (ecs-dd92-26db-0003) │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Worker #1 │ │ Worker #2 │ │ Worker #3 │ │
│ │ kubelet │ │ kubelet │ │ kubelet │ │
│ │ kube-proxy │ │ kube-proxy │ │ kube-proxy │ │
│ │ containerd │ │ containerd │ │ containerd │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ 192.168.0.23 192.168.0.47 192.168.0.119 │
└─────────────────────────────────────────────────────────┘
网络插件: Calico v3.29.3 (BGP模式)
Pod CIDR: 10.244.0.0/16
Service CIDR: 10.96.0.0/12
容器运行时: containerd v2.2.4
二、环境规划
2.1 服务器信息
| 节点 | 角色 | 公网IP | 私有IP | 主机名 | OS |
|---|---|---|---|---|---|
| Master | Control Plane | 27.106.96.55 | 192.168.0.61 | ecs-dd92-26db-0003 | Ubuntu 24.04.4 |
| Worker1 | Worker | 190.92.235.156 | 192.168.0.23 | ecs-dd92-26db-0002 | Ubuntu 24.04.4 |
| Worker2 | Worker | 119.13.124.119 | 192.168.0.47 | ecs-dd92 | Ubuntu 24.04.4 |
| Worker3 | Worker | 159.138.140.194 | 192.168.0.119 | ecs-dd92-26db-0001 | Ubuntu 24.04.4 |
2.2 软件版本
| 组件 | 版本 | 说明 |
|---|---|---|
| Kubernetes | v1.32.13 | 使用阿里云镜像仓库安装 |
| containerd | v2.2.4 | Docker官方APT源安装 |
| Calico | v3.29.3 | CNI网络插件 (BGP模式) |
| Ubuntu | 24.04.4 LTS | Kernel 6.8.0-106-generic |
2.3 网络规划
| 参数 | 值 | 说明 |
|---|---|---|
| Pod CIDR | 10.244.0.0/16 | --pod-network-cidr,Calico默认CIDR |
| Service CIDR | 10.96.0.0/12 | --service-cidr |
| API Server | 192.168.0.61:6443 | --apiserver-advertise-address |
| DNS IP | 10.96.0.10 | kube-dns Service自动分配 |
三、部署步骤
步骤1:配置/etc/hosts和关闭Swap
目的:确保各节点通过主机名互相解析,关闭Swap满足kubelet硬性要求。
bash
# === 所有节点执行 ===
# 1.1 配置hosts(让节点互相识别)
cat >> /etc/hosts << EOF
192.168.0.61 ecs-dd92-26db-0003
192.168.0.23 ecs-dd92-26db-0002
192.168.0.47 ecs-dd92
192.168.0.119 ecs-dd92-26db-0001
EOF
# 1.2 关闭Swap(kubelet强制要求)
swapoff -a # 临时关闭
sed -i '/swap/s/^/#/' /etc/fstab # 永久关闭(注释fstab中swap行)
命令解释:
swapoff -a:立即禁用所有swap设备。Kubernetes要求关闭swap以确保Pod QoS和资源隔离sed -i '/swap/s/^/#/' /etc/fstab:将fstab中含有swap的行前加#注释,防止重启后swap重新挂载
步骤2:加载内核模块和配置内核参数
目的:加载overlay和br_netfilter模块,配置iptables转发规则。
bash
# === 所有节点执行 ===
# 2.1 加载内核模块
cat > /etc/modules-load.d/k8s.conf << EOF
overlay
br_netfilter
EOF
modprobe overlay # 立即加载overlay模块(容器存储驱动)
modprobe br_netfilter # 立即加载bridge网络过滤模块
# 2.2 配置内核参数
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-iptables = 1 # 桥接流量经过iptables
net.bridge.bridge-nf-call-ip6tables = 1 # 桥接IPv6流量经过iptables
net.ipv4.ip_forward = 1 # 启用IP转发(Pod间通信必须)
EOF
sysctl --system # 立即应用所有sysctl配置
命令解释:
- overlay:OverlayFS内核模块,containerd使用overlay作为存储驱动实现容器镜像分层
- br_netfilter:启用bridge设备的netfilter钩子,使iptables能处理桥接流量
net.bridge.bridge-nf-call-iptables=1:K8s网络关键参数。Pod网络基于bridge,此参数确保iptables规则对桥接流量生效net.ipv4.ip_forward=1:IP转发。node作为Pod网关需要转发跨Pod流量
步骤3:安装containerd容器运行时
目的:安装containerd作为Kubernetes CRI(Container Runtime Interface)实现。
bash
# === 所有节点执行 ===
# 3.1 安装containerd(使用Docker官方APT源)
apt-get update
apt-get install -y containerd.io=2.2.4-1
# 3.2 生成默认配置文件
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
# 3.3 关键配置修改:启用SystemdCgroup
# 找到 [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
# 修改 SystemdCgroup = true
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
# 3.4 配置docker.io镜像加速器(国内环境必备)
cat >> /etc/containerd/config.toml << 'EOF'
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://docker.mirrors.ustc.edu.cn", "https://hub-mirror.c.163.com"]
EOF
# 3.5 重启containerd
systemctl restart containerd
systemctl enable containerd
命令解释:
- containerd v2.2.4:Docker官方发布的稳定CRI实现,与K8s 1.32.x兼容
- SystemdCgroup = true :关键配置!将cgroup驱动改为systemd,与kubelet默认驱动一致。如果cgroup驱动不一致会导致kubelet启动失败
- 镜像加速器:国内Docker Hub访问受限,中科大和网易镜像加速器提供国内镜像
containerd config default:生成完整默认配置作为起点,然后只修改必要参数
步骤4:安装Kubernetes核心组件
目的:安装kubeadm、kubelet、kubectl三件套。
bash
# === 所有节点执行 ===
# 4.1 添加Kubernetes APT源(使用阿里云镜像)
apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.32/deb/ /' > /etc/apt/sources.list.d/kubernetes.list
# 4.2 安装kubeadm/kubelet/kubectl(锁定版本v1.32.13)
apt-get update
apt-get install -y kubeadm=1.32.13-1.1 kubelet=1.32.13-1.1 kubectl=1.32.13-1.1
apt-mark hold kubeadm kubelet kubectl # 防止apt upgrade自动升级
# 4.3 启用kubelet(但还未初始化,无法启动)
systemctl enable kubelet
命令解释:
- kubeadm :集群初始化和管理工具。
kubeadm init初始化Master,kubeadm join添加Worker - kubelet:每个节点上的Kubernetes代理,负责Pod生命周期管理。它是唯一不以容器运行的K8s组件
- kubectl:命令行管理工具,与API Server通信
- apt-mark hold:锁定版本。K8s升级必须遵循版本偏差策略,自动升级可能导致集群故障
- 阿里云APT源:避免google官方源在国内无法访问
步骤5:初始化Master节点
目的:使用kubeadm init初始化集群控制平面。
bash
# === Master节点执行 (192.168.0.61) ===
# 5.1 预拉取控制平面镜像(使用阿里云镜像仓库)
kubeadm config images pull \
--image-repository=registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.32.13
# 5.2 初始化集群
kubeadm init \
--apiserver-advertise-address=192.168.0.61 \ # API Server绑定地址
--pod-network-cidr=10.244.0.0/16 \ # Pod网络CIDR (Calico默认)
--service-cidr=10.96.0.0/12 \ # Service网络CIDR
--image-repository=registry.aliyuncs.com/google_containers \ # 阿里云镜像
--kubernetes-version=v1.32.13 \ # 指定版本
--cri-socket=unix:///var/run/containerd/containerd.sock # CRI socket路径
# 5.3 配置kubectl(Master节点管理用)
mkdir -p $HOME/.kube
cp /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
命令解释:
--apiserver-advertise-address=192.168.0.61:必须使用节点实际IP,其他节点通过此IP访问API Server。不能在公网或多网卡环境下使用127.0.0.1--pod-network-cidr=10.244.0.0/16:Calico默认Pod CIDR。此CIDR与网络插件Calico的默认配置匹配,不一致会导致Pod IP分配失败--service-cidr=10.96.0.0/12:Service ClusterIP地址分配范围。默认10.96.0.0/12,与kube-proxy和CoreDNS配置联动--image-repository=registry.aliyuncs.com/google_containers:使用阿里云镜像仓库替代k8s.gcr.io,国内必备--cri-socket:显式指定CRI socket路径,告诉kubelet去哪里找containerd- admin.conf:集群管理员证书和配置,包含CA证书和admin用户凭证,安全敏感文件
初始化成功后输出:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You can now join any number of worker nodes by running:
kubeadm join 192.168.0.61:6443 --token zwhz0s.um5i006tbirku5hr \
--discovery-token-ca-cert-hash sha256:d20737d898188003e3a16380c1d8b45eecac9e29216e1d5b65d66ebdd4c70101
步骤6:Worker节点加入集群
目的:3个Worker节点通过kubeadm join加入集群。
bash
# === 每个Worker节点执行 (192.168.0.23/0.47/0.119) ===
kubeadm join 192.168.0.61:6443 \
--token zwhz0s.um5i006tbirku5hr \
--discovery-token-ca-cert-hash sha256:d20737d898188003e3a16380c1d8b45eecac9e29216e1d5b65d66ebdd4c70101
命令解释:
- 192.168.0.61:6443:Master节点API Server地址和端口。6443是默认安全端口
- --token:Bootstrap Token,有效期24小时。用于Worker首次连接Master时的身份认证
- --discovery-token-ca-cert-hash:CA证书哈希值。Worker用此值验证API Server的TLS证书合法性,防中间人攻击
- Token过期处理 :如果Token过期,在Master节点执行
kubeadm token create --print-join-command重新生成
步骤7:安装Calico CNI网络插件
目的:安装Calico作为Pod网络插件,实现跨节点Pod通信。
bash
# === Master节点执行 ===
# 7.1 下载Calico manifest(使用阿里云镜像)
curl -L https://raw.githubusercontent.com/projectcalico/calico/v3.29.3/manifests/calico.yaml \
-o calico.yaml
# 7.2 修改镜像地址为阿里云(国内加速)
sed -i 's|docker.io/calico|registry.aliyuncs.com/calico|g' calico.yaml
# 7.3 应用Calico配置
kubectl apply -f calico.yaml
命令解释:
- Calico v3.29.3:与K8s 1.32.x兼容的最新稳定版
- BGP模式:Calico使用BGP协议在节点间通告Pod路由,性能优于overlay方案
- Pod CIDR 10.244.0.0/16 :Calico默认Pod网络范围,与kubeadm init时
--pod-network-cidr保持一致
⚠️ 注意事项:国内环境可能需要配置containerd的registry mirror来拉取calico镜像。如果遇到ImagePullBackOff错误,检查containerd的registry.mirrors配置。
步骤8:验证集群功能
目的:通过部署测试应用验证集群所有功能。
bash
# === Master节点执行 ===
# 8.1 创建nginx Deployment (3副本)
cat << 'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-nginx
spec:
replicas: 3
selector:
matchLabels:
app: test-nginx
template:
metadata:
labels:
app: test-nginx
spec:
containers:
- name: nginx
image: docker.io/nginx:1.25-alpine
ports:
- containerPort: 80
EOF
# 8.2 创建Service
cat << 'EOF' | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: test-nginx-svc
spec:
type: ClusterIP
selector:
app: test-nginx
ports:
- port: 80
targetPort: 80
EOF
# 8.3 查看Pod分布
kubectl get pods -o wide
# 8.4 测试Service可达性
curl -I http://$(kubectl get svc test-nginx-svc -o jsonpath='{.spec.clusterIP}')
步骤9:清理测试资源
bash
kubectl delete deployment test-nginx
kubectl delete service test-nginx-svc
四、验证结果
4.1 节点状态
NAME STATUS ROLES AGE VERSION INTERNAL-IP
ecs-dd92 Ready <none> 25m v1.32.13 192.168.0.47
ecs-dd92-26db-0001 Ready <none> 25m v1.32.13 192.168.0.119
ecs-dd92-26db-0002 Ready <none> 25m v1.32.13 192.168.0.23
ecs-dd92-26db-0003 Ready control-plane 26m v1.32.13 192.168.0.61
✅ 4/4节点 Ready
4.2 Pod状态
NAMESPACE NAME READY STATUS
default test-nginx-55c4985f9b-hkq89 1/1 Running (ecs-dd92-26db-0001)
default test-nginx-55c4985f9b-n56f8 1/1 Running (ecs-dd92)
default test-nginx-55c4985f9b-sqwbd 1/1 Running (ecs-dd92-26db-0002)
kube-system calico-node-4skp9 1/1 Running (ecs-dd92-26db-0001)
kube-system calico-node-j8pdq 1/1 Running (ecs-dd92)
kube-system calico-node-p8trf 1/1 Running (ecs-dd92-26db-0003)
kube-system calico-node-sbmn2 1/1 Running (ecs-dd92-26db-0002)
kube-system calico-kube-controllers-... 1/1 Running (ecs-dd92-26db-0003)
kube-system coredns-6766b7b6bb-bt5ng 1/1 Running (ecs-dd92-26db-0003)
kube-system coredns-6766b7b6bb-t4wrl 1/1 Running (ecs-dd92-26db-0003)
✅ 18/18 Pod Running,test-nginx的3个Pod分布在3个不同Worker节点
4.3 Service测试
HTTP/1.1 200 OK ← Service可达,nginx正常响应
五、故障排查记录
问题1:阿里云Calico镜像仓库不存在
现象:
Failed to pull image "registry.aliyuncs.com/calico/cni:v3.29.3":
pull access denied, repository does not exist or may require authorization
原因 :阿里云镜像仓库 registry.aliyuncs.com 不包含Calico镜像
解决方案:
- 将calico.yaml镜像地址改为
docker.io/calico - 配置containerd使用docker.io镜像加速器(中科大/网易)
- 重新apply calico.yaml
问题2:节点NotReady导致Pod无法调度
现象:
0/4 nodes are available: 4 node(s) had untolerated taint {node.kubernetes.io/not-ready: }
原因 :CNI网络插件未安装或未运行,kubelet添加了 node.kubernetes.io/not-ready taint
解决方案:先修复CNI(问题1),节点自动变为Ready
六、关键知识点总结
6.1 kubeadm init核心参数
| 参数 | 作用 | 注意事项 |
|---|---|---|
--apiserver-advertise-address |
API Server监听地址 | 必须用节点实际IP,不能是127.0.0.1 |
--pod-network-cidr |
Pod网络地址范围 | 必须与CNI插件配置一致 |
--service-cidr |
Service ClusterIP范围 | 不能与Pod CIDR或宿主机网络重叠 |
--image-repository |
控制平面镜像仓库 | 国内建议用阿里云/中科大镜像 |
6.2 Kubernetes架构核心概念
| 组件 | 角色 | 运行方式 |
|---|---|---|
| kube-apiserver | 集群统一入口 | Static Pod (Master) |
| etcd | 分布式KV存储 | Static Pod (Master) |
| kube-controller-manager | 控制器管理器 | Static Pod (Master) |
| kube-scheduler | Pod调度器 | Static Pod (Master) |
| kubelet | 节点代理 | Systemd服务 (所有节点) |
| kube-proxy | 服务代理 | DaemonSet (所有节点) |
| CoreDNS | 集群DNS | Deployment (kube-system) |
| Calico-node | CNI网络 | DaemonSet (所有节点) |
6.3 containerd关键配置
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true ← kubelet默认使用systemd驱动,必须一致
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = [...] ← 国内镜像加速器
七、常用管理命令
bash
# 查看集群信息
kubectl cluster-info # 集群基本信息
kubectl get nodes -o wide # 节点详情
kubectl get pods -A -o wide # 所有Pod详情
kubectl get svc -A # 所有Service
# 查看组件日志
kubectl logs -n kube-system <pod-name> # 查看Pod日志
journalctl -u kubelet -f # 实时查看kubelet日志
# 加入集群令牌管理
kubeadm token list # 查看现有令牌
kubeadm token create --print-join-command # 生成新join命令
# 排错调试
kubectl describe node <node-name> # 节点详情(包含Conditions)
kubectl describe pod -n <ns> <pod-name> # Pod详情(包含Events)
kubectl get events --sort-by='.lastTimestamp' # 集群事件列表
八、环境清理
bash
# 如果需要重置集群
kubeadm reset -f # Master/Worker通用重置
rm -rf /etc/cni /etc/kubernetes /var/lib/etcd # 清理残留
systemctl restart containerd # 重启容器运行时
实验结论:成功部署4节点Kubernetes v1.32.13集群,Calico CNI运行正常,跨节点Pod通信和Service发现均验证通过。主要踩坑点是国内镜像源选择(阿里云镜像仓库不适合Calico,需用docker.io + 镜像加速器)。