Podman与Docker-哪个容器引擎最适合你

1,430 阅读23分钟

Docker和Podman是伟大的容器管理引擎,在构建、运行和管理容器方面具有相同的目的。

Docker在容器化市场上已经有相当长的时间了。它已经证明了自己的价值,增加了就业市场的需求。它是由Docker公司在2013年首次开发的,并已被一些技术领域的大公司使用,如谷歌和Facebook,从而使其成为最受欢迎的容器引擎。

现在,容器已经变得更加流行,几乎到处都在使用,其他工具如Podman出现,使之更加完善,并解决我们在容器化方面面临的一些具体问题。

在这个Podman与Docker的比较博客中,你将了解到Podman和Docker。
此外,你将对这两个容器引擎有更多的了解。在博文的最后,你将能够决定哪个容器引擎最适合你。

你目前可能正在使用Docker,所以我也会在本博客后面的Podman vs Docker部分解释如何从Docker迁移到Podman而不产生任何问题。

所以,让我们开始吧。

什么是容器化?

容器化是一种非常有效的虚拟化方法,目前有很多。它使开发人员更容易测试、构建和部署大型应用程序。

容器和虚拟机是相似的,但它们并不一样。由于它们如此相似,一些人往往会混淆它们,因为它们做的是同一件事,但却不一样。

Containers and Virtual machines

为什么Podman与Docker相比?

如果我们看一下谷歌的趋势,我们会发现对Podman的搜索兴趣正在上升,并且一直在增加。我们可能会看到Podman在未来几年内变得更加流行。

Podman vs Docker

资料来源

Docker仍然是该领域的领导者,我不认为它很快就会消失,但图表告诉我们,对Docker的整体兴趣正在下降。

要么是开发者对Docker失去了兴趣,要么是他们已经迁移到另一个比Docker更能完成他们工作的软件。

Docker

资料来源

在讨论Podman与Docker的区别之前,让我们先了解什么是容器。有些人倾向于混淆这两者,因为它们都做同样的事情(虚拟化),但它们是完全不同的。

容器与虚拟机

在虚拟机(VM)中,系统的资源被分配给多个虚拟机。这些虚拟机单独运行,可以有不同的操作系统。

另一方面,容器只对操作系统级别以上的软件层进行虚拟化,这意味着你可以有多个虚拟化环境,但只有一个操作系统。要了解更多的差异,你可以通过这篇博客阅读,其中讨论了容器与虚拟机

Containers vs Virtual Machines

容器化是将软件代码与运行代码所需的操作系统库和依赖关系打包,创建一个单一的轻量级可执行文件,称为容器。

容器为什么重要?

容器在部署应用程序,特别是微服务方面起着相当大的作用。微服务是一些小服务,它们相互之间进行通信、发送和接收数据。

根据报告,Netflix现在使用超过1000个微服务。每个部署的应用程序控制着巨大的Netflix运营的一个特定方面。例如,一个微服务只负责确定你的订阅状态,以提供与该订阅层相关的内容。

微服务允许团队在不干扰其他团队工作的情况下,分别对其应用程序的不同部分进行工作。它们是灵活的、可维护的,并且容易适应。

微服务设计模式帮助开发者有效地开发、扩展和维护他们的项目。然而,当涉及到部署时,他们可能会面临一些挑战,特别是在大规模应用中。

如果你不使用容器,你将不得不写一堆指令给你的DevOps团队,让他们在他们那边运行代码。这就增加了应用程序中可能出现的错误数量。

要了解更多关于微服务的信息,你可以参考这篇关于如何测试微服务架构应用的博客。

不使用容器的挑战

如果DevOps团队在遵循你的指示时犯了错误,他们将无法在自己这边运行代码。所以他们会反馈给你,而你必须找到那个小错误。

例如:假设你使用的是MongoDB 4.0版本,但对于生产来说,有一个错误,4.1版本已经被安装了。你的一个微服务与那个特定的版本不兼容。

