kuberlet服务启动报错:"Failed to run kubelet" err="failed to run Kubelet: misconfiguration: kubelet cgroup driver: \"systemd\" is different from docker cgroup driver: \"cgroupfs\""
这是因为kubelet的cgroup和docker的不一致所导致的,“kubelet cgroup驱动为systemd,而docker的为cgroupfs”,有两种决解决方式,
方式一:修改docker的cgroup为systemd
修改docker服务的配置文件,“/etc/docker/daemon.json ”文件,添加如下
"exec-opts": ["native.cgroupdriver=systemd"]
重启dokcer服务:
sudo systemctl daemon-reload
sudo systemctl restart docker
修改后查看docker的cgroup
$ docker info |grep "Cgroup Driver"
Cgroup Driver: systemd #表明已经更新为了systemd
重启kuberlet:
systemctl restart kubelet
方式二:修改kubelet的cgroup为cgroupfs (不推荐)
修改Kubelet的配置文件:/var/lib/kubelet/config.yaml
cgroupDriver: cgroupfs
重启kuberlet:
systemctl restart kubelet
修改完成后,此时可以可以在目标node上,再次查看kubelet的事件,看看是否报错,或通过docker ps 、crictl ps工具查看目标容器是否被创建。
虽然解决了上面的问题,但是我们不禁产生一些疑问,什么是cgroup?systemd和cfgroupfs两种cgroup有什么区别?
cgroup 驱动
在 Linux 上,控制组(CGroup)用于限制分配给进程的资源。
kubelet 和底层容器运行时都需要对接控制组来强制执行 为 Pod 和容器管理资源 并为诸如 CPU、内存这类资源设置请求和限制。若要对接控制组,kubelet 和容器运行时需要使用一个 cgroup 驱动。 关键的一点是 kubelet 和容器运行时需使用相同的 cgroup 驱动并且采用相同的配置。
可用的 cgroup 驱动有两个:
cgroupfs 驱动
cgroupfs
驱动是 kubelet 中默认的 cgroup 驱动。当使用 cgroupfs
驱动时, kubelet 和容器运行时将直接对接 cgroup 文件系统来配置 cgroup。
当 systemd 是初始化系统时, 不 推荐使用 cgroupfs
驱动,因为 systemd 期望系统上只有一个 cgroup 管理器。 此外,如果你使用 cgroup v2, 则应用 systemd
cgroup 驱动取代 cgroupfs
。
systemd cgroup 驱动
当某个 Linux 系统发行版使用 systemd 作为其初始化系统时,初始化进程会生成并使用一个 root 控制组(cgroup
),并充当 cgroup 管理器。
systemd 与 cgroup 集成紧密,并将为每个 systemd 单元分配一个 cgroup。 因此,如果你 systemd
用作初始化系统,同时使用 cgroupfs
驱动,则系统中会存在两个不同的 cgroup 管理器。
同时存在两个 cgroup 管理器将造成系统中针对可用的资源和使用中的资源出现两个视图。某些情况下, 将 kubelet 和容器运行时配置为使用 cgroupfs
、但为剩余的进程使用 systemd
的那些节点将在资源压力增大时变得不稳定。
当 systemd 是选定的初始化系统时,缓解这个不稳定问题的方法是针对 kubelet 和容器运行时将 systemd
用作 cgroup 驱动。
要将 systemd
设置为 cgroup 驱动,需编辑 KubeletConfiguration
的 cgroupDriver
选项,并将其设置为 systemd
。例如:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
...
cgroupDriver: systemd
如果你将 systemd
配置为 kubelet 的 cgroup 驱动,你也必须将 systemd
配置为容器运行时的 cgroup 驱动。 参阅容器运行时文档,了解指示说明。例如: