0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

为什么说不要用Docker了?

Linux爱好者 来源:架构头条 作者:架构头条 2021-03-03 15:31 次阅读

在容器的远古时代 (差不多就是 4 年前),Docker 是这场游戏的唯一玩家。但现在情况已经不一样了,Docker 不再是唯一玩家,而只是一个容器引擎而已。我们可以用 Docker 构建、运行、拉取、推送或检查容器镜像,但对于这里的每一项任务,都有其他可替代的工具,它们可能比 Docker 做得更好。所以,让我们来探究一下它们,然后卸载和忘掉 Docker……

为什么说不要用 Docker 了?

如果你已经使用 Docker 很长时间了,那么要说服你考虑使用其他的工具可能需要费点唇舌。

首先,Docker 是一个整体性的工具,它试图做所有的事情,但这通常不是最好的方法。大多数情况下,选择一种专门的工具会更好,它可能只做一件事,但会做到最好。如果你害怕使用不同的工具,可能是因为你要学习使用不同的 CLI、不同的 API 或接受不同的概念。不过请放心,选择本文介绍的工具都是完全无缝衔接的,因为它们 (包括 Docker) 都遵循 OCI (Open Container Initiative) 规范。OCI 包含了容器运行时、容器分发和容器镜像的规范,涵盖了使用容器所需的所有特性。多亏了 OCI,你可以选择一套最适合自己的工具,同时又能够继续使用与 Docker 一样的 API 和 CLI 命令。

所以,如果你愿意尝试新的工具,那么就让我们来比较一下 Docker 和其他工具的优缺点和特性,看看是否有必要考虑放弃 Docker,并转向其他一些新的工具。

容器引擎

在比较 Docker 和其他工具时,我们需要将其分解为组件,首先我们要讨论的是容器引擎。容器引擎是一种工具,它为处理镜像和容器提供了用户界面,这样你就不需要处理 SECCOMP 规则或 SELinux 策略之类的事情。它的工作还包括从远程存储库提取镜像并将其解压到磁盘。它似乎也运行容器,但实际上它的工作是创建容器清单和包含了镜像层的目录。然后它将它们传到容器运行时,例如使用 runc 或 crun(稍后我们将讨论这个)。目前有很多可用的容器引擎,不过 Docker 最突出的竞争对手是由 Red Hat 开发的 Podman。与 Docker 不同,Podman 不需要守护进程,也不需要 root 特权,这是 Docker 长期以来一直存在的问题。从它的名字就可以看出来,Podman 不仅可以运行容器,还可以运行 Pod。Pod 是 Kubernetes 的最小计算单元,由一个或多个容器 (主容器和所谓的边车) 组成,Podman 用户在以后可以更容易地将他们的工作负载迁移到 Kubernetes。以下演示了如何在一个 Pod 中运行两个容器:

~$podmanpodcreate--namemypod ~$podmanpodlist PODIDNAMESTATUSCREATED#OFCONTAINERSINFRAID 211eaecd307bmypodRunning2minutesago1a901868616a5 ~$podmanrun-d--podmypodnginx#Firstcontainer ~$podmanrun-d--podmypodnginx#Secondcontainer ~$podmanps-a--pod CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMESPODPODNAME 3b27d9eaa35cdocker.io/library/nginx:latestnginx-gdaemono...2secondsagoUp1secondagobrave_ritchie 211eaecd307bmypodd638ac011412docker.io/library/nginx:latestnginx-gdaemono...5minutesagoUp5minutesagocool_albattani 211eaecd307bmypoda901868616a5k8s.gcr.io/pause:3.26minutesagoUp5minutesago211eaecd307b-infra211eaecd307bmypod

Podman 提供了与 Docker 完全相同的 CLI 命令,因此你只需执行 alias Docker=Podman,然后就像什么都没有发生改变一样。除了 Docker 和 Podman 之外,还有其他容器引擎,但我认为它们没有出路或者都不适合用于本地开发。不过如果你想要对容器引擎有一个较为完整的了解,我们可以列出一些:

LXD——是 LXC (Linux 容器) 的容器管理器 (守护进程)。这个工具提供了运行系统容器的能力,这些系统容器提供了类似于 VM 的容器环境。它比较小众,没有很多用户,所以除非你有特定的用例,否则最好使用 Docker 或 Podman。

CRI-O——如果你在网上搜索 cri-o 是什么东西,你可能会发现它被描述为一种容器引擎。不过,它实际上是一种容器运行时。除了不是容器引擎之外,它也不适合用于“一般”的情况。我的意思是,它是专门为 Kubernetes 运行时 (CRI) 而构建的,并不是给最终用户使用的。

rkt——rkt(“rocket”) 是由 CoreOS 开发的容器引擎。这里提到这个项目只是为了清单的完整性,因为这个项目已经结束了,它的开发也停止了——因此它不应该再被使用。

镜像的构建

