跳转至

环境与工具

90% 的集群部署失败,都能在安装前避免:swap 没关、内核模块没加载、时间不同步、沙箱镜像拉不到。这一章把「装之前该做的事」一次做对。

难度 · 入门 预计 45 分钟 前置:Linux、SSH、网络基础

你将学到

  • 两种实验环境的取舍: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 永久生效:

sudo swapoff -a
sudo sed -ri 's/^([^#].*\sswap\s.*)$/# \1/' /etc/fstab
free -h

预期 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 外部 → 所有节点
sudo ufw status
# 实验环境如需关闭:
# sudo ufw disable

安装 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:

sudo apt-get install -y 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

验证:

kubeadm version
kubelet --version
kubectl version --client

配置 kubelet 的沙箱镜像

如果 registry.k8s.io 不可达,需要修改 kubelet 的 pause 镜像。先确认默认值:

kubeadm config images list --kubernetes-version v1.31.0

在 /etc/default/kubelet 或 kubeadm 配置中增加:

KUBELET_EXTRA_ARGS="--pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.10"

修改后重启 kubelet:

sudo systemctl daemon-reload
sudo systemctl restart 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 日志聚合 推荐

配置补全:

# bash
source <(kubectl completion bash)
# zsh
source <(kubectl completion zsh)

节点检查脚本

把下面的脚本保存为 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。

延伸阅读