要让 Kubernetes 集群可靠运行,节点(无论是控制平面还是工作节点)的 Linux 系统必须满足一些强制性前提。这些要求并非发行版的自带默认值,通常是你在 kubeadm init 或 kubeadm join 之前需要手动完成的固定配置。下面逐项说明最关键的几个方面,并给出可直接使用的命令与解释。
1. 内核版本与模块
Kubernetes 需要 Linux 内核版本不低于 3.10(实际上几乎所有现代发行版都远超这个版本),但为了使用性能更好的 eBPF、cgroup v2 等特性,建议使用 4.15 或更新的长期支持内核。典型的生产环境节点通常运行在 5.x 或 6.x 内核上。
必须加载的内核模块包括 overlay 和 br_netfilter,这是容器网络和存储依赖的基础:
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
确保 br_netfilter 加载后,还要开启 netfilter 对网桥流量的处理,否则 Pod 间的网络策略和 Service 转发会失效。
2. 启用必要的内核网络参数
必须设置以下 sysctl 参数,让 iptables 能够正确看到桥接流量,并允许 IP 转发:
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
如果不设置 bridge-nf-call-iptables,kube-proxy 的 iptables 规则将无法作用于 Pod 间的跨节点通信。ip_forward 则是 Pod 访问集群外部网络的必要条件。
3. 关闭 Swap(交换空间)
这是每个 Kubernetes 新手都会遇到的第一个“硬性”要求。kubelet 在启动前会主动检测并拒绝在开启 swap 的节点上运行。原因是:swap 会引入不可预测的调度延迟和性能抖动,破坏 Kubernetes 的资源预留与驱逐模型。永久关闭 swap 的方法:
sudo swapoff -a # 立即禁用当前 swap
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab # 注释掉 /etc/fstab 中的 swap 行
某些发行版使用 swap 文件而非分区,同样需要在 /etc/fstab 中注释对应条目。重启后确认 free -m 中 swap 全部为 0。
4. 容器运行时与 cgroup 驱动
Kubernetes 需要容器运行时(如 containerd、CRI-O)。现代集群普遍使用 containerd 作为默认运行时。在安装 containerd 后,务必确保其 cgroup 驱动与 kubelet 一致,都使用 systemd。否则会发生 cgroup 冲突,导致 Pod 启动失败。
containerd 的配置文件通常在 /etc/containerd/config.toml,可运行以下命令生成默认配置并设置 SystemdCgroup:
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd
kubelet 在初始化时默认就会使用 systemd 的 cgroup 驱动,因此保持两边一致即可。
5. 防火墙与网络端口
节点上的防火墙(如 firewalld、ufw、iptables)不能阻断 Kubernetes 组件通信所需的端口,否则集群将无法正常工作。关键端口包括:
- 控制平面节点:6443(API Server)、2379-2380(etcd)、10250(kubelet API)、10257/10259(kube-controller-manager/kube-scheduler)
- 工作节点:10250(kubelet)、30000-32767(NodePort 服务范围)
推荐在初始化前临时放宽或按需配置规则,也可以直接关闭系统防火墙(仅在受控的测试或内网环境):
sudo ufw disable # 如果使用 ufw
sudo systemctl stop firewalld && sudo systemctl disable firewalld # 如果使用 firewalld
生产环境应使用精准的放行规则,而非完全禁用。
6. SELinux 与 AppArmor
基于强化安全的需要,RHEL/CentOS 系的 SELinux 如果处于 enforcing 模式,可能阻挡容器对宿主机资源的访问。kubelet 官方要求将 SELinux 设为 permissive 或 disabled 模式:
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
在 Ubuntu/Debian 上,AppArmor 通常不需要关闭,但需确保容器使用的应用 profile 不会阻断合法操作。多数发行版默认配置即可正常工作。
7. 时间同步
Kubernetes 各组件(特别是 etcd 和证书)对节点间时间差异非常敏感。节点必须启用 NTP 时钟同步:
sudo timedatectl set-ntp true
验证时可用 timedatectl status 确认 System clock synchronized: yes 且 NTP service: active。
8. 禁用不相关的服务与更新策略
为了保证环境纯净和稳定,应该禁用系统自动更新服务(防止在集群运行中意外升级内核或软件)和一些无用服务:
sudo systemctl stop unattended-upgrades && sudo systemctl disable unattended-upgrades # Debian/Ubuntu
sudo systemctl disable --now packagekit # 如果存在
此外,建议将内核的自动更新锁定,防止内核升级导致 kubelet 需要的模块版本不匹配。
完成以上所有步骤后,重启系统使内核参数和模块变更彻底生效,再进行 kubeadm init 或 kubeadm join,通常就能避开绝大多数环境配置导致的预检错误。这些要求不仅是“规矩”,更是确保集群长期稳定运行的基石。