cgroup驱动的选择:cgroupfs 或 systemd
在 Linux 上,控制组(CGroup)用于限制分配给进程的资源。
kubelet 和 底层容器运行时 都需要对接控制组,以强制对Pod和容器进行资源管理和资源配置,如CPU和内存资源的请求和限制。若要对接控制组,kubelet 和 容器运行时 需要使用一个cgroup驱动。关键的一点是kubelet和容器运行时需使用相同的cgroup驱动,并且采用相同的配置。
可用的 cgroup 驱动有两个:
- cgroupfs
- systemd
1. cgroupfs 驱动
cgroupfs驱动 是kubelet中默认的cgroup驱动。当使用cgroupfs驱动时,kubelet和容器运行时将直接对接cgroup文件系统来配置 cgroup。
当某个Linux系统发行版使用systemd作为其初始化系统时(例如 RedHat7/CentOS7),则不推荐使用cgroupfs驱动,因为systemd期望系统上只有一个cgroup管理器。
此外,如果你使用 cgroup v2 ,则应用systemd cgroup驱动取代cgroupfs。
由于 kubeadm 把 kubelet 视为一个系统服务来管理,所以对基于 kubeadm 的安装, 我们推荐使用 systemd 驱动,不推荐 cgroupfs 驱动。
2. systemd cgroup 驱动
当某个Linux系统发行版使用systemd作为其初始化系统时(例如 RedHat7/CentOS7),初始化进程会生成并使用一个root控制组(cgroup),并充当cgroup管理器。
systemd 与 cgroup 集成紧密,并将为每个systemd单元分配一个cgroup。因此,如果你systemd用作初始化系统,同时使用cgroupfs驱动,则系统中会存在两个不同的cgroup管理器。
同时存在两个cgroup管理器将造成系统中针对可用的资源和使用中的资源出现两个视图。某些情况下,配置为对kublet和容器运行时使用cgroupfs、但对其余进程使用systemd的节点,在资源压力增大时会变得不稳定。
当systemd是选定的初始化系统时,缓解这个不稳定问题的方法是选择systemd作为kubelet和容器运行时的cgroup驱动。
要将systemd设置为cgroup驱动,需编辑 KubeletConfiguration 的 cgroupDriver 选项,并将其设置为systemd。例如:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
...
cgroupDriver: systemd
如果你将systemd配置为kubelet的cgroup驱动,你也必须将systemd配置为容器运行时的cgroup驱动。以containerd为例,结合 runc使用systemd cgroup驱动,在/etc/containerd/config.toml中设置:
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
注意!
更改已加入集群的节点的cgroup驱动是一项敏感的操作。如果kubelet已经使用某种cgroup驱动的语义创建了Pod,更改运行时以使用别的cgroup驱动,当为现有Pod重新创建PodSandbox时会产生错误。重启kubelet也可能无法解决此类问题。
如果你有切实可行的自动化方案,使用其他已更新配置的节点来替换该节点,或者使用自动化方案来重新安装。
3. 总结
cgroup驱动的选择,总结如下:
- 当某个Linux系统发行版使用systemd作为其初始化系统时(例如 RedHat7/CentOS7),推荐使用systemd cgroup驱动;
- 当Kubernetes集群基于kubeadm安装管理时,推荐使用systemd cgroup驱动;
- 如果使用 cgroup v2,则应使用systemd cgroup驱动替代cgroupfs;
- 其他情况自行选择 cgroupfs 或 systemd;