文章转自:分布式实验室

原文链接:https://towardsdatascience.com/its-time-to-say-goodbye-to-docker-5cfec8eff833

Docker并不是唯一的容器化工具,可能还有更好的选择……

在容器的早期时代(其实更像是4年前),Docker是容器游戏中唯一的玩家。但现在情况已经不一样了,Docker不再是唯一的一个,而只是其中一个容器引擎而已。Docker允许我们构建、运行、拉、推或检查容器镜像,然而对于每一项任务,都有其他的替代工具,甚至可能比Docker做得还要好。所以,让我们探索一下,然后再卸载(只是可能),直至完全忘记Docker……

那,为什么不再用Docker了?

如果你已经使用Docker很长时间了,估计要真正说服你去考虑其他工具,得先提供些依据。

首先,Docker是一个单体工具。它尝试去涵盖所有的功能,通常这并不是最佳实践。大多数情况下,我们都是只选择一种专门的工具,它只做一件事,并且做得非常好,非常精。

如果害怕切换到不同的工具集是因为将不得不学习使用不同的CLI、API或者说不同的概念,那么这不会是一个问题。本文中展示的任何工具都可以是完全无缝的,因为它们(包括Docker)都遵循OCI (Open Container Initiative)下的相同规范。它们包含了容器运行时、容器分发和容器镜像的规范,其中涵盖了使用容器所需的所有特性。

有了OCI,你可以选择一套最符合你需求的工具,同时你仍然可以享受跟Docker一样使用相同的API和CLI命令。

所以,如果你愿意尝试新的工具,那么让我们比较一下Docker和它的竞争对手的优缺点和特性,看看是否有必要考虑放弃Docker,使用一些新的闪亮的工具。

容器引擎

在比较Docker和其他工具时,我们需要将其分解为组件,首先我们先讨论一下容器引擎。Container Engine是一种工具,它为处理镜像和容器提供用户界面,这样就不必处理SECCOMP规则或SELinux策略之类的事情。它的工作还包括从远程仓库提取镜像并将其扩展到磁盘。它看起来也是运行容器,但实际上它的工作是创建容器清单和带有镜像层的目录。然后它将它们传递到容器运行时,如runC或Crun(稍后我们将讨论这一点)。

目前已经有许多容器引擎,但Docker最突出的竞争对手是由红帽开发的Podman。与Docker不同,Podman不需要Daemon来运行,也不需要root特权,这是Docker长期以来一直关注的问题。基于它的名字,Podman不仅可以运行容器,还可以运行pods。如果你不熟悉pods的概念,其实,简单的概括就是,Pod是Kubernetes的最小计算单元。它由一个或多个容器(主容器和执行支持任务的Sidecar)组成,这使得Podman用户以后更容易将他们的工作负载迁移到Kubernetes。因此,作为一个简单的演示,这是如何在一个Pod中运行两个容器:

\~ \$ podman pod create --name mypod  \~ \$ podman pod list  POD ID         NAME    STATUS    CREATED         # OF CONTAINERS   INFRA ID  211eaecd307b   mypod   Running   2 minutes ago   1                 a901868616a5  \~ \$ podman run -d --pod mypod nginx  # First container  \~ \$ podman run -d --pod mypod nginx  # Second container  \~ \$ podman ps -a --pod  CONTAINER ID  IMAGE                           COMMAND               CREATED        STATUS            PORTS  NAMES               POD           POD NAME  3b27d9eaa35c  docker.io/library/nginx:latest  nginx -g daemon o...  2 seconds ago  Up 1 second ago          brave\_ritchie       211eaecd307b  mypod  d638ac011412  docker.io/library/nginx:latest  nginx -g daemon o...  5 minutes ago  Up 5 minutes ago         cool\_albattani      211eaecd307b  mypod  a901868616a5  k8s.gcr.io/pause:3.2                                  6 minutes ago  Up 5 minutes ago         211eaecd307b-infra  211eaecd307b  mypod

最后,Podman提供了与Docker完全相同的CLI命令,因此只需执行alias docker = podman并装作什么都没有改变。

除了Docker和Podman之外,还有其他的容器引擎,但我个人认为它们都是没什么出路的技术,或者都不太适合本地开发和使用。但是,要全面了解,至少要看一下其中的内容:

  • LXD——LXC (Linux Containers)是一个容器管理器(守护进程)。该工具提供了运行系统容器的能力,这些系统容器提供了更类似于VM的容器环境。它位于非常狭窄的空间,没什么用户,所以除非你有非常具体的实例,否则最好还是使用Docker或Podman。

  • CRI-O——当你Google什么是CRI-O你可能会发现它被描述为容器引擎。不过,实际上它只是容器运行时。其实它既不是引擎,也不适合“正常”使用。我的意思是,它是专门为Kubernetes运行时(CRI)而构建的,而不是为最终用户使用的。

  • Rkt——rkt(“Rocket”)是由CoreOS开发的容器引擎。这里提到这个项目只是为了完整性,因为这个项目已经结束,开发也停止了——所以也就没必要再使用了。

构建镜像

对于容器引擎来说,一般都只选择Docker。但是,当涉及到构建镜像时,选择的余地还是比较多的。

首先,介绍一下Buildah。Buildah是红帽开发的另一个工具,它与Podman配合使用相当合适。如果已经安装了Podman,你可能会注意到podman build子命令,它实际上只是伪装的Buildah,因为它的二进制文件已经包含在Podman里。

至于它的特性,它遵循了与Podman相同的路线——无守护程序和无根的,并遵循OCI的镜像标准,所以它能保证所构建的镜像和Docker构建的是一样的。它还能够从Dockerfile或更恰当的命名Containerfile来构建镜像,Dockerfile和Containerfile都是相同的,只是命名的区别。除此之外,Buildah还对镜像层提供了更精细的控制,允许在单层中提交更多变更。唯一的例外是(在我看来)与Docker的区别是,由Buildah构建的镜像是基于用户的,因此用户可以只列出自己构建的镜像。

那么,考虑到Buildah已经包含在Podman CLI中,大家可能会问,为什么还要使用单独的Buildah CLI?Buildah CLI是podman build中包含的命令的超集,所以基本不需要单独接触Buildah CLI,但是通过使用它,你可能还会发现一些额外有用的特性(有关podman build和buildah之间的差异的细节,请参阅这个文章[1])。

现在,我们来看看一个演示:

\~ \$ buildah bud -f Dockerfile .  \~ \$ buildah from alpine:latest  # Create starting container - equivalent to "FROM alpine:latest"
Getting image source signatures
Copying blob df20fa9351a1 done
Copying config a24bb40132 done
Writing manifest to image destination
Storing signatures
alpine-working-container  # Name of the temporary container
\~ \$ buildah run alpine-working-container -- apk add --update --no-cache python3  # equivalent to "RUN apk add --update --no-cache python3"
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86\_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86\_64/APKINDEX.tar.gz
...  \~ \$ buildah commit alpine-working-container my-final-image  # Create final image
Getting image source signatures
Copying blob 50644c29ef5a skipped: already exists
Copying blob 362b9ae56246 done
Copying config 1ff90ec2e2 done
Writing manifest to image destination
Storing signatures
1ff90ec2e26e7c0a6b45b2c62901956d0eda138fa6093d8cbb29a88f6b95124c  \~ # buildah images
REPOSITORY               TAG     IMAGE ID      CREATED         SIZE
localhost/my-final-image latest  1ff90ec2e26e  22 seconds ago  51.4 MB

从上面的脚本可以看到,我们可以只用buildah bud构建镜像,bud代表使用Dockerfile构建,但是你还可以使用更多Buildahs的脚本:from,run和copy,这些命令对应命令Dockerfile的(FROM image,RUN…,COPY…)。

下一个是谷歌的Kaniko。Kaniko也是从Dockerfile构建容器镜像,跟Buildah类似,也不需要守护进程。与Buildah的主要区别在于,Kaniko更专注于在Kubernetes中构建镜像。

Kaniko使用gcr.io/ Kaniko -project/executor作为镜像运行。这对于Kubernetes来说是行得通的,但是对于本地构建来说不是很方便,并且在某种程度上违背了它的初衷,因为我们得先使用Docker来运行Kaniko镜像,然后再去构建镜像。也就是说,如果正在为Kubernetes集群中构建镜像的工具进行选型(例如在CI/CD Pipeline中),那么Kaniko可能是一个不错的选择,因为它是无守护程序的,而且(可能)更安全。

从我个人的经验来看——我在Kubernetes/OpenShift集群中使用了Kaniko和Buildah来构建镜像,我认为两者都能很好地完成任务,但在使用Kaniko时,我看到了一些将镜像导入仓库时的,会有随机构建崩溃和失败的情况。

第三个竞争者是Buildkit,也可以称为下一代的Docker build。它是Moby项目的一部分。在Docker里可以使用DOCKER_BUILDKIT=1 Docker build…作为实验特性进行启用。那么,它的核心价值到底有哪些?它引入了许多改进和炫酷的特性,包括并行构建、跳过未使用的阶段、更好的增量构建和无根构建。然而另一方面,它仍然需要运行守护进程(buildkitd)才能运行。所以,如果你不想摆脱Docker,但是想要一些新的特性和更好的改进,那么使用Buildkit可能是最好的选择。

