K8s集群部署实验笔记:4节点Kubernetes v1.32.13 + Calico v3.29.3

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=1K8s网络关键参数。Pod网络基于bridge,此参数确保iptables规则对桥接流量生效
  • net.ipv4.ip_forward=1IP转发。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/16Calico默认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镜像

解决方案

  1. 将calico.yaml镜像地址改为 docker.io/calico
  2. 配置containerd使用docker.io镜像加速器(中科大/网易)
  3. 重新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 + 镜像加速器)。

相关推荐
古城小栈11 小时前
k8s 存储练习
云原生·容器·kubernetes
万里侯11 小时前
云原生监控体系建设:打造全方位的可观测性平台
微服务·容器·k8s
无级程序员11 小时前
记一次K8S增加新节点
云原生·容器·kubernetes
仙柒41519 小时前
控制平面组件和节点组件
运维·容器·kubernetes
wb1891 天前
Kubernetes服务优化
云原生·容器·kubernetes
码点滴1 天前
Workload 自动化进化论:从手动运维到 AI 驱动的 Kubernetes 智能管控
运维·人工智能·kubernetes·自动化·workload
魏杨杨1 天前
被流量逼出来的架构:从一台服务器到云原生的 17 次蜕变 —— 集群、缓存、MQ、微服务、Docker、K8S 的前世今生
微服务·k8s·负载均衡·ddd·分部署
Waay1 天前
图文详解|K8s Pod内部结构
docker·云原生·kubernetes
码点滴1 天前
CRI-O选型与容器运行时标准
开发语言·人工智能·架构·kubernetes·cri-o