云原生时代下 K8s CGroup/CRI 的优劣势

k8s-1



前言

在 v1.24 版本之前的 k8s 直接集成了 Docker Engine 组件,但从 v1.24 版本起,Kubernetes 项目正式移除了 Dockershim,也就是说 K8s 不再唯一支持以 Docker 作为 K8s 容器运行时。尽管移除了 Dockershim,但这并不代表 Docker 不可用,我们依然可通过容器运行时接口(CRI)来将 Docker 作为 K8s 的容器运行时。

容器运行时部署于 K8s 集群的 work 节点上,以使得 Pod 可以正常运行。

常见容器运行时:

  • Containerd
  • CRI-O
  • Docker Engine
  • Mirantis Container Runtime

一、CGroup

1.1 基本概念

CGroup 相信大家并不陌生,只要接触过 Docker 容器技术的应该都用过。CGroup 是 Linux 的一个底层技术,用于限制分配给系统进程的资源。

在我前面的 K8s 集群部署文档中,我们知道 kubelet 和底层容器运行时需要对控制组实现 Pod 和容器资源管理和限制(如 CPU、内存等资源设置请求和限制)。因此,想要对接 K8s 控制组,关键点就在于 kubelet 和容器运行时需要使用同一个 cgroup 驱动。

CGroup 驱动有一下两种:

  • cgroupfs
  • systemd

1.2 cgroupfs 驱动

1.2.1 基本概念

cgroupfs 驱动 是 kubelet 中默认的 cgroup 驱动,当使用 cgroupfs 驱动时, kubelet 和容器运行时将直接对接 cgroup 文件系统来配置 cgroup。

当你的系统是以 systemd 作为初始化时,不推荐使用 cgroupfs 驱动,因为 systemd 期望系统上只有一个 cgroup 管理器。 此外,如果你的系统使用的 cgroup v2 版本,则应用 systemd cgroup 驱动取代 cgroupfs

1.2.2 什么是 cgroup v2

Linux 中有两个 cgroup 版本:cgroup v1 和 cgroup v2。cgroup v2 是新一代的 cgroup API,cgroup v2 提供了一个具有增强资源管理能力的统一控制系统。一些 Kubernetes 特性专门使用 cgroup v2 来增强资源管理和隔离,因此,推荐使用 systemd 来作为 cgroup 驱动,从而可提升更好的资源管理效果。

如何查看 Linux 节点上的 cgroup 版本?

stat -fc %T /sys/fs/cgroup/

# 对于 cgroup v2,输出为 cgroup2fs
# 对于 cgroup v1,输出为 tmpfs

下图的 cgroup 版本为 v1

image-20221026113557429

1.2.3 cgroup v2 使用要求
  • 操作系统发行版启用 cgroup v2
  • Linux 内核为 5.8 或更高版本
  • 容器运行时支持 cgroup v2
  • kubelet 和容器运行时被配置为使用 systemd cgroup 驱动

1.3 systemd cgroup 驱动

1.3.1 基本概念

当某个 Linux 系统发行版使用 systemd 作为其初始化系统时,初始化进程会生成并使用一个 root 控制组(cgroup),并充当 cgroup 管理器。

systemd 与 cgroup 集成紧密,并将为每个 systemd 单元分配一个 cgroup。 因此,如果你 systemd 用作初始化系统,同时使用 cgroupfs 驱动,则系统中会存在两个不同的 cgroup 管理器。

同时存在两个 cgroup 管理器将造成系统中针对可用的资源和使用中的资源出现两个视图。某些情况下, 将 kubelet 和容器运行时配置为使用 cgroupfs、但为剩余的进程使用 systemd 的那些节点将在资源压力增大时变得不稳定。

当 systemd 是选定的初始化系统时,缓解这个不稳定问题的方法是针对 kubelet 和容器运行时将 systemd 用作 cgroup 驱动。

1.3.2 kubelet 设置 cgroup 驱动

如:将 systemd 设置为 cgroup 驱动

编辑 KubeletConfigurationcgroupDriver 选项,并将其设置为 systemd

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
...
cgroupDriver: systemd

下图为我博客截图:

image-20221026120542791

