【Docker】基于Docker18.09, 不同版本栈,关于cgroupDriver的选择

Huawei Cloud EulerOS 2.0 (aarch64) + Docker 18.09.0 + Kubernetes 1.20.10 的组合 , cgroupDriver驱动使用cgroupfs 还是 systemd ?

Huawei Cloud EulerOS 2.0(aarch64) + Docker 18.09.0 + K8s 1.20.10:必须选择 cgroupfs,不要用 systemd。

重要背景:Docker 18.09 默认cgroup驱动是cgroupfs;K8s 1.20 官方建议如果docker用systemd,kubelet也必须对齐systemd,但EulerOS 2.0+docker‑18.09开启systemd存在兼容性坑,不推荐。

1、底层限制说明

  1. Docker 18.09 年代特性
    • docker 18.09 原生默认cgroupfs
    • docker 18.09 的systemdcgroup驱动属于早期实现,稳定性差,在ARM(aarch64)欧拉2.0上容易出现:
      • cgroup层级错乱
      • kubelet无法识别容器资源配额
      • 节点压力大时容器卡死、kubelet异常重启
  2. Kubernetes 1.20.10规则

kubelet 的 cgroup 驱动必须和docker保持一致

  • docker=cgroupfs → kubelet=cgroupfs
  • docker=systemd → kubelet=systemd

两者不一致会导致kubelet启动失败。

2、两种方案对比(针对你的组合)

✅方案A(推荐,生产首选):docker=cgroupfs,kubelet=cgroupfs

优点:

  1. Docker18.09原生默认配置,欧拉2.0 arm环境经过大量验证,bug最少
  2. 部署简单,不需要修改systemd挂载参数、不需要额外开启cgroup v2
  3. K8s1.20完美兼容,社区该组合大量落地
    缺点:
  • 无法由systemd统一管理容器cgroup资源,资源隔离粒度弱于systemd驱动(但在18.09版本下这个代价可接受,稳定性优先)

❌方案B(不推荐):docker=systemd,kubelet=systemd

风险点(EulerOS2.0 aarch64上很常见)

  1. Docker18.09对systemd cgroup支持不完善,不是成熟版本(docker从20.10后systemd驱动才稳定)
  2. EulerOS 2.0内核+systemd版本和docker18.09存在ARM平台特有的cgroup层级问题
  3. 开启后容易出现kubelet日志报Failed to create cgroup、容器OOM判定异常

如果是docker≥20.10 + k8s≥1.22,才建议systemd驱动

3、落地配置模板(直接复制使用)

①修改docker daemon /etc/docker/daemon.json