和前面一样,这里我们也还有一些“光鲜亮丽的产品”,它们也都有非常具体的场景,虽然并不是我们的首选:

  • Source-To-Image(S2I)是一个不需要Dockerfile直接从源代码构建镜像的工具包。这个工具在简单的、预期的场景和工作流中运行的很好,但是如果有太多的定制,或者该项目没有预期的布局,你很快就会觉得这个工具很烦人和笨拙。如果你对Docker还不是很有信心,或者如果在OpenShift集群上构建镜像,那么你可以尝试考虑一下使用S2I,因为使用S2I构建是一个内置特性。

  • Jib是谷歌的另一个工具,专门用于构建Java镜像。它包括Maven和Gradle插件,可以轻松地构建镜像,而不会干扰Dockerfile。

  • 最后一个但并不是不重要的是Bazel,它是谷歌的另一款工具。它不仅用于构建容器镜像,而且是一个完整的构建系统。如果你只是想构建一个镜像,那么钻研Bazel可能有点过头,但绝对是一个很好的学习体验,所以如果你想尝试,rules_docker绝对是一个很好的起点。

容器运行时

最后一个大块儿是容器运行时,它负责运行容器。容器运行时是整个容器生命周期/栈的一部分,除非你对速度、安全性等有一些非常具体的要求,否则一般是不需要对其进行干扰。所以,如果读者看到这里已经厌倦,那么可以跳过这一部分。如果不是,那么有关容器运行时的选择,如下:

runC是基于OCI容器运行时规范创建的,且最流行的容器运行时。Docker(通过containerd)、Podman和crio使用它,所以几乎所有东西都依赖于LXD。它几乎是所有产品/工具的默认首选项,所以即使你在阅读本文后放弃Docker,但你仍然会用到runC。

runC的另一款替代方产品为Crun,名称类似(容易混淆)。这是Red Hat开发的工具,完全用C编写(runC是用Go编写的)。这使得它比runC更快,内存效率更高。考虑到它也是OCI兼容的运行时。所以,如果你想做个测试,切换起来很容易。尽管它现在还不是很流行,但在RHEL 8.3技术预览版中,它将作为一个替代OCI运行时,同时,考虑到它是红帽的产品,我们可能最终会看到它会成为Podman或CRI-O的默认首选项。

说到CRI-O。前面我说过,CRI-O实际上不是一个容器引擎,而是容器运行时。这是因为CRI-O不包括比如推送镜像这样的特性,而这正是容器引擎的特性。作为运行时的CRI-O在内部使用runC运行容器。通常情况下不需要在单机尝试这个工具,因为它被构建为用于Kubernetes节点上的运行时,可以看到它被描述为“Kubernetes需要的所有运行时,仅此而已”。因此,除非你正在设置Kubernetes集群(或OpenShift集群——CRI-O已经是默认首选项了),否则不大可能会接触到这个。

本节的最后一个内容是containerd,它是CNCF的一个毕业的项目。它是一个守护进程,充当各种容器运行时和操作系统的API。在后台,它依赖于runC,是Docker引擎的默认运行时。谷歌Kubernetes引擎(GKE)和IBM Kubernetes服务(IKS)也在使用。它是Kubernetes容器运行时接口的一个部署(与CRI-O相同),因此它是Kubernetes集群运行时的一个很好的备选项。

镜像检测与分发

容器栈的最后一部分是镜像的检测与分发。这有效地替代了docker inspect,还(可选地)增加了远程镜像仓库之间复制/映射镜像的能力。

这里唯一要提到的可以完成这些任务的工具是Skopeo。它由红帽公司开发,是Buildah,Podman和CRI-O的配套工具。除了我们都从Docker中知道的基本的skopeo inspect之外,Skopeo还能够使用skopeo copy复制镜像,它允许你在远程镜像仓库之间映射镜像,而无需先将它们拉到本地仓库。如果你使用本地仓库,此功能也可以作为pull/push。

另外,我还想提一下Dive,这是一个检查、探测和分析镜像的工具。它对用户更友好一些,提供了更可读的输出,可以更深入地探测镜像,并分析和衡量其效率。它也适合在CI管道中使用,它可以测量你的镜像是否“足够高效”,或者换句话说——它是否浪费了太多空间。

结论

本文的目的并不是要说服大家完全抛弃Docker,而是向大家展示构建、运行、管理和分发容器及其镜像的整个场景和所有选项。包括Docker在内的每一种工具都有其优缺点,评估哪一组工具最适合你的工作流和场景才是最重要的,真心希望本文能在这方面帮助到你。

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:

长按订阅更多精彩▼如有收获,点个在看,诚挚感谢