这些错误经常出现在大规模的应用程序中,而且调试起来很有挑战性。

随着你的应用程序的增长,它需要更多的依赖性和微服务,每次添加新的东西时,手动重新部署将是相当令人头痛的。

容器化使这一切变得更加容易。你不必给你的DevOps团队下指令,因为指令是写在Docker文件中的。容器引擎会自动下载和安装你的代码运行所需的每一个依赖项。

示例Docker文件

Docker将读取文件和说明,并为该特定的应用程序下载依赖性,最后用特定的命令来运行该应用程序。在这种情况下,我们要拉出一个特定版本的官方NodeJs Docker镜像。

这些镜像仓库可以依赖其他的仓库和依赖物,而且它们也可以依赖其他的依赖物,不断地依赖。Docker在构建和运行容器时将在后台处理所有这些艰苦的工作。

由于容器只使用高级软件,这使得它们很轻,可以轻松地创建、修改和删除。

大多数容器运行时系统也有一个强大的生态系统。许多公共的容器镜像库可以随时下载和执行。

例如,你可以从DockerHub 下载最新版本的Selenium ,只需一个命令就可以在Docker容器内运行它。

docker pull selenium/standalone-docker
 
docker run selenium/standalone-docker

这将从DockerHub下载官方的Selenium Docker镜像和它所需的所有依赖项。然后,Selenium将在Docker容器中运行。

今天,几乎每个大公司都使用容器化来测试、构建和部署其应用程序。在过去的几年里,容器已经证明了其重要性,尤其是Docker。

什么是Docker?

Docker是一个平台即服务(PAAS)产品,它在称为容器的小型轻量级包中使用操作系统级的虚拟化。

对于初学者来说,PaaS是一个完整的开发和云端托管的平台。它允许企业和开发人员托管、构建和部署应用程序。

Docker也是开源的,帮助开发者构建、部署、运行和管理容器化的应用程序。它使用一个在后台运行的REST API来监听请求并执行相应的操作。这个过程被称为Docker daemon(或dockerd)。

Docker守护进程是一个后台进程,负责管理单个主机上的所有容器。它可以处理所有的Docker镜像、容器、网络、存储等。

Docker使用监听REST API请求的containerdDaemon来管理Docker的大部分工作。例如,管理图像、管理容器、卷和网络。Containerd在Unix套接字上监听,并公开gRPC端点。它处理所有低级别的容器管理任务、存储、镜像分发、网络连接等。

Docker是如何工作的?

containerd守护进程将从容器注册处提取容器镜像。然后,它把创建容器的过程交给一个名为runc的低级运行时。

runc是一个CLI工具,用于根据OCI规范在Linux上运行容器。

OCI是一个由Linux基金会主持的合作项目,旨在为容器建立标准。像Docker、CRI-O和containerd这样的容器引擎依靠符合OCI的标准来与操作系统对接并创建运行中的容器。

它被设计为由更高级别的容器软件使用。因此,运行容器的过程是从通过Docker守护程序、containerd运行,然后再运行。

Docker daemon

  • Docker镜像

一个Docker镜像就像一个模板,它作为一组指令来构建一个Docker容器。一个Docker镜像包含应用程序代码、库、工具、依赖性和其他运行应用程序所需的文件。

  • Docker卷

假设你有一个Docker容器,里面有一个MongoDB数据库。通常情况下,这个容器会将每一点数据保存在容器本身里面。

这样做的问题是,如果你因为某种原因想删除这个容器,你会失去所有积累的数据。

有了Docker卷,你可以在主机中保存你需要的必要信息。在你希望数据在docker容器和服务中持续存在的地方,它们是首选。

  • Docker网络

Docker网络有助于连接可以相互通信的容器。因此,Docker不仅仅是构建和运行容器的软件。它也是一个云平台,可以将你的容器镜像上传和下载到云端。

通过Docker,你可以创建、构建和运行与任何操作系统兼容的容器。换句话说,如果你的系统上有Docker,你的代码在你的机器上运行,如果另一台设备上安装了Docker,就可以保证这段代码在另一台设备上运行。

