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

    文章

    521

    浏览量

    22812
  • 镜像
    +关注

    关注

    0

    文章

    178

    浏览量

    11548
  • Docker
    +关注

    关注

    0

    文章

    526

    浏览量

    14022

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

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

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    【HZ-T536开发板免费体验】Docker 环境安装及应用

    一、检查 Docker 安装状态 板子提示“command not found”或无版本信息,说明 Docker 未安装,如有需要请自行安装 二、Docker 环境安装 首先更新系统包索引并安装
    发表于 09-01 17:59

    docker无法启用怎么解决?

    mengxing@mengxing-virtual-machine:/etc/docker$ sudo systemctl daemon-reload
    发表于 06-23 07:17

    Docker Volume管理命令大全

    Docker Volume管理命令大全
    的头像 发表于 05-28 17:14 613次阅读

    如何使用Docker部署大模型

    随着深度学习和大模型的快速发展,如何高效地部署这些模型成为了一个重要的挑战。Docker 作为一种轻量级的容器化技术,能够将模型及其依赖环境打包成一个可移植的容器,极大地简化了部署流程。本文将详细介绍如何使用 Docker 部署大模型,并给出具体的步骤和示例。
    的头像 发表于 05-24 16:39 801次阅读

    Docker Compose的常用命令

    大家好,今天给大家分享Docker Compose的常用命令,以及docker-compose文件的属性。Docker Compose 是一个用于定义和运行多容器 Docker 应用应
    的头像 发表于 04-30 13:40 927次阅读

    Docker常用命令大全

    Docker 是一种开源的应用容器引擎,广泛应用于开发、部署和运行分布式应用。掌握 Docker 常用命令对于开发人员和运维人员来说非常重要。本文将为大家整理常用的Docker 命令,并按照功能分为多个部分,帮助你高效使用
    的头像 发表于 04-22 12:47 674次阅读

    【技术案例】Android in Docker

    Docker介绍Docker是一个开源的容器化平台,用于打包、分发和运行应用程序。它通过将应用及其所有依赖打包到独立的容器中,确保应用在不同环境中一致运行。Docker提供快速部署、隔离性强和高效
    的头像 发表于 04-02 16:33 1455次阅读
    【技术案例】Android in <b class='flag-5'>Docker</b>

    基于Docker镜像逆向生成Dockerfile

    在本文中, 我们将通过理解Docker镜像如何存储数据, 以及如何使用工具查看镜像方方面面的信息来逆向工程一个Docker镜像; 以及如何使用Python的Docker API来构建一个类似Dedockify的工具来创建Dock
    的头像 发表于 03-10 09:45 1217次阅读
    基于<b class='flag-5'>Docker</b>镜像逆向生成Dockerfile

    华为 FlexusX 与 Docker+Nginx 的高效整合之路

    前言 华为 FlexusX 携手 Docker+Nginx,高效整合,云端性能再升级!FlexusX 服务器,依托华为强大的技术实力,为 Docker 容器与 Nginx 服务器提供完美的运行环境
    的头像 发表于 01-23 17:55 570次阅读
    华为 FlexusX 与 <b class='flag-5'>Docker</b>+Nginx 的高效整合之路

    云服务器 Flexus X 实例,Docker 集成搭建 NGINX

    Docker 集成搭建 NGINX 1、购买华为云 Flexus X 实例 Flexus云服务器X实例-华为云 (huaweicloud.com)   2、docker 安装 yum install
    的头像 发表于 01-13 11:09 1231次阅读
    云服务器 Flexus X 实例,<b class='flag-5'>Docker</b> 集成搭建 NGINX

    基于 Docker 与 Jenkins 实现自动化部署

    优化,为 Docker 容器化应用与 Jenkins 自动化流水线提供理想的运行环境。无论是快速构建、测试还是部署,Flexus X 都能确保流程顺畅无阻,大幅提升软件开发与交付效率。立即拥抱华为云
    的头像 发表于 01-07 17:25 859次阅读
    基于 <b class='flag-5'>Docker</b> 与 Jenkins 实现自动化部署

    Dockerfile镜像制作与Docker-Compose容器编排

    Dockerfile镜像制作 docker/podman中, 镜像是容器的基础,每次执行docker run的时候都会指定哪个基本镜像作为容器运行的基础。我们之前的docker的操作都是使用来
    的头像 发表于 01-07 11:01 1145次阅读
    Dockerfile镜像制作与<b class='flag-5'>Docker</b>-Compose容器编排

    docker的基本命令和使用示例

    DotCloud 公司是一家 PAAS 服务提供商,从 docker 的出身也可以看出它的主要功能和方向。
    的头像 发表于 01-06 15:59 778次阅读

    docker通过中间镜像加速部署

    使用 docker 打包镜像的时候, 每次耗费时间最多的就是 docker build 的过程. 特别是对于前端工程的打包, 有时候下载依赖包的时间就要 10 几分钟, 这就导致发布版本的效率极低.
    的头像 发表于 01-06 12:39 847次阅读

    在 Huawei Cloud EulerOS 系统中安装 Docker 的详细步骤与常见问题解决

    前言   1. 安装Docker   1.1 系统更新与依赖安装   1.2 添加华为云Docker仓库   2. 解决仓库配置错误   2.1 手动修改仓库配置文件   2.2 安装Docker
    的头像 发表于 12-26 18:12 2720次阅读
    在 Huawei Cloud EulerOS 系统中安装 <b class='flag-5'>Docker</b> 的详细步骤与常见问题解决