从容器引擎方面来说,除了 Docker 之外只有一种选择。但是,在构建镜像方面,我们有很多选择。首先是 Buildah。Buildah 是 Red Hat 开发的一款工具,可以很好地与 Podman 配合使用。如果你已经安装了 Podman,可能会注意到 podman build 子命令,它实际上是经过包装的 Buildah。在特性方面,Buildah 遵循了与 Podman 相同的路线——它是无守护进程的,可以生成符合 OCI 的像,并保证以相同的方式来运行使用 Docker 构建的镜像。它还能基于 Dockerfile 或 Containerfile(它们实际上是同一个东西,只是叫法不一样)构建镜像。

除此之外,Buildah 还提供了对镜像层更精细的控制,支持提交大量的变更到单个层。在我看来,它与 Docker 之间有一个出乎人意料的区别,使用 Buildah 构建的镜像是特定于用户的,因此你可以只列出自己构建的镜像。你可能会问,既然 Buildah 已经被包含在 Podman CLI 中,为什么还要使用单独的 Buildah CLI?buildah CLI 是 podman build 所包含的命令的超集,你可能不需要使用 buildah CLI,但是通过使用它,你可能会发现一些额外有用的特性。

我们来看看一个小演示:

~$buildahbud-fDockerfile. ~$buildahfromalpine:latest#Createstartingcontainer-equivalentto"FROMalpine:latest" Gettingimagesourcesignatures Copyingblobdf20fa9351a1done Copyingconfiga24bb40132done Writingmanifesttoimagedestination Storingsignatures alpine-working-container#Nameofthetemporarycontainer ~$buildahrunalpine-working-container--apkadd--update--no-cachepython3#equivalentto"RUNapkadd--update--no-cachepython3" fetchhttp://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz fetchhttp://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz ... ~$buildahcommitalpine-working-containermy-final-image#Createfinalimage Gettingimagesourcesignatures Copyingblob50644c29ef5askipped:alreadyexists Copyingblob362b9ae56246done Copyingconfig1ff90ec2e2done Writingmanifesttoimagedestination Storingsignatures 1ff90ec2e26e7c0a6b45b2c62901956d0eda138fa6093d8cbb29a88f6b95124c ~#buildahimages REPOSITORYTAGIMAGEIDCREATEDSIZE localhost/my-final-imagelatest1ff90ec2e26e22secondsago51.4MB

从上面的脚本可以看到,你可以直接使用 buildah bud 构建镜像,其中 bud 表示使用 Dockerfile 来构建镜像,你也可以使用其他更多的命令,如 from、run 和 copy,它们分别对应 Dockerfile 中的 FROM、RUN、COPY。

第二个工具是谷歌的 Kaniko。Kaniko 也基于 Dockerfile 构建容器镜像,而且与 Buildah 类似,它也不需要守护进程。与 Buildah 的主要区别在于,Kaniko 更专注于在 Kubernetes 中构建镜像。

Kaniko 本身是作为镜像 (gcr.io/kaniko-project/executor) 运行的,这对于 Kubernetes 来说是没有问题,但对于本地构建来说不是很方便,并且在某种程度上违背了构建镜像的目的,因为你需要使用 Docker 来运行 Kaniko 镜像来构建镜像。

如果你正在寻找在 Kubernetes 集群中构建镜像的工具 (例如在 CI/CD 管道中),那么 Kaniko 可能是一个不错的选择,因为它是无守护进程的,而且 (可能) 更安全。

从我个人的经验来看——我在 Kubernetes/OpenShift 集群中使用了 Kaniko 和 Buildah 来构建镜像,我认为两者都能很好地完成任务,但在使用 Kaniko 时会随机出现构建故障,在将镜像推送到注册表时也会随机地出现失败的情况。

第三个是 buildkit,也可以称之为下一代 docker build。它是 Moby 项目的一部分,在运行 Docker 时通过 DOCKER_BUILDKIT=1 docker build 就可以启用它,作为 Docker 的一个实验性特性。

