1.3. 环境与工具

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

层级:

L1 · 入门

难度:

入门

预计:

45 分钟

前置:

Linux、SSH、网络基础

1.3.1. 你将学到

  • 两种实验环境的取舍:kind 与多节点虚拟机

  • 节点操作系统必须完成的预检项

  • containerd、kubeadm、kubelet、kubectl 的正确安装顺序

  • 国内网络下的镜像仓库与沙箱镜像配置

  • 一套可复用的节点检查脚本

1.3.2. 选一条路径

维度

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。

1.3.3. 硬件与系统

项目

最低

建议

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 配置,初学阶段会增加变量。

1.3.4. 节点规划

主机名

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.3.5. 系统预检(所有节点)

1.3.5.1. 1. 关闭 swap

kubelet 默认要求禁用 swap。临时关闭并写入 /etc/fstab 永久生效:

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

预期 Swap: 一行全为 0。

1.3.5.2. 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'

1.3.5.3. 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

1.3.5.4. 4. 时间同步

证书、Token、日志都依赖时间。确保 NTP 正常:

sudo apt-get update && sudo apt-get install -y chrony
sudo systemctl enable --now chrony
chronyc tracking

System time 与 Last offset 应在毫秒级;偏差过大时先修时间,再装集群。

1.3.5.5. 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

1.3.6. 安装 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

1.3.6.1. 配置镜像加速(国内环境)

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,按对应版本文档修改,不要盲目复制。

1.3.7. 安装 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

1.3.7.1. 配置 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

1.3.8. 客户端工具

在本地工作站安装:

# 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)

1.3.9. 节点检查脚本

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

1.3.10. 常见问题

现象

原因

处理

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,再重建集群

1.3.11. 小结

  • 预检比安装更重要:swap、内核模块、sysctl、时间、cgroup driver,五项必须一次做对。

  • containerd 配置要按版本查文档,不要跨版本复制。

  • 先在每台节点跑一遍检查脚本,再执行 kubeadm init。

1.3.12. 延伸阅读