要了解更多关于Docker及其实现的信息,请阅读这篇关于如何使用Docker与Selenium的博客。

关于Docker的一个简单总结。

  • Docker使用一个守护进程,这是一个后台进程,用于监听API请求,以相应地管理容器。
  • Docker让你建立和运行超轻量级的容器
  • Docker是一个基于多种软件的PAAS,包括一个分享和下载Docker镜像的云托管注册中心,名为DockerHub。

用Docker运行你的Selenium测试。现在就试试LambdaTest吧!

什么是Podman?

Podman是一个类似于Docker的容器引擎。它也用于开发、管理和运行OCI容器。Podman可以使用libpod库管理整个容器生态系统,如pod、容器、图像和容器卷。

什么是pod?

Podman的主要特点之一是它允许你创建pod。一个pod是容器的一个组织单位。Pods是Kubernetes容器协调框架的重要组成部分。

你可以使用Podman创建清单文件,以声明的格式描述荚。Kubernetes可以消费这些用YAML编写的清单文件。

与Docker不同,Podman中的容器可以以root或非root用户身份运行。我们将在本博客后面关于Podman与Docker的部分更详细地讨论这个Podman与Docker的区别。

Podman不依赖守护程序来开发、管理或运行容器。由于Podman没有守护程序来管理容器,Podman使用另一个服务管理器来管理所有的服务,并支持在后台运行容器,称为Systemd。

Systemd为现有的容器创建控制单元或生成新的容器,有了Systemd,供应商可以安装、运行和管理他们的容器应用程序,因为现在大多数都是专门打包和交付的。

Podman在Buildah的帮助下,可以在不使用守护程序的情况下构建镜像。Buildah是一个通过低级别的核心工具接口来构建与OCI兼容的镜像的工具。

就像Docker有一个CLI一样,因为由Docker和Podman创建的图像与OCI标准兼容。Podman可以从Docker Hub和Quay.io等容器注册处推拉。

如果你已经熟悉Docker,你可以轻松地从Docker迁移到Podman(后面会有更多介绍)。你也可以将Podman别名为docker而不会有任何问题alias docker=podman 。这意味着你可以在Podman中使用与Docker相同的命令。

就像Docker一样,Podman依赖于像RunC这样的OCI标准来与操作系统对接并创建运行容器。因此,这将使Podman与Docker等其他容器引擎非常相似。

跑道还使用跑道提供的REST API来管理容器;这个REST API只适用于Linux。为了与这个REST API互动,Podman有一个客户端,可用于所有主要操作系统Windows、macOS和Linux。

如果Podman REST API只在Linux上可用,我们如何在Windows或macOS中使用它?

尽管容器是Linux,但Podman也可以在Mac和Windows上运行。它提供了一个本地的Podman CLI,并嵌入了一个客体Linux系统来启动容器。

这个客人也被称为Podman机器,可以通过使用podman machine 命令来管理。

关于Podman的一个简单总结。

  • Podman帮助你在DockerHub或quay.io或内部注册表服务器上找到容器。
  • 轻松地从预先构建的容器镜像中运行容器。
  • 通过一些调整来构建新的层或容器。
  • 你可以轻松地在任何地方分享你的容器镜像,只需一个命令podman push

使用Podman在容器中运行一个Redis服务器

用Podman运行容器是非常容易的,与Docker类似。要做到这一点,运行以下命令。

podman pull selenium/standalone-docker
 
podman run selenium/standalone-docker

Podman将在容器内运行基于官方Redis镜像的Redis服务器。容器将以-d 声明的分离模式运行,并将以—-name 指定的Redis命名。

容器将暴露端口,并将其连接到主机上的相同端口,这是用-p 6379:6379 指定的默认Redis端口。

在你运行该命令后,Podman将检查Redis镜像是否已经存在于本地机器中。如果存在,它将在该镜像的基础上建立一个容器。如果不存在,它将从DockerHub寻找该镜像并下载最新版本。

