《云原生从0到1:4台华为云ECS搭建Kubernetes 1.28集群实录(上)——环境与踩坑全记录》

《云原生从0到1:4台华为云ECS搭建Kubernetes 1.28集群实录(上)------环境与踩坑全记录》

作者:云原生学习者 | 系列:云原生工程师实战之路

一句话导读:本文记录了用 4 台华为云 ECS(Ubuntu 24.04,8C16G)从零搭建 Kubernetes 1.28.2 集群的完整过程。其中最大的"惊喜"是 Ubuntu 24.04 自带的 containerd 2.2.1 配置体系与网上 99% 教程完全不同,本文会把每个坑的报错、根因、修复方案全部摊开讲清楚。文章适合所有准备亲手搭建 K8s 集群的开发者,建议收藏。


0. 写在前面

云原生时代,Kubernetes 已经成为事实上的"操作系统"。无论你是想转行云原生工程师、考 CKA/CKS 证书,还是想在公司内部落地容器化,亲手从零搭建一套 K8s 集群都是绕不开的第一课。

本次实操,我准备了 4 台华为云 ECS 服务器,规划为经典的 1 Master + 3 Worker 拓扑。机器配置如下:

角色 主机名 公网 IP 私网 IP 配置 系统
Master master 114.116.250.152 192.168.0.114 8 vCPU / 16 GiB Ubuntu 24.04 Server
Worker node1 113.44.249.32 192.168.0.71 8 vCPU / 16 GiB Ubuntu 24.04 Server
Worker node2 116.205.105.142 192.168.0.178 8 vCPU / 16 GiB Ubuntu 24.04 Server
Worker node3 113.44.154.124 192.168.0.25 8 vCPU / 16 GiB Ubuntu 24.04 Server

💡 同可用区部署,私网互通,K8s 集群组件间通信走内网,速度快且不消耗公网流量。

技术选型(重点!)

组件 版本 说明
Kubernetes v1.28.2 稳定、资料多、考试覆盖
容器运行时 containerd 2.2.1 Ubuntu 24.04 apt 自带,注意不是 1.7.x!
网络插件 Calico v3.26.1 业界主流 CNI,支持 BGP/IPIP
Pod 网段 10.244.0.0/16 避开华为云 VPC 私有网段 192.168.0.0/16,防止冲突

1. 架构设计与部署规划

scss 复制代码
┌─────────────────────────────────────────────────────────┐
│                       公网 (弹性IP)                       │
│   114.116.250.152   113.44.249.32   116.205.105.142     │
│   113.44.154.124                                         │
└──────────────┬──────────────────────────────────────────┘
               │  华为云 VPC 私有网络 192.168.0.0/24
┌──────────────▼──────────────────────────────────────────┐
│  master (192.168.0.114)   ← API Server :6443 / etcd     │
│  node1  (192.168.0.71 )   ← kubelet + kube-proxy        │
│  node2  (192.168.0.178)   ← kubelet + kube-proxy        │
│  node3  (192.168.0.25 )   ← kubelet + kube-proxy        │
│  Pod 网段: 10.244.0.0/16 (Calico)                        │
└─────────────────────────────────────────────────────────┘

部署清单(四步走)

  1. ✅ 所有节点基础环境:内核参数、swap 关闭、containerd 配置、K8s 组件安装
  2. ⏳ Master 初始化:kubeadm init 生成控制面与 join token
  3. ⏳ Worker 加入:kubeadm join 批量接入
  4. ⏳ 网络打通:Calico CNI 部署,节点 Ready

2. 环境准备:从零配置 4 台机器

2.1 基础工具与内核参数

首先登录所有节点(本文使用 SSH 免密 + 批量脚本管理 4 台机器,大幅提升效率),安装基础工具并配置内核:

bash 复制代码
# 基础工具
apt-get update && apt-get install -y curl wget vim net-tools jq \
    apt-transport-https ca-certificates gnupg lsb-release

# 关闭 swap(K8s 1.28 要求)
swapoff -a && sed -i '/swap/d' /etc/fstab

# 加载内核模块
cat > /etc/modules-load.d/k8s.conf <<'EOF'
overlay
br_netfilter
EOF
modprobe overlay && modprobe br_netfilter

# 内核网络参数(iptables 桥接流量、IP 转发)
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

📌 net.ipv4.ip_forward=1 是容器网络通信的基础,缺失会导致 Pod 间无法跨节点通信。

