CentOS 与 Kubernetes 冲突的定位与解决
一、先判定冲突类型
- 运行旧版 Kubernetes 1.9 且内核为 CentOS 7.3 的 3.10 时,启用 cgroup 的 kernel memory 特性会导致节点不稳定,典型报错为创建 sandbox 失败或 cgroup memory 报 “No space left on device”。这是已知的内核与 kubelet 组合缺陷,重启后更易复现。若看到这类日志,基本可判定为内核特性不兼容。
- 在 CentOS 7.9 默认 3.10 内核 上运行 Kubernetes 1.28+(尤其是 1.31),常见网络性能严重劣化(如 iperf3 仅 百 KB/s~几 MB/s)、偶发 CPU 僵死等。根因是旧内核对 IPVS 高级参数、eBPF、VXLAN、nf_conntrack 等现代网络栈优化支持不足。
- 运行 Kubernetes 1.24+ 时,内置的 Dockershim 已被移除,若仍按旧方式依赖 Docker 而不切换到 containerd/CRI,会出现无法创建 Pod 或组件异常等兼容性问题。
二、对应解决方案
- 针对内核特性缺陷(K8s 1.9 + 3.10)
- 优先方案:升级到 CentOS 7.9 并启用 ELRepo 的 LTS 内核 5.4,可规避 cgroup kernel memory 等稳定性问题。
- 导入 GPG 并安装 ELRepo:rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org && yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
- 安装长期支持内核:yum --enablerepo=elrepo-kernel install kernel-lt -y
- 设置默认启动项(grub2 菜单顺序通常为 0):awk -F' ‘$1=="menuentry " {print i++ " : " $2}’ /etc/grub2.cfg;grub2-set-default 0;grub2-mkconfig -o /boot/grub2/grub.cfg
- 重启并验证:uname -r 应显示 5.4.x。
- 临时缓解(无法立即升级时):避免触发 cgroup kernel memory 相关路径,回退到更稳定的 K8s 版本组合(如 1.6/1.8 系列),并严格测试后再滚动升级。
- 针对网络性能灾难(1.28+ 在 3.10 上)
- 推荐:升级内核至 ≥5.10(如 5.4 LTS 或更高),可显著改善 IPVS、eBPF、VXLAN、conntrack 等路径的性能与稳定性。
- 替代:若短期内无法升级内核,建议将 K8s 版本回退到 1.23.x 等更适配 3.10 内核的稳定版本,以获得可预期的网络表现。
- 针对运行时与版本分界(1.24+)
- 切换到 containerd/CRI:安装并配置 containerd,启用 SystemdCgroup = true,使用 crictl 验证运行时连通性,kubeadm 初始化时指定 criSocket: unix:///run/containerd/containerd.sock。
- 若必须使用 Docker,可通过 cri-dockerd 适配,但生产更推荐直接使用 containerd。
三、版本与内核搭配建议
| 目标 K8s 版本 |
建议 CentOS 与内核 |
说明 |
| ≤ 1.23.x |
CentOS 7.9 + 3.10(或升级至 5.4 LTS 更稳) |
老内核可用,但建议升级内核以规避 cgroup 等历史缺陷 |
| 1.24.x |
CentOS 7.9 + 5.4 LTS(或迁移至 8/9 系) |
1.24 移除 Dockershim,需使用 containerd/CRI |
| 1.26–1.27.x |
CentOS 7.9 + ≥5.10 或迁移至 8/9 系 |
建议更高内核以获得更佳网络/存储栈支持 |
| 1.28–1.31.x |
≥5.10 或迁移至 8/9 系 |
3.10 上网络性能与稳定性问题显著,升级内核收益最大 |
| ≥ 1.32.x |
优先 Rocky/AlmaLinux 8/9、Ubuntu 22.04/24.04 |
新内核与生态支持更完善,长期维护成本更低 |
| 说明:若无法升级内核,务必将 K8s 版本控制在 1.23.x;若追求新特性与性能,优先升级内核或迁移操作系统。 |
|
|
四、落地操作清单
- 基线检查
- 查看系统与内核:cat /etc/centos-release;uname -r
- 查看容器运行时:crictl info;systemctl status containerd
- 查看 kubelet 与 kubeadm 版本:kubelet --version;kubeadm version
- 统一修复动作(所有节点)
- 关闭 Swap:swapoff -a;sed -i ‘/swap/s/^/#/’ /etc/fstab
- 加载与持久化内核模块:modprobe br_netfilter;modprobe overlay;echo -e “br_netfilter\noverlay” | tee /etc/modules-load.d/k8s.conf
- 开启桥接与转发:sysctl -p /etc/sysctl.d/k8s.conf(内容含 net.bridge.bridge-nf-call-iptables=1、net.bridge.bridge-nf-call-ip6tables=1、net.ipv4.ip_forward=1)
- 升级内核(如采用 ELRepo):按第二部分步骤安装 kernel-lt 5.4 并设为默认后重启
- 配置 containerd 为 SystemdCgroup:/etc/containerd/config.toml 中设置 SystemdCgroup = true,重启 containerd
- 安装并指定一致的 kubelet/kubeadm/kubectl 版本(如 1.24.17 或 1.33.x),kubeadm init 时正确设置 criSocket 与 podSubnet
- 安装 CNI(Flannel 用 10.244.0.0/16,Calico 常用 192.168.0.0/16),确保与 kubeadm 配置一致
- 验证
- 节点就绪:kubectl get nodes;kubectl get pods -A
- 网络基线:节点间 iperf3 吞吐应接近物理带宽;无异常丢包与极高重传
- 稳定性:长时间拉起/销毁 Pod,观察 kubelet 与容器运行时无频繁重启或 OOM