注意:更改已加入集群的节点的 cgroup 驱动是一项敏感的操作。 如果 kubelet 已经使用某 cgroup 驱动的语义创建了 Pod,此时更改运行时以使用别的 cgroup 驱动,当为现有的 Pod 重新创建 PodSandbox 时会产生错误,该错误重启 kubelet 也可能无法解决此类问题,只能重新部署 K8s 集群,因此对于一个正在正常运行的 K8s 集群,我们就最好不要动其 cgroup 驱动了。

二、CRI

这里我以 Kubernetes 1.24 举例,因为我部署的就是该版本的 k8s 集群。

各位小伙伴也可以尝试以二进制方式部署一下 K8s 集群,会有很大收获。

什么是 CRI?其实 CRI 就是我们的容器运行时接口,可以通过 CRI 来实现 K8s 来集成不同的容器组件。

首先,对于 Kubernetes 1.24 集群,你的容器运行时必须至少支持 v1alpha2 版本的容器运行时接口。因为 Kubernetes 1.24 默认使用 v1 版本的 CRI API。如果容器运行时不支持 v1 版本的 API, 则 kubelet 会回退到使用(已弃用的)v1alpha2 版本的 API。

2.1 Containerd

2.1.1 基本概念

什么是 Containerd ?这里不过多解释,简单的说:Containerd 不需要经过 dockershim,是一个工业级标准的容器运行时,它强调简单性、健壮性和可移植性。在 Linux 上,containerd 的默认 CRI 套接字是 /run/containerd/containerd.sock

2.1.2 配置 CGroup 驱动

以 systemd 驱动为例

1、安装 Containerd

2、生成配置文件

mkdir -p /etc/containerd && containerd config default > /etc/containerd/config.toml

3、修改配置文件

vim /etc/containerd/config.toml
...
SystemdCgroup = true
# 将 SystemdCgroup = false 改为 SystemdCgroup = true
...
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.7"
# 将 sandbox_image = "k8s.gcr.io/pause:3.6" 改为:sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.7"

4、启动 Containerd

systemctl enable containerd && systemctl start containerd

2.2 CRI-O

2.2.1 基本概念

对 CRI-O 没有过多的研究,CRI-O 是一个由 redhat 发起并开源且由社区驱动的 container-runtime,专为 K8s 而生。这里就不过多介绍,感兴趣的化可以深入研究。

CRI-O 默认使用 systemd cgroup 驱动程序,可编辑 /etc/crio/crio.conf 或在 /etc/crio/crio.conf.d/02-cgroup-manager.conf 中放置一个插入式配置,具体操作如下。

2.2.2 配置 CGroup 驱动
[crio.runtime]
conmon_cgroup = "pod"
cgroup_manager = "cgroupfs"
...
[crio.image]
pause_image="registry.aliyuncs.com/google_containers/pause:3.7"
...

# 将 pause_image="registry.k8s.io/pause:3.6" 改为 pause_image="registry.aliyuncs.com/google_containers/pause:3.7"

当使用 CRI-O 时,并且 CRI-O 的 cgroup 设置为 cgroupfs 时,必须将 conmon_cgroup 设置为值 pod

2.3 Docker Engine

2.3.1 基本概念

Docker 就不用多说,各位想必再熟悉不过了。想要使用 docker 作为 k8s 的编排对象,那需要安装 cri-docker 来作为 dockershim。对于 cri-dockerd,默认情况下,CRI 套接字是 /run/cri-dockerd.sock

cri-docker 源码安装地址:https://github.com/Mirantis/cri-dockerd

2.3.2 配置 CGroup 驱动

修改 CGroup 为 systemd

image-20221026150427417

修改沙箱镜像为国内源

...
[Service]
Type=notify
ExecStart=/usr/local/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.7
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
...

# 在 ExecStart= 部分添加即可

修改完成后重启 Docker 即可

systemctl restart docker.service

2.4 Mirantis

Mirantis Container Runtime (MCR) 是一种商用容器运行时,以前称为 Docker 企业版,可以使用 MCR 中包含的开源 cri-dockerd 组件将 Mirantis Container Runtime 与 Kubernetes 一起使用。

更多 Mirantis 相关知识,可阅读其官方文档。

看了这么多容器运行时,没有谁好谁坏,适合自己公司业务的就是最好的

<点击跳转至开头>


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云计算-Security

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值