2.2 主机名与 hosts 解析

bash 复制代码
hostnamectl set-hostname master   # node1/node2/node3 同理

cat >> /etc/hosts <<'EOF'
192.168.0.114 master
192.168.0.71  node1
192.168.0.178 node2
192.168.0.25  node3
EOF

配置内网 hostname 解析后,join 时可以直接用 master:6443,证书也能正确匹配。


3. 🚨 第一大坑:Ubuntu 24.04 的 containerd 2.2.1,配置体系全变了!

这是本次部署最值得写的一节。网上绝大多数教程(包括很多付费课程)都在讲 containerd 1.7.x 时代的配置:

toml 复制代码
# 老版本写法(网上 99% 教程)
sandbox_image = "registry.k8s.io/pause:3.8"
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]

但 Ubuntu 24.04 通过 apt 安装的 containerd 是 2.2.1,配置格式发生了革命性变化:

toml 复制代码
# 新版本(containerd 2.x)
version = 3
[plugins.'io.containerd.cri.v1.images']
  [plugins.'io.containerd.cri.v1.images'.pinned_images]
    sandbox = 'registry.k8s.io/pause:3.10.1'   # ← 字段名从 sandbox_image 变成 sandbox!
  [plugins.'io.containerd.cri.v1.images'.registry]
    config_path = '/etc/containerd/certs.d:/etc/docker/certs.d'  # ← 推荐用 hosts.toml 而非 mirrors

3.1 坑 1.1:sandbox_image 配置不生效

我按老教程执行 sed -i 's#sandbox_image = "..."#...#',结果 grep 出来根本没有这个字段!运行 kubelet 后日志狂报:

css 复制代码
error="failed to get sandbox image \"registry.k8s.io/pause:3.10.1\":
failed to pull image ... dial tcp 74.125.195.82:443: i/o timeout"

根因 :containerd 2.x 中沙箱镜像配置在 pinned_images.sandbox,且默认指向 registry.k8s.io(国内不可达),必须替换。

修复

bash 复制代码
sed -i "s#sandbox = 'registry.k8s.io/pause:3.10.1'#sandbox = 'registry.aliyuncs.com/google_containers/pause:3.9'#" /etc/containerd/config.toml

💡 K8s 1.28 对应 pause:3.9,别用错版本。

3.2 坑 1.2:mirrorsconfig_path 互斥,CRI 插件直接加载失败

我在老位置追加了镜像加速配置后,containerd 日志出现致命错误:

ini 复制代码
level=warning msg="failed to load plugin"
error="unable to load CRI image service plugin dependency:
invalid cri image config: `mirrors` cannot be set when `config_path` is provided"

根因 :containerd 2.x 默认启用 config_path(指向 /etc/containerd/certs.d)时禁止 同时使用 mirrors。CRI 插件加载失败 → crictlCRI v1 image API is not implemented

修复(官方推荐方式:hosts.toml)

bash 复制代码
mkdir -p /etc/containerd/certs.d/docker.io /etc/containerd/certs.d/registry-1.docker.io
cat > /etc/containerd/certs.d/docker.io/hosts.toml <<'EOF'
server = "https://docker.io"

[host."https://docker.m.daocloud.io"]
  capabilities = ["pull", "resolve"]
[host."https://docker.1ms.run"]
  capabilities = ["pull", "resolve"]
[host."https://hub-mirror.c.163.com"]
  capabilities = ["pull", "resolve"]
EOF

修复后验证 CRI 正常、镜像可拉:

bash 复制代码
$ systemctl restart containerd
$ crictl pull registry.aliyuncs.com/google_containers/pause:3.9
Image is up to date for sha256:e6f1816883972d4be47bd48879a08919b96afcd344132622e4d444987919323c
$ crictl images
IMAGE                                           TAG                 IMAGE ID            SIZE
registry.aliyuncs.com/google_containers/pause   3.9                 e6f1816883972       322kB

3.3 坑 1.3:crictl 默认连 dockershim 端点

arduino 复制代码
FATA[0000] validate service connection: ... dial unix /var/run/dockershim.sock: connect: no such file or directory

修复 :配置 /etc/crictl.yaml 指向 containerd:

bash 复制代码
cat > /etc/crictl.yaml <<'EOF'
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF

3.4 别忘了 SystemdCgroup