Docker不再是唯一的选择相关推荐

  1. 超低时延交换机,让Infiniband交换机不再是唯一的选择

    近期与同事去某物理所技术交流,满机房的都是IB 交换机,十分壮观. 然而,客户这次叫我们来,目的却是想换掉他们,一台不留.客户无奈地说,IB 交换机的时延方面,没得说,但是"想买到" ...

  2. 除了 Docker,我们还有哪些选择?

    来源 | CSDN 编译 | 弯月 责编 | 张文 头图 | CSDN下载于视觉中国 [编者按]所谓三十年河东,三十年河西,曾经在容器领域叱咤风云的 Docker 如今已风光不再.抛开情怀,我们不得不 ...

  3. 盘点2015年可能上市的19家互联网公司,IPO不再是唯一终点

    盘点2015年可能上市的19家互联网公司,IPO不再是唯一终点  2015-04-06 19:21   生活杂记   标签:科技 应用   1303    发表评论 2014年是中概股全面丰收的一年, ...

  4. 山腰中的AMD,向前是唯一的选择

    本周的焦点集中在芯片双雄,英特尔和AMD近日陆续发布了新财年第一季度的财报,可以看出,两家在本季的表现均引起了业界的关注.早在3月,英特尔已确定闪存价崩会损害本季的获利,结果证实受累闪存,英特尔净利同 ...

  5. 在深度学习模型的优化上,梯度下降并非唯一的选择

    如果你是一名机器学习从业者,一定不会对基于梯度下降的优化方法感到陌生.对于很多人来说,有了 SGD,Adam,Admm 等算法的开源实现,似乎自己并不用再过多关注优化求解的细节.然而在模型的优化上,梯 ...

  6. bsd是linux发行版本,BSD推新版本 Linux不再是唯一开源操作系统

    1月8日消息,从07年1月1日起,Linux不再是唯一的开源操作系统了.BSD推出的最新版本PC-BSD1.3,开始开源操作系统的尝试. 据internetnews.com报道,新版PC-BSD基于F ...

  7. 求出N×M整型数组的最大元素及其所在的行坐标及列坐标(如果最大元素不唯一,选择位置在最前面的一个)。

    功能:求出N×M整型数组的最大元素及其所在的行坐标及 列坐标(如果最大元素不唯一,选择位置在最前面 的一个). 例如:输入的数组为: 1 2 3 4 15 6 12 18 9 10 11 2 求出的最 ...

  8. 你是为了什么而努力?不放弃才是我们唯一的选择,加油,每一个有缘人

    这篇博客就不写什么知识点了,就是说下自己目前的心态.(可以看到的人说明也是一种缘分,希望你不要放弃,我们一起加油) 没有想赢 只是不想输 首先自报家门 我是专科,今年大三,等到六月份的时候就要毕业了, ...

  9. 大数据时代,票房不再是唯一

    经历了数代学院派导演在艺术上的探索和产业化白手起家的拓荒,电影不再只是"声光电"的艺术形式,更开启了一个雄心勃勃的市场化运作的时代.众多资本的涌入,一方面创造出巨大的利益空间,另一 ...

最新文章

  1. 让我们定义一个ggplot版本的华夫饼图吧
  2. Linux|UNIX下LAMP环境的搭建及常见问题[连载3]
  3. linux-shell命令之cp(copy)【拷贝复制】
  4. STM32工作笔记006---常见硬件介绍-以及常见术语--随时更新
  5. 计算机毕业设计中基于Java和MySQL的图书管理系统
  6. RoaringBitmap 原理
  7. (一) pyhon 基础语法(数值 字符串 元组 列表 字典)
  8. easyui datagrid一般创建模板
  9. Axure中继器基础教程(增行、删当前、标记、全部、规则行) Mark
  10. [基本功]假设检验概念统计量一览
  11. 各大IT公司、软件公司员工等级(级别)及薪资
  12. “少年派”生命里的上帝与野兽
  13. 小象学院python网课值得吗-小象学院Python数据分析第二期【升级版】
  14. Oracle数据库配置完全实战手册
  15. html win10虚拟键盘,五种打开win10虚拟键盘的方法 win10虚拟键盘快捷键
  16. VC 控制台颜色设置
  17. 【JVM学习笔记】内存回收与内存回收算法 就哪些地方需要回收、什么时候回收、如何回收三个问题进行分析和说明
  18. rutracker网站无法进入,解决方案来啦
  19. python字典操作题_python字典练习题
  20. 这个新品牌能止住SaaS领域不断传来的坏消息吗?

热门文章

  1. 教你如何防范远程桌面协议(RDP)的安全威胁
  2. java布局工具,Java Swing:库,工具,布局管理器
  3. java运行在用户态_理解Linux用户态和内核态
  4. 【Java】反射( reflection)机制 详解
  5. 解题报告(十五)莫比乌斯反演与积性函数(ACM / OI)
  6. 手写html5游戏,HTML5 手写输入法
  7. mysql5.7用declare声明失败_我可能会失败,但我不会一直失败。
  8. com.android.phone已停止 vivo,oppo,vivo应用程序终止通知不在android fcm中出...
  9. java ee开发技术 上海大学_学院介绍
  10. Metasploit 使用后门和Rootkit维持访问