{
  "exec-opts": ["native.cgroupdriver=cgroupfs"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}

重启docker:

systemctl daemon-reload
systemctl restart docker
#验证驱动
docker info | grep -i cgroup
#输出:Cgroup Driver: cgroupfs

②kubelet配置对齐cgroupfs

kubeadm安装场景,修改/var/lib/kubelet/config.yaml

cgroupDriver: cgroupfs

或者kubeadm初始化时指定:

kubeadm init --kubernetes-version=1.20.10 \
--apiserver-advertise-address=xxx \
--cgroup-driver=cgroupfs

手动部署kubelet:在kubelet启动参数增加--cgroup-driver=cgroupfs

4、补充提醒(EulerOS2.0 ARM特有注意事项)

  1. 确认内核开启cgroup子系统:cpu、cpuset、memory、blkio
  2. 不要开启cgroup v2,K8s1.20对cgroup v2支持不完善,本套组合只能使用cgroup v1
  3. 不要升级docker到20.x,一旦升级,最佳实践就变成systemd驱动

一句话总结

你的版本栈(Docker18.09 + K8s1.20.10 + EulerOS2.0 aarch64)稳妥路线是cgroupfs,避开systemd驱动的老旧bug。
如果你后续升级Docker至20.10+、K8s升级到1.24+,再切换为systemd。

不同版本栈,关于cgroupDriver的选择

CentOS7 + Docker 18.09.0 + Kubernetes 1.20.10  ,可以使用 systemd 作为 cgroupDriver

KylinV10SP3 + Docker 18.09.0 + Kubernetes 1.20.10 ,可以使用 systemd 作为 cgroupDriver

openEuler + Docker 18.09.0 + Kubernetes 1.20.10  ,必须使用 cgroupfs 作为 cgroupDriver

结论整理

  1. CentOS7 + Docker‑18.09.0 + K8s‑1.20.10 ✅支持systemd cgroup驱动
  2. KylinV10 SP3 + Docker‑18.09.0 + K8s‑1.20.10 ✅支持systemd cgroup驱动
  3. openEuler + Docker‑18.09.0 + K8s‑1.20.10 ❗不是必须cgroupfs,存在坑,很多文档直接强制cgroupfs是历史踩坑总结

我们下面把原理、风险、配置、验证完整说明:

重要前提:

  1. Docker 18.09 本身同时支持 cgroupfs / systemd,能不能用 systemd,核心不在K8s 1.20.10,而在于操作系统的systemd版本、内核、cgroup v1/v2、os发行版补丁
  2. K8s 1.20 对两种驱动都兼容,只是要求docker和kubelet驱动保持一致。

一、CentOS7 配置示例(systemd)

/usr/lib/systemd/system/docker.service

[Service]
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

修改 /etc/docker/daemon.json

{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {"max-size":"100m"},
  "storage-driver": "overlay2"
}

重启docker,kubelet自动识别,稳定可用

CentOS7 systemd=219,cgroup v1,无cgroup2,这套组合生产大量落地。

二、麒麟KylinV10 SP3 + Docker18.09 + K8s1.20.10(systemd可行)

KylinV10 SP3内核是4.19,默认cgroup v1,systemd版本适配cgroup v1,
daemon.json同上,native.cgroupdriver=systemd 可以正常运行。

️KylinV10后续SP版本部分开启cgroup2,Docker18.09不支持cgroup v2,这时systemd驱动会报错,只能cgroupfs;SP3默认cgroupv1无此问题。

三、openEuler + Docker‑18.09.0 + K8s‑1.20.10 重点说明

1)为什么很多运维文档写“必须cgroupfs”

openEuler 内核 4.19 / 5.x 版本特性:

  1. openEuler 部分版本默认编译开启 cgroup v2
  2. Docker 18.09 只支持 cgroup v1,完全不兼容cgroup v2
  3. 如果操作系统是cgroup v2,docker daemon设置native.cgroupdriver=systemd启动直接失败
Error response from daemon: cgroups: cannot found cgroup mountable

此时只能改为cgroupfs,这就是“必须cgroupfs”说法的来源。

2)区分两种场景

场景A:openEuler 使用cgroup v2(默认新版)

✅只能配置 "native.cgroupdriver":"cgroupfs"
❌不能使用systemd驱动,docker起不来

{
  "exec-opts": ["native.cgroupdriver=cgroupfs"],
  "log-driver": "json-file",
  "log-opts": {"max-size":"100m"},
  "storage-driver": "overlay2"
}

场景B:openEuler手动切换到cgroup v1(内核启动参数)

内核增加启动参数 systemd.unified_cgroup_hierarchy=0,重启后变成cgroup v1
此时 docker18.09可以正常使用systemd驱动

但是openEuler官方主推cgroup v2,强行切v1会丢失部分系统特性,不推荐生产这么做,工程最佳实践:openEuler+docker18.09直接用cgroupfs。

3)如何确认当前系统是cgroup v1/v2

#查看挂载
mount |grep cgroup
#或者
cat /sys/fs/cgroup/cgroup.controllers
#文件存在= cgroup v2;不存在= cgroup v1

四、K8s强制约束(所有平台通用,极易踩坑)

dockerd的cgroupdriver 和 kubelet 的cgroupdriver必须一模一样!

  1. docker用systemd → kubelet必须systemd
  2. docker用cgroupfs → kubelet必须cgroupfs
    不一致会导致kubelet启动失败、节点NotReady
    kubelet配置 /var/lib/kubelet/config.yaml
cgroupDriver: systemd
#或者
#cgroupDriver: cgroupfs

五、总结

  1. CentOS7:✅支持systemd
  2. KylinV10 SP3(默认cgroupv1):✅支持systemd;如果升级到开启cgroupv2的SP版本,则只能cgroupfs
  3. openEuler:不是绝对必须cgroupfs,取决于cgroup版本;默认cgroupv2环境下只能cgroupfs,不建议切v1强行上systemd,工程规范直接使用cgroupfs
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容