containerd 2.x 的 config default 生成的配置里 SystemdCgroup = false,而 kubeadm 默认要求 kubelet 与运行时统一使用 systemd cgroup 驱动,必须改:

bash 复制代码
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
systemctl restart containerd

4. 安装 K8s 组件(kubeadm / kubelet / kubectl)

国内环境必须用阿里云镜像源 ,官方源 packages.cloud.google.com 不可达:

bash 复制代码
# 添加阿里云 K8s 源
install -d /etc/apt/keyrings
curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg \
    | 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/apt kubernetes-xenial main" \
    > /etc/apt/sources.list.d/kubernetes.list
apt-get update

# 安装 1.28.2 并锁定版本
apt-get install -y kubelet=1.28.2-00 kubeadm=1.28.2-00 kubectl=1.28.2-00
apt-mark hold kubelet kubeadm kubectl

安装完成确认版本:

text 复制代码
kubeadm version: v1.28.2 (GitCommit: 89a4ea3e1e4ddd7f7572286090359983e0387b2f)
Kubernetes v1.28.2 (Client Version)

5. Master 节点初始化(kubeadm init)

在 master 上执行初始化。核心参数说明:

bash 复制代码
kubeadm init \
  --image-repository=registry.aliyuncs.com/google_containers \  # 国内镜像仓库,必须!
  --kubernetes-version=v1.28.2 \
  --pod-network-cidr=10.244.0.0/16 \          # 与 Calico 网段保持一致
  --apiserver-advertise-address=192.168.0.114 \ # Master 私网 IP
  --cri-socket=unix:///run/containerd/containerd.sock

⚠️ 注意 --image-repository 只影响 kubeadm 拉取的组件镜像(apiserver/etcd 等),沙箱镜像 pause 由 containerd 的 pinned_images 决定------这就是上面坑 1.1 必须解决的原因。

初始化成功后,控制台会输出关键信息(务必保存!):

text 复制代码
Your Kubernetes control-plane has been initialized successfully!

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

kubeadm join 192.168.0.114:6443 --token 6ju96d.f633yienwrluzp27 \
	--discovery-token-ca-cert-hash sha256:0a6d6ff34a117c1e1f8f6936f04be153994a09266bbed6f3ba0cdf3981b8a457

💡 token 有效期默认 24 小时,若过期可执行 kubeadm token create --print-join-command 重新生成。

5.1 配置 kubectl

bash 复制代码
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
kubectl get nodes

6. 小结与下期预告

本文完成了云原生集群搭建的前半程:4 台 ECS 环境准备 + containerd 2.2.1 三连坑修复 + kubeadm init 控制面初始化

核心收获:

  1. Ubuntu 24.04 的 containerd 2.x 配置体系完全不同sandbox 替代 sandbox_imagehosts.toml 替代 mirrors、CRI 插件路径从 grpc.v1.cri 改为 cri.v1.*
  2. 国内环境镜像源三件套:阿里云 K8s apt 源 + 阿里云容器镜像仓库 + hosts.toml 加速;
  3. cgroup 驱动必须统一:kubelet 与 containerd 都要用 systemd。

下期预告:《3 个 Worker 节点批量加入集群 + Calico 网络插件部署 + 集群健康检查实战》,敬请期待!


本文为原创实操记录,基于真实环境一步步跑通。欢迎转载,请注明出处。

相关推荐
那咋乎吧18 分钟前
数据包到达网卡后到用户态应用程序的全流程
后端
codeY21 分钟前
Vite 前端发布后「点击菜单没反应」?旧版本资源 404 的完整排查与修复实录
前端·前端工程化
程序猿阿越22 分钟前
kubelet源码阅读
后端·kubernetes·源码阅读
90后的晨仔39 分钟前
uni-app Vue3 状态管理 Pinia 完全指南:从概念到实战的深度解析
前端
mqiqe39 分钟前
AgentScope Java 2.0 集成 Chat Completions Web:一行依赖让你的 Agent 变身 OpenAI 兼容服务
java·开发语言·前端
程序员小八77740 分钟前
后端开发初学TypeScript
前端·javascript·typescript
90后的晨仔42 分钟前
Puppeteer 与 Playwright 深度实战指南:从零到精通,全面提升开发效率
前端
sunphp开发者1 小时前
阿里云CDN加速配置问题
前端·阿里云·云计算
小小数媒成员1 小时前
存储器层级结构
java·服务器·前端