Podman与Docker的比较

一般来说,Podman和Docker做同样的事情。然而,Podman和Docker这两个容器引擎之间有一些区别。

以下是Podman与Docker的主要区别。

架构。波德曼有一个无Daemon的架构

Docker守护进程是一个后台进程,负责管理单个主机上的所有容器。它可以处理所有Docker镜像、容器、网络、存储等。Docker守护进程使用REST API来监听请求并执行相应的操作。

因此,Docker需要这个守护程序在后台运行,以管理、创建、运行和构建容器。Docker有一个由Docker守护进程调解的客户-服务器逻辑。

另一方面,Podman不需要一个守护程序。它有一个(无daemon架构),帮助用户开始运行容器(无根)。换句话说,Podman不需要root权限来管理容器。

根权限

由于Docker需要一个守护程序来管理它的容器,它将需要root权限来运行进程。

由于Podman没有守护程序,它有一个(无守护程序架构)。它的容器不需要root权限。

无根执行

起初,当Docker出现时,没有root权限是无法运行Docker的。然而,无根模式在Docker的v19.03版本中被引入,并在Docker Engine v20.10版本中从实验性毕业。

然而,Docker无根模式并不是开箱即用的。在安装Docker之前,应首先在主机上安装一些配置和第三方软件包。

所以,没错,你可以以root身份运行Docker和Podman。但要知道,Podman推出了在无根状态下运行容器,这也有一些限制。

Docker无根模式的局限性

Docker的无根模式并不完美,用Docker无根模式运行容器会出现一些问题。

  • 不能在特权端口上运行容器,也就是1024以下的所有端口。否则,它们将无法运行。

  • 只支持以下存储驱动。

  • overlay2 (只有当运行内核5.11或更高版本或Ubuntu风味的内核时)。

  • fuse-overlayfs (只有当运行内核4.18或更高版本,并且安装了fuse-overlayfs时)。

  • btrfs (只有当运行内核4.18或更高版本,或者 ,并安装了 mount选项)。~/.local/share/docker user_subvol_rm_allowed

  • Vfs.

  • 只有在使用cgroup v2和systemd运行时,才支持Cgroup。

  • 不支持以下功能。

  • AppArmor

  • 检查点

  • 叠加网络

  • 暴露 SCTP 端口

  • 要使用ping 命令。

  • IPAddressdocker inspect 中显示,并在 RootlessKit 的网络命名空间中进行命名。这意味着如果没有nsenter - 进入网络命名空间,该 IP 地址就无法从主机上到达。

  • 主机网络 (docker run --net=host ) 也是在 RootlessKit 内命名的。

  • 不支持作为docker "数据根 "的NFS挂载。这个限制不是针对无根模式的。

安全性

Podman的安全性是否比Docker高?早些时候,我们在比较Podman和Docker时,看到了Podman可以无根运行,因为它有一个(无守护程序架构),而Docker不能无根运行,因为它需要一个守护程序来运行和管理容器。

但为什么这很重要呢?为什么没有守护程序和能够在没有root权限的情况下运行容器是至关重要的?答案是,我们不会给不信任的应用程序以根权限,而我们确实信任我们的容器和应用程序。

但事实并非如此。比方说,一个攻击者找到了访问你的一个容器的方法!由于Docker只能以root权限运行,任何恶意行为者(即攻击者)都可以用这些root权限在你的服务器上采取错误行动。

有了Podman,如果攻击者进入你的容器,他们将能够对你造成伤害,但他们仍然无法进行需要root权限的操作。因此,Podman被认为比Docker更安全。

构建镜像

Docker是一个自给自足的平台。它可以自己构建镜像和运行容器,而不需要任何其他第三方工具。

另一方面,Podman只被设计用来运行容器,而不是构建容器。这就是Buildah的作用。Buildah是一个开源工具,可以构建Open Container Initiative(OCI)容器镜像。

Podman在Buildah的帮助下,可以构建其OCI容器镜像。

