我到底应该使用哪个 CRI 替换 kubernetes 集群的 Docker?

共 3360字,需浏览 7分钟

 ·

2021-01-30 11:45

前一段时间 kubernetes 对 docker 的弃用引起了不小的讨论,但其实 docker 并不是 kubernetes 中的 CRI 唯一实现。那么除了 docker 之外,我们还可以使用其他什么 CRI 呢?

下面是我已经测试的几个 CRI,并进行一些基准测试来对他们进行了简单的对比,希望对你有所帮助:

  • dockershim
  • containerd
  • crio

对于 cri-o,已经测试了2个后端:runc 和 crun,以测试对 cgroupsv2 的影响。

测试环境

我这里的测试环境是一个 1.19.4 版本的 kubernetes 集群,使用 ansible 进行创建(https://gitlab.com/incubateur-pe)。集群运行在 kvm 上,配置如下:

  • master:Centos/7, 2vcpus/2G内存。
  • crio-crun 节点:Fedora-32, 2vcpus/4G内存。
  • 其他节点:Centos/7, 2vcpus/4G内存.

底层是 i7-9700K ,64G的内存和一个 mp510 nvme 硬盘。

创建集群

这里我直接使用 molecule 创建一个集群,并配置了它在每个 worker 节点上使用不同的 cri,对应的 ansible 源码位于:https://gitlab.com/incubateur-pe/kubernetes-bare-metal/-/tree/dev/molecule/criBench

使用上面的脚本,执行 molecule converge 命令后,大概10分钟左右,我们就可以得到一个如下所示的 kubernetes 集群。

接下来我们就可以进行一些简单的基准测试了。

测试

1. bucketbench 测试

Bucketbench (https://github.com/estesp/bucketbench) 是一个可以对容器引擎执行一系列操作的测试工具,它非常适合于了解之前每个节点的性能。

这里我们的测试参数很简单:

  • 3个线程
  • 15次循环
  • run/stop/delete 操作

对应的结果如下所示(ms 为单位):

我们可以看到在性能上还是有相当大的差异的。但是需要注意的是我们这里为什么测试了5个实例呢?上面不是只有4个 worker 节点吗?

这里其实是因为这里我们使用的 docker 客户端并不是 kubernetes 使用的,事实上 docker 实现了 CRI,并提供了一个 socket,这个 socket 和其他 cri socket 一样可以调用。所以这里的区别是:

  • docker-shim:是通过 cri 的 socket 来做测试
  • docker-cli:是通过 docker 客户端来做测试

但是实际上 docker 并没有想象中那么差,在这个测试中我们可以看到他比 cri-o 要快点,当然这个测试中很明显 dockerd 是表现最好的。

2. kubernetes 测试

上面的测试并不能完整说明这几个 cri 之间的差距,当它们被 kubernetes 使用的时候,它们表现又如何呢?是否不止 run/stop/delete 这些操作?性能上的差异在真正的集群上又有什么意义吗?

下面我们就来深入了解下,这次我们使用集群中的 Prometheus、Grafana 来可视化监控指标,对应的自定义 dashboard 数据可以在 https://gitlab.com/ulrich.giraud/bench-cri/-/blob/master/dashboard/dashboard_bench.json 这里获取。由于只是测试容器运行时,不是工作负载,所以这里我们只是简单的在集群中部署的一个 busybox 镜像并一直 sleep 的 DaemonSet 应用。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: benchds-replaceme
  namespace: benchds
  labels:
    k8s-app: benchds
spec:
  selector:
    matchLabels:
      name: benchds
  template:
    metadata:
      labels:
        name: benchds
    spec:
      containers:
      - name: benchds
        image: busybox:latest
        command:
          - sleep
          - infinity
        resources:
          limits:
            memory: 20Mi
          requests:
            cpu: 10m
            memory: 20Mi

该 DamonSet 将用唯一的名称进行部署:

  • 100次(两次创建之间有一定延迟)
  • 批量 100次
  • 批量 1000次

对应的 Grafana 展示图表信息如下所示:

缓慢创建数百个 DaemonSets

快速创建数百个 DaemonSets

快速创建数千个 DaemonSets

现在我们来分析下上面的测试结果。

  • Cri-o/runc:令人惊讶的是,在所有 create/delete 中是最慢的,但在其他方面处于中等水平。
  • Cri-o/crun:在 create/delete 方面不是很好,但是在其他方面表现是最好的。
  • Containerd:表现非常好,几乎在所有情况下都可以快速响应。
  • Docker:在 create/delete 方面比 cri-o 快,但在 status/list 请求方面是最慢的。

status/list 请求是 cri 上最频繁的请求,所以这也是性能最重要的地方,cri-o 在这里似乎是更好的选择,其次就是 containerd。

containerd 在所有指标上的表现都比较好,应该是最均衡的一个选择了。另外一方面,docker 并没有得到很好的测试结果,但是无论负载情况如何,它的表现基本上都是一致的。

总结

从纯性能角度来说,确实有比 docker 更好的替代品,我们的集群也不会替换 docker 产生什么影响。从另外一个角度来看,kubernetes 这次废弃 docker 的事情也算是一件好事,让更多的人意识到 docker 并不是唯一可用的 CRI,甚至不是唯一的构建镜像工具。

在我看来,docker 仍然是让整个容器化向前发展的一个伟大工具。但是好像我还没有回答我最初的问题,那就是:我应该为我的k8s集群使用什么CRI?

从我个人角度考虑的话,我个人的选择是:containerd,他速度快,配置方便,相当可靠和安全,不过 cri-o 已经支持 cgroupsv2 了,所以如果我使用 fedora 或者 centos/8 的话我会优先选择 cri-o。

原文链接:https://ulrich-giraud.medium.com/which-cri-should-i-use-to-replace-docker-for-my-kubernetes-cluster-14a45c080004


进阶训练营第二期

本次训练营采用线上直播的形式,基于1.19.x版本,根据第1期课程的打磨,我们总结出了 Docker 基础 + Kubernetes 基础 + 原理 + 基本使用 + 进阶技能 + 完整项目实践 的课程体系。加强系统知识吸收夯实基础的同时,并在实际操作过程中去了解排查问题的方式方法,更为重要的是我们的老师非常负责任,随时帮你答疑解惑,我们认为不只是课堂上讲授知识,更重要的是售后支持,完全不用担心学习不到知识。


 点击屏末  | 即刻学习

浏览 152
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报