目标:完成 k8s 安装前的最后两项准备——内核网络参数(k8s 的神经网络)和容器运行时(k8s 的手)。 前置:已完成 阶段 0(上):虚拟机与系统初始化。 步骤编号延续上篇(从第 5 步开始);所有命令在 Rocky 机器上以 root 执行。
5. 加载内核模块并开启 iptables 桥接流量(必须)
为什么必须——k8s 的 Service 网络(阶段 3 主角)依赖三样底层能力:
overlay:容器镜像分层存储的文件系统,containerd 启动容器必备br_netfilter+bridge-nf-call-iptables=1:强制网桥流量经过 iptables。Service 虚拟 IP 靠 iptables 规则转换(kube-proxy 写入),桥内流量若绕过 iptables,Service 全部失灵ip_forward=1:允许节点转发数据包,跨节点 Pod 通信的前提
缺了任何一样,阶段 1 的 kubeadm init 预检会直接报错拒绝安装。
验证:lsmod | grep br_netfilter 应有输出,例如:
输出读法(四列 = 模块名 / 大小(字节) / 引用计数 / 被谁引用):
引用计数 0 不等于没用——br_netfilter 靠 sysctl 开关起作用,不靠被谁引用;
bridge 行尾出现 br_netfilter,说明它是 bridge 网桥驱动的"扩展插件",
专门给网桥加 netfilter(iptables)钩子。两行都在 = 这对搭档都在岗。
(/etc/modules-load.d/ 管开机自动加载,modprobe 管立即生效,缺一不可。)
6. 安装容器运行时 containerd
k8s 自己不会跑容器——它只是调度大脑(决定 Pod 放哪台机器),真正拉镜像、起容器的是容器运行时。kubelet 通过标准接口 CRI 指挥 containerd 干活:kubectl 命令 → apiserver → scheduler → kubelet → containerd → 容器进程。
Kubernetes 从 1.24 起不再直接支持 Docker(它对 k8s 来说太重),containerd 是主流选择。
6.1 安装
- containerd 的官方发布渠道是 Docker 公司的软件源
download.docker.com(国内不可达)。阿里把它整个镜像了一份,我们借仓库只取containerd.io这一个包,不装 docker-ce 本身——虚拟机里不会有 Docker - 包名是
containerd.io(不带 .io 的是另一个老包,别搞混) - containerd 没有开箱即用的配置文件,必须先用
config default生成底版再修改
6.2 关键修改 1:SystemdCgroup = true(与 kubelet 统一资源管理)
| |
为什么必改:cgroup 是 Linux 给进程分配/限制资源(CPU、内存)的机制,k8s 的 requests/limits 全靠它。
cgroup 有两种"管理员":cgroupfs(传统写法)和 systemd(Rocky 9 等现代发行版由 systemd 统一管理)。
一台机器只能有一个管理员——kubelet 用 systemd,containerd 默认却是 cgroupfs(false),
两个管理员各记一套账,会导致资源统计错乱、节点不稳定。这行 sed 把 containerd 也划归 systemd 阵营。
6.3 关键修改 2:certs.d 镜像代理(国内拉镜像的生存指南)
| |
原理:certs.d 是 containerd 的"仓库导航改写本"。它拉镜像时的决策过程是:
目录结构就是映射关系——要拉哪个仓库的镜像,就用哪个目录下的 hosts.toml:
hosts.toml 三行的含义:
最后那条 sed 是总开关:containerd 2.x 默认配置里 config_path = ''(空 = 根本不看 certs.d 目录),
把它指向该目录,导航本才生效。
为什么这样设计,而不是别的办法:
- ❌ 直接改镜像名(把
nginx写成docker.m.daocloud.io/library/nginx):镜像名写在全世界的 YAML、Helm Chart、kubeadm 生成的清单里,改不完也改不到;换代理时还要全局替换 - ❌ 配 HTTP 代理:多一个要维护的中间故障点,且企业环境未必有代理可用
- ✅ certs.d:只在一个地方声明映射,全世界照常用官方镜像名,拉取被悄悄改道; daocloud 挂了改两行 hosts.toml 换一家即可,业务零改动。 本质是逻辑地址(镜像名)与物理地址(镜像站)解耦,对 kubelet/YAML/Helm 完全透明
registry.k8s.io 那份的必要性:阶段 1 装集群时核心组件可以换阿里云源,
但 ingress-nginx(阶段 6)、metrics-server(阶段 8)等第三方组件的官方清单里写死了
registry.k8s.io 地址,不便改也没法改。配上这条,届时 kubectl apply 官方清单直接跑通。
6.4 关键修改 3:pause(sandbox)镜像指向阿里云(国内搭集群第一坑)
| |
pause 容器是什么:一个 Pod 可以装多个容器,它们共享同一个网络命名空间(同一个 IP)。 这个"共享"需要一个先行者先把网络命名空间创建好、占住位置——就是 pause 容器(沙箱容器)。 每个 Pod 里都有一个看不见的 pause,几乎不占资源,但没它 Pod 无法创建。
问题链条:pause 镜像默认在 registry.k8s.io/pause(Google CDN,国内被墙)→
老办法是 kubelet 参数 --pod-infra-container-image,但 kubelet 1.34 起该参数失效,
改为从 containerd 的 sandbox_image 读取 → 不改的后果是所有 Pod 永远卡在 ContainerCreating。
这条 sed 在该插件节下追加一行,指向阿里云镜像站(a\ = 在匹配行之后追加)。
三关总结:
SystemdCgroup让 containerd 与 kubelet 和平共处;certs.d让 Docker Hub / k8s 官方镜像拉得到;sandbox_image让 Pod 能创建。 少任何一个,阶段 1 都会以不同的姿势翻车。
6.5 (按需)虚拟机直连出网被拦时:给 containerd 配代理
containerd 是系统服务,不读你终端里 export 的代理变量,必须用 systemd drop-in 单独配置
(192.168.5.2 是 Lima 内置的"Mac 本机"地址,长期有效,排查思路见
阶段 0(上)附录 A):
| |
⚠️ 配了这个代理后,将来直连恢复或 Clash 关闭时必须删掉它并重启 containerd (
rm 该文件 && systemctl daemon-reload && systemctl restart containerd), 否则 containerd 拉镜像全部失败。原则:代理配置和代理软件同开同关。
6.6 启动与验证
验证:
| |
💡 镜像代理说明:配置后,所有
nginx、mysql这类来自 Docker Hub 的镜像 会经由docker.m.daocloud.io代理拉取,对 Kubernetes 完全透明(镜像名不用改)。 如果 daocloud 将来失效,换其他可用代理地址改hosts.toml即可。 k8s 官方镜像仓库registry.k8s.io本教程网络实测可达,无需代理; 如果你的网络不行,阶段 1 有阿里云替代方案。
7. 检查清单
进入下一阶段前确认:
常见问题
Q: 第 6 步装 containerd / 拉镜像时网络不通?
containerd 是系统服务,不读终端环境变量。先按上篇附录 A 的分层法确认是不是"虚拟机直连被拦",
是的话用第 6.5 节的 systemd drop-in 给 containerd 配代理;
将来 Pod 出现 ImagePullBackOff 也先怀疑这层。
Q: containerd 配置文件里的插件名为什么和网上旧教程不一样?
containerd 2.x 使用了新版配置格式(如 io.containerd.cri.v1.images),
旧教程里的 io.containerd.grpc.v1.cri 是 1.x 的写法。本教程的 sed 命令两种都兼容。
附录 B:集群装好后如何验证(阶段 1 完成后使用)
进程活着 ≠ 集群可用,能跑起一个真 Pod 才是终极证明。按三层验证(虚拟机里、root 执行):
第一层:节点状态
第二层:系统组件 Pod 全部 Running(最关键)
第三层:跑一个真容器(终极证明)
辅助定位(上面不正常时查):
判断标准速记:
get nodesReady → 集群成立;kube-system 全 Running → 控制面健康; 自建 Pod 到 Running 且能 exec → 端到端真通了(也是本阶段 containerd 三个关键修改的验收)。 若 kubectl 报 “connection to localhost:8080 refused”,说明 kubeconfig 没配,先做阶段 1 的mkdir -p $HOME/.kube && cp /etc/kubernetes/admin.conf $HOME/.kube/config。
动手练习
- 查看 containerd 配置文件
/etc/containerd/config.toml,找到你刚改的SystemdCgroup和config_path两行。 - 查看
/etc/containerd/certs.d/docker.io/hosts.toml,理解镜像代理的配置结构。
下一步
➡️ 阶段 1:搭建集群(系列第 1 篇,即将发布——从这里开始正式安装 Kubernetes)