Docker Swarm和docker-compose

Docker Swarm是一个容器协调平台,用于管理Docker容器。通过Docker Swarm,你可以运行一个Docker节点集群,并在不需要其他依赖的情况下部署可扩展的应用程序。

Docker Swarm还可以跨多个主机管理多个容器,并将它们全部连接起来。Docker Swarm显然可以与Docker一起使用,开箱即用,没有任何问题。

Podman不支持Docker Swarm,但其他工具可以与Podman一起使用,比如Nomad,它带有Podman驱动。

Docker-compose是一个用多个容器管理应用程序的工具。Docker compose和Docker swarm的主要区别在于,docker-compose只在一台主机上运行,而Docker swarm则连接了各种主机。

Docker自动与docker-compose兼容,开箱就能与之很好地工作。

在以前的Podman版本中,Podman没有办法模拟Docker compose工作所需的Docker守护程序,所以才会使用Podman compose。

现在,在3.0版本中,Podman引入了podman.socket ,一个UNIX套接字,取代了Docker Daemon。

一体化与模块化

Podman采用模块化方法,依靠专门的工具来完成特定的任务,而Docker是一个单体的独立工具。Docker是一个单体的、强大的独立工具。所谓单体,是指Docker不依赖任何其他第三方工具来管理容器、运行、构建或处理与容器相关的任何其他任务。

这个是Podman与Docker技术的重大区别。

正如我们所讨论的,Podman依靠许多额外的第三方工具来实现与Docker相同的目标。例如,它使用Buildah来构建容器镜像,而Docker不需要Buildah或任何其他第三方工具来构建镜像。

以下是Podman与Docker对比的总结。

Docker波德曼
使用一个守护进程。有一个无守护进程的架构。
它只能以root权限运行。能够以无根方式运行。
不太安全,因为所有容器都有root权限。更安全,因为容器没有root权限。
Docker是一个自给自足的工具,可以自己构建镜像。Podman不能自己构建图像。它使用另一个叫做buildah的工具来构建图像。
它支持Docker swarm和Docker compose,而且开箱即用。它不支持Docker swarm或Docker compose。
Docker是一个单一的独立工具。Podman依赖于其他第三方工具。

既然我们已经了解了Podman和Docker的比较,那么是否可以认为Podman是Docker的替代品呢?让我们在本篇Podman vs Docker博客的下一节中查看。

Podman是Docker的替代品,还是可以一起使用?

一些开发者将Podman用于生产,Docker用于开发。由于它们都符合OCI标准,兼容性不会有问题。然而,在前进之前最好先比较一下Podman和Docker。

你可以将Docker用于开发,使你的工作更容易,而将Podman用于生产,以受益于它所提供的额外安全性,并使你的应用程序更有效率。

如果你从头开始一个项目,Podman可以成为一个主要的容器化技术选择。如果项目正在进行,并且已经使用了Docker,那就要看具体情况了,但可能不值得这么做。作为一个Linux原生应用,它要求参与的开发者具备Linux技能。

在CI/CD中运行你的Selenium测试。现在就试试LambdaTest吧!

如何从Docker迁移到Podman?

从Docker迁移到Podman是很容易实现的。你在使用Docker时使用的命令也可以用于Podman,所以你不必担心要记住新的命令,这使得迁移非常容易。

有些开发者只是将Docker别名为Podman,一切工作都很相同,但进程由Podman而不是Docker处理。

用Podman运行一个Node.js容器

首先,你必须在你的电脑上安装Podman。如果你想跟上这个简短的教程,你可以从这个GitHub仓库下载node.js应用程序的样本。

由于Podman和Docker都符合OCI容器标准,Podman也可以从Docker文件中构建容器,所以如果你能用Docker从Docker文件 中构建和运行一个容器,那么你也可以用Podman运行它。

让我们在这个Docker文件上构建容器。

要构建容器,请运行以下命令。

podman build -t my-node-app .

container

