Docker不再是唯一的选择

标签: docker 唯一 选择 | 发表时间:2020-11-11 20:44 | 作者:frankinbj
出处:http://weekly.dockone.io

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(“火箭”)是由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之间的差异的细节,请参阅这个文章 https://podman.io/blogs/2018/1 ... .html。)
现在,我们来看看一个演示:

~ $ 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/ ... ar.gz
fetch http://dl-cdn.alpinelinux.org/ ... ar.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
view rawbuildah.sh hosted with ❤ by GitHub

从上面的脚本可以看到,我们可以只用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或crio的默认首选项。
说到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在内的每一种工具都有其优缺点,评估哪一组工具最适合你的工作流和场景才是最重要的,真心希望本文能在这方面帮助到您。

原文链接: https://towardsdatascience.com ... ff833

相关 [docker 唯一 选择] 推荐:

Docker不再是唯一的选择

- - DockOne.io
Docker并不是唯一的容器化工具,可能还有更好的选择. 在容器的早期时代(其实更像是4年前),Docker是容器游戏中唯一的玩家. 但现在情况已经不一样了,Docker不再是唯一的一个,而只是其中一个容器引擎而已. Docker允许我们构建、运行、拉、推或检查容器镜像,然而对于每一项任务,都有其他的替代工具,甚至可能比Docker做得还要好.

Docker & Flatpak

- - IT瘾-dev
目前最流行的技术莫过于Docker,Docker和Docker衍生的东西用到了很多很酷的技术,目前deepin应用软件发布转变成flatpak,这些看似风牛马不相及的技术方案,实际都使用了一个共同的底层技术——Namespace,假如没有namespace支持,这些技术实现都将成为空中楼阁. 一句话总结,无论是Docker、sysmted-nspawn还是flatpak,都是在namespace基础上,针对不同的场景,生出的不同的解决方案.

docker初体验之docker-tomcat

- - BlogJava-首页技术区
docker已经是现在最热的容器技术,最近也去体验了一下,在daocloud注册了一个账号,并开始本机实战docker. daocloud免费有两个容器可用,体验送T恤,邀请送书,这里我分享一个daocloud的邀请码 https://account.daocloud.io/signup?invite_code=mxeq2jkmcur37vz6ven8,daocloud是非常棒的容器云平台,使用体验好,问题响应也及时,绑定微信还送一个额外容器.

kubernetes移除Docker?

- -
两周前,Kubernetes在其最新的Changelog中宣布1.20之后将要弃用dockershime,也就说Kubernetes将不再使用Docker做为其容器运行时. 这一消息持续发酵,掀起了不小的波澜,毕竟Kubernetes+Docker的经典组合是被市场所认可的,大量企业都在使用. 看上去这个“弃用”的决定有点无厘头,那么为什么Kubernetes会做出这样的决定.

Docker应用场景

- - 灯火阑珊
Flynn:一个使用go语言编写的开源PaaS平台,目标是简化分布式环境中应用的部署和维护,可以通过git push命令,将应用部署到Docker,从而省去复杂的配置和操作. CoreOS:一种新的架构体系重新设计的Linux发型版,可以运行在既有的硬件活着云服务器上. CoreOS不提供类似yum或apt的包管理工具,用户不需要在CoreOS中安装软件,而是让程序都在Docker容器中运行.

docker使用场景

- - 开源软件 - ITeye博客
Docker应用容器相对于 VM 有以下几个优点:. 1、启动速度快,容器通常在一秒内可以启动,而 VM 通常要更久. 2、资源利用率高,一台普通PC 可以跑上千个容器,你跑上千个 VM 试试. 3、性能开销小, VM 通常需要额外的 CPU 和内存来完成 OS 的功能,这一部分占据了额外的资源. 因为VM 的 Hypervisor 需要实现对硬件的虚拟化,并且还要搭载自己的操作系统,自然在启动速度和资源利用率以及性能上有比较大的开销.

Docker 监控实战

- - SegmentFault 最新的文章
如今,越来越多的公司开始使用 Docker 了,现在来给大家看几组数据:. 2 / 3 的公司在尝试了 Docker 后最终使用了它. 也就是说 Docker 的转化率达到了 67%,而转化市场也控制在 60 天内. 越大型的公司越早开始使用 Docker. 研究发现主机数量越多的公司,越早开始使用 Docker.

Docker入门例子

- - 开源软件 - ITeye博客
Docker 提供了一个可以运行应用程序的容器. Docker 容器并不包含一个单独的操作系统,而是基于已有的基础设施中操作系统提供的功能来运行的. 2 Docker安装与启动. #将docker加入开机启动. 3 Docker的14个基础命令. 检查Docker的安装是否正确. 运行"Hello World"例子.

Docker认识基础

- - CSDN博客推荐文章
作者:chszs,版权所有,未经同意,不得转载. 博主主页: http://blog.csdn.net/chszs. Docker是一个C/S架构的容器引擎,它包括镜像、容器和库这三个重要的概念. Docker是一个开源平台,它包含容器引擎和Docker Hub注册服务器. 1)Docker容器引擎.

Docker 调试技巧

- - 行业应用 - ITeye博客
摘要: 『重用』容器名 但我们在编写/调试Dockerfile的时候我们经常会重复之前的command,比如这种docker run --name jstorm-zookeeper zookeeper:3.4,然后就容器名就冲突了. 但我们在编写/调试Dockerfile的时候我们经常会重复之前的command,比如这种.