那么,这到底会给你带来什么呢?它带来了很多改进和很酷的特性,包括并行构建步骤、跳过未使用的阶段、更好的增量构建和无根构建。但是,它仍然需要运行守护进程 (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 和 CRI-O 都在使用它,它是 (几乎) 所有东西的默认配置,所以即使你在阅读本文后放弃使用 Docker,很可能仍然会使用 runc。

runc 的另一种替代品是 crun。这是 Red Hat 开发的一款工具,完全用 C 语言开发 (runc 是用 Go 开发的),所以它比 runc 更快,内存效率更高。因为它也是兼容 OCI 的运行时,所以你应该可以很容易上手。尽管它现在还不是很流行,但作为 RHEL 8.3 版本的技术预览,它将作为一个可选的 OCI 运行时,又因为它是 Red Hat 的产品,它可能最终会成为 Podman 或 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。它由 Red Hat 公司开发,可以与 Buildah、Podman 和 CRI-O 配套使用。除了基本的 inspect 之外,Skopeo 还提供了 skopeo copy 命令来复制镜像,可以直接在远程注册表之间复制镜像,无需将它们拉取到本地注册表。如果你使用了本地注册表,这个命令也可以作为拉取 / 推送的替代方案。

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

结论

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

责任编辑:lq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 容器
    +关注

    关注

    0

    文章

    481

    浏览量

    21876
  • 镜像
    +关注

    关注

    0

    文章

    153

    浏览量

    10586
  • Docker
    +关注

    关注

    0

    文章

    437

    浏览量

    11602

原文标题:是时候跟 Docker 说再见了

文章出处:【微信号:LinuxHub,微信公众号:Linux爱好者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    如何利用树莓派安装DockerDocker-compose呢?

    本文主要演示了树莓派如何安装DockerDocker-compose的过程。
    的头像 发表于 12-14 16:19 1199次阅读
    如何利用树莓派安装<b class='flag-5'>Docker</b>和<b class='flag-5'>Docker</b>-compose呢?

    docker核心组件有哪些

    Docker 是一种开源的容器化平台,它能够实现将应用程序及其依赖项打包到一个可移植的容器中,从而实现快速、可重复、可扩展的部署和管理。Docker 的核心组件包括 Docker Engine
    的头像 发表于 11-23 09:47 730次阅读

    docker进入容器的方法有哪些

    Docker是一种流行的容器化平台,它能够快速构建、交付和运行应用程序。在使用Docker时,我们经常需要进入容器进行调试、管理和运行命令等操作。本文将详细介绍Docker进入容器的各种方法,包括
    的头像 发表于 11-23 09:45 3347次阅读

    如何启动本机docker服务

    Docker是一个开源项目,可以帮助开发者打包应用程序及其依赖,并且能够将其作为独立的容器来运行。本文将详细介绍如何在本机上启动Docker服务。 第一步:安装Docker 在开始之前,首先需要
    的头像 发表于 11-23 09:43 616次阅读

    linux关闭docker的命令

    在 Linux 系统中,关闭 Docker 的操作可以通过以下多种方式进行。本文将详细讲解每一种方式,并提供示例代码和命令,以帮助读者更好地理解和实践。 使用 docker 命令 最常用的方法
    的头像 发表于 11-23 09:39 1148次阅读

    docker exec命令的使用方法

    Docker是一种开源的容器化平台,可以让开发人员在容器中打包和运行应用程序。它提供了一种快速、可靠和一致的方式来构建、部署和运行应用程序。Docker exec命令是Docker提供的一个非常
    的头像 发表于 11-23 09:33 739次阅读

    docker部署对性能的影响

    Docker 是一个流行的容器化平台,它提供了一种轻量级的虚拟化技术,使得应用程序可以在独立的容器中运行。然而,部署应用程序到 Docker 容器中可能会对性能产生一些影响。在本文中,我们将探讨
    的头像 发表于 11-23 09:31 673次阅读

    docker部署mysql的坏处

    Docker 是一种虚拟化技术,它允许开发人员在容器内打包应用程序及其所有依赖项,从而实现在不同环境中运行相同的应用程序的能力。然而,在使用 Docker 部署 MySQL 时,也存在一些潜在
    的头像 发表于 11-23 09:29 702次阅读

    使用Docker容器编译OK3568源代码

    经常编译系统,又免不了搭建各种开发环境,所以为了不对开发主机的环境有影响,使用Docker容器编译代码是比较方便和省心的方式。 编译OK3568的源代码,需要用Ubunut 18.04版本,我的开发
    发表于 10-19 10:36

    如何使用 Docker容器化技术

    对于开发人员来说,Docker肯定都不陌生,今天小编带大家重新学习一下Docker。 什么是 Docker 官话: Docker 是一种开源的容器化平台,它可以帮助开发者将应用程序与其
    的头像 发表于 09-30 11:24 1w次阅读

    docker常用基础命令

    作为嵌入式开发工程师,需要用到的docker命令基础解析与使用。
    发表于 09-18 17:54 2次下载

    docker基础知识和使用bmnnsdk时的docker常用命令

    的物理机上运行一样。有 Docker,就不用担心环境问题。 1.2 image文件与容器container Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能
    发表于 09-18 07:59

    使用Docker安装WordPress教程

    本教程将向您展示如何使用 Docker Compose 在 Docker 容器中运行 WordPress 安装。
    的头像 发表于 07-28 11:39 1070次阅读
    使用<b class='flag-5'>Docker</b>安装WordPress教程

    docker 搜索镜像,docker查看镜像详细信息(docker下载镜像命令)

    Docker Hub是集中管理的Docker镜像注册中心。通过Docker 用户可以在注册中心搜索、下载和使用CLI命令行工具中的镜像。以下是常用的Docker命令搜索镜像:
    的头像 发表于 07-19 09:46 1112次阅读

    Linux中如何使用Docker安装MySQL

    如果您是 MySQL 的新手或希望快速轻松地安装 MySQL 数据库的人,那么本文适合您,在本文中,我们将学习如何在 Linux 中使用 DockerDocker compose 设置 MySQL。 让我们首先设置 dock
    的头像 发表于 05-12 16:22 3121次阅读
    Linux中如何使用<b class='flag-5'>Docker</b>安装MySQL