在你运行该命令后,Podman将执行Dockerfile并在你的本地机器上构建镜像。

你可以通过运行podman images 来显示你本地设备上可用的容器镜像。

podman images

我们只创建了一个名为my-node-app 的镜像,但如果你注意到,我们还有一个额外的镜像,因为我们要运行的容器依赖于node:16 。Podman将自动下载该镜像以运行我们想要运行的容器。

在你建立镜像后,你可以通过使用以下命令运行一个容器来运行一个实例。

podman run --name my-node-js-container -p 3000:3000 localhost/my-node-app

--name tag 将指定容器的名称,-p 将容器内的端口映射到主机上的端口-p host:container

最后,在末尾添加localhost/my-node-app ,以指定我们希望新容器运行的容器镜像。

 localhost/my-node-app

恭喜你,你的服务器现在已经在由Podman运行的容器中的3000端口上运行。你可以从你的浏览器访问它。

3000 image

我们在本教程中使用的所有命令都与Docker命令相同。这就是为什么从docker迁移到Podman很容易,开发者毫不费力地就能适应它。

关于Podman的另一个很酷的功能是,你可以使用—-all 标志停止或删除所有的容器。在Docker中,你不可能使用这个。

例如,如果你想用Podman停止所有容器,你可以运行podman stop —-all 。如果你要用Docker做同样的事情,你必须运行docker stop $(docker ps -a -q) ,这有点难记。

将Docker或Podman与Selenium Grid整合起来很容易,有助于你进行Selenium自动化测试。然而,Selenium Grid与Docker或Podman提供的功能可以通过整合LambdaTest等在线Selenium Grid来进一步加强。

你也可以订阅LambdaTest的YouTube频道,随时了解围绕Selenium测试Cypress E2E测试、CI/CD等的最新教程。

LambdaTest是一个跨浏览器的测试平台,允许你在3000多个浏览器和操作系统组合的在线浏览器场上对网站和网络应用进行手动和自动的浏览器测试

LambdaTest的可靠、可扩展、安全和高性能的测试执行云使开发和测试团队能够加快其发布周期。它可以让你运行并行测试,并将测试执行时间缩短10倍以上。

总结

在这个Podman与Docker的博客中,我们已经看到Docker和Podman在运行和管理容器方面都很出色。你可以用它们来构建和部署大型应用程序。

如果你更关心你的应用程序的安全性或计划使用Kubernetes来协调你的容器,Podman是你更好的选择。

如果你想要一个文档齐全的工具,拥有更大的用户群,那么Docker是你更好的选择。

常见问题(FAQ)

我应该使用Docker还是Podman?

容器化现状的问题是,只有少数几个选项可以协调去特权化的进程。许多大型企业的开发人员已经在他们的系统中实施了容器(Docker),但大多数中小型网站的其他应用程序并没有有效地使用容器。跑道管理是解决这个问题的一个办法。跑道管理允许容器拥有非root权限,在这里可以以安全的方式快速解决问题。

波德曼与Docker有什么不同?

Docker和Podman最显著的区别是,Docker使用客户端服务器架构,在每个需要运行容器的主机上运行一个守护程序,而Podman使用单进程架构。正因为如此,pods和图像都比较小。另外,由于Podman是一个单一的进程,它可以避免与多进程架构相关的安全问题,如与所有其他容器共享PID命名空间。

Podman比Docker更安全吗?

Docker使用一个运行在本地机器上的守护程序来管理容器。这使得它可以完全从仓库(如Ubuntu或Red Hat)安装。这也意味着,攻击者不仅要破坏容器平台,还要破坏运行docker守护程序的本地机器。docker守护程序默认以root身份运行,这实际上给了攻击者对你的机器的root权限。

Podman以普通用户的身份运行,不需要root权限。这使得它更安全,因为对Podman的成功攻击仍然需要闯入底层操作系统。例如,一个用户可以通过Podman访问主机上的文件的只读权限。同时,他们有可能通过Docker的守护程序(以root身份运行)获得对可写文件系统的访问。