环境与工具¶
90% 的集群部署失败,都能在安装前避免:swap 没关、内核模块没加载、时间不同步、沙箱镜像拉不到。这一章把「装之前该做的事」一次做对。
你将学到¶
- 两种实验环境的取舍:kind 与多节点虚拟机
- 节点操作系统必须完成的预检项
- containerd、kubeadm、kubelet、kubectl 的正确安装顺序
- 国内网络下的镜像仓库与沙箱镜像配置
- 一套可复用的节点检查脚本
选一条路径¶
| 维度 | kind(本地) | 多节点虚拟机(推荐) |
|---|---|---|
| 启动速度 | 1–2 分钟 | 20–40 分钟 |
| 资源占用 | 2C / 4G 起 | 4 台 × 2C / 4G |
| 能学的对象 | Pod、Deployment、Service、Ingress | 全部 |
| 能练的故障 | 有限 | 节点宕机、网络分区、磁盘满 |
| 存储 / LB | 受限 | 可完整演练 |
| 适合章节 | 开始 / 核心 | 平台 / 交付 / 生产化 |
本文以多节点虚拟机为主,kind 作为补充。如果你用 macOS,推荐 OrbStack 或 Docker Desktop + kind;如果要做平台实验,用 UTM / VMware Fusion / Proxmox 开 4 台 Ubuntu。
硬件与系统¶
| 项目 | 最低 | 建议 |
|---|---|---|
| CPU(总数) | 6 核 | 12 核以上 |
| 内存(总数) | 12 GB | 24 GB 以上 |
| 磁盘 | 120 GB | 250 GB SSD |
| 系统 | Ubuntu 22.04 / 24.04 | 22.04 LTS |
| 网络 | 同一二层网段 | 固定 IP + 可访问外网 |
为什么推荐 Ubuntu
仓库中的 Ansible playbook、containerd 配置、内核参数示例都以 Debian / Ubuntu 为基线。用 CentOS / Rocky 也能做,但需要自行替换包管理与 SELinux 配置,初学阶段会增加变量。
节点规划¶
| 主机名 | IP | 角色 | 说明 |
|---|---|---|---|
| k8s-master01 | 192.168.10.6 | control-plane | API Server、etcd、调度器、控制器 |
| k8s-node01 | 192.168.10.11 | worker | 业务 Pod |
| k8s-node02 | 192.168.10.12 | worker | 业务 Pod |
| k8s-node03 | 192.168.10.13 | worker | 业务 Pod / 存储实验 |
所有节点需要能互相解析主机名。实验环境可以直接写 /etc/hosts:
sudo tee -a /etc/hosts >/dev/null <<'EOF'
192.168.10.6 k8s-master01.magedu.com k8s-master01
192.168.10.11 k8s-node01.magedu.com k8s-node01
192.168.10.12 k8s-node02.magedu.com k8s-node02
192.168.10.13 k8s-node03.magedu.com k8s-node03
EOF
生产环境请用 DNS,并确保正向、反向解析一致。
系统预检(所有节点)¶
1. 关闭 swap¶
kubelet 默认要求禁用 swap。临时关闭并写入 /etc/fstab 永久生效:
预期 Swap: 一行全为 0。
2. 加载内核模块¶
cat <<'EOF' | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
lsmod | grep -E 'overlay|br_netfilter'
3. 配置内核参数¶
cat <<'EOF' | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
sysctl net.ipv4.ip_forward net.bridge.bridge-nf-call-iptables
4. 时间同步¶
证书、Token、日志都依赖时间。确保 NTP 正常:
sudo apt-get update && sudo apt-get install -y chrony
sudo systemctl enable --now chrony
chronyc tracking
System time 与 Last offset 应在毫秒级;偏差过大时先修时间,再装集群。
5. 关闭防火墙或放行端口¶
实验环境可以关闭 ufw;生产环境应按端口放行。控制平面与工作节点需要的关键端口:
| 端口 | 组件 | 范围 |
|---|---|---|
| 6443 | kube-apiserver | 所有节点 → control-plane |
| 2379–2380 | etcd | control-plane 之间 |
| 10250 | kubelet API | control-plane → 所有节点 |
| 10257 / 10259 | controller-manager / scheduler | 本机 |
| 8472/udp | Flannel VXLAN | 所有节点之间 |
| 4789/udp | Calico/Cilium VXLAN | 所有节点之间 |
| 179/tcp | Calico BGP | 所有节点之间 |
| 4240/tcp | Cilium health | 所有节点之间 |
| 30000–32767 | NodePort | 外部 → 所有节点 |
安装 containerd¶
Kubernetes v1.31 默认使用 containerd 1.7 / 2.x。先安装依赖与 containerd:
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release apt-transport-https
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
sudo apt-get update
sudo apt-get install -y containerd.io
生成配置并开启 SystemdCgroup(kubelet 与 containerd 的 cgroup driver 必须一致):
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl enable --now containerd
sudo systemctl restart containerd
验证:
sudo systemctl status containerd --no-pager
sudo crictl --runtime-endpoint unix:///run/containerd/containerd.sock version
如果 crictl 不存在,安装 cri-tools:
配置镜像加速(国内环境)¶
containerd 2.x 的 registry 配置与 1.x 有差异。以 1.7 为例,编辑 /etc/containerd/config.toml,在 [plugins."io.containerd.grpc.v1.cri".registry.mirrors] 下增加:
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://docker.m.daocloud.io", "https://docker.io"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]
endpoint = ["https://registry.aliyuncs.com/google_containers"]
然后 sudo systemctl restart containerd。
配置格式随版本变化
仓库 README 也提示:registry.mirrors / registry.configs 在 containerd 2.x 中逐步弃用,新格式使用 [plugins."io.containerd.cri.v1.images".registry]。配置前先执行 containerd --version,按对应版本文档修改,不要盲目复制。
安装 kubeadm、kubelet、kubectl¶
使用 Kubernetes 官方社区仓库(pkgs.k8s.io):
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | \
sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \
https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | \
sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
验证:
配置 kubelet 的沙箱镜像¶
如果 registry.k8s.io 不可达,需要修改 kubelet 的 pause 镜像。先确认默认值:
在 /etc/default/kubelet 或 kubeadm 配置中增加:
修改后重启 kubelet:
客户端工具¶
在本地工作站安装:
# macOS
brew install kubectl helm k9s jq yq
# Linux
# kubectl 同上;helm 用官方脚本:
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
| 工具 | 用途 | 是否必需 |
|---|---|---|
| kubectl | 集群操作 | 必需 |
| helm | 安装平台组件 | 必需 |
| k9s | 终端 UI,快速排错 | 推荐 |
| jq / yq | 处理 JSON / YAML | 推荐 |
| cilium CLI | 安装与排查 Cilium | 用 Cilium 时必需 |
| calicoctl | 排查 Calico BGP | 用 Calico 时推荐 |
| stern | 多 Pod 日志聚合 | 推荐 |
配置补全:
节点检查脚本¶
把下面的脚本保存为 preflight.sh,在所有节点执行。任何一项失败都不要继续安装集群:
#!/usr/bin/env bash
set -uo pipefail
fail=0
check() {
local name="$1"; shift
if "$@" >/dev/null 2>&1; then
printf " [OK] %s\n" "$name"
else
printf " [FAIL] %s\n" "$name"
fail=1
fi
}
echo "== 系统 =="
check "swap 已关闭" bash -c '! swapon --show | grep -q .'
check "overlay 模块" bash -c 'lsmod | grep -q overlay'
check "br_netfilter 模块" bash -c 'lsmod | grep -q br_netfilter'
check "ip_forward=1" bash -c '[ "$(sysctl -n net.ipv4.ip_forward)" = "1" ]'
check "bridge-nf-call-iptables=1" bash -c '[ "$(sysctl -n net.bridge.bridge-nf-call-iptables)" = "1" ]'
echo "== 运行时 =="
check "containerd 运行中" systemctl is-active containerd
check "SystemdCgroup=true" grep -q 'SystemdCgroup = true' /etc/containerd/config.toml
echo "== 组件 =="
check "kubeadm" command -v kubeadm
check "kubelet" command -v kubelet
check "kubectl" command -v kubectl
echo "== 时间 =="
check "chrony 同步" chronyc tracking
exit "$fail"
常见问题¶
| 现象 | 原因 | 处理 |
|---|---|---|
kubeadm init 报 swap |
swap 未关闭 | swapoff -a 并清理 fstab |
| kubelet 反复重启 | cgroup driver 不一致 | containerd 开 SystemdCgroup=true |
ImagePullBackOff |
镜像仓库不可达 | 配 mirror,或改 imageRepository |
| 节点 NotReady | CNI 未安装 / 内核模块缺失 | 装 CNI,检查 br_netfilter |
crictl 连不上 |
endpoint 配错 | 指定 /run/containerd/containerd.sock |
| 时间漂移导致证书错误 | NTP 未同步 | 修 chrony,再重建集群 |
小结¶
- 预检比安装更重要:swap、内核模块、sysctl、时间、cgroup driver,五项必须一次做对。
- containerd 配置要按版本查文档,不要跨版本复制。
- 先在每台节点跑一遍检查脚本,再执行
kubeadm init。