Ryan

写给Docker用户的Podman和Buildah简介
经常在Twitter被要求为熟悉Docker的用户更好地解释Podman和Buildah。尽管已经有博文和教程了(...
扫描右侧二维码阅读全文
02
2019/09

写给Docker用户的Podman和Buildah简介

Podman_and_Buildah_for_Docker_users_01.png
经常在Twitter被要求为熟悉Docker的用户更好地解释Podman和Buildah。尽管已经有博文和教程了(后面会列出来),我们社区中没有集中解释Docker用户如何从docker迁移到Podman和Buildah。 Buildah到底扮演什么角色?Podman有什么不足所以我们需要Podman和Buildah来一起替换?

这篇文章里会一一解答并演示如何迁移到Podman。

Docker是怎么工作的

首先,我们需要了解的是Docker的工作原理;这会帮助我们理解开发Podman和Buildah的动机。如果你是Docker用户,你肯定知道Docker命令都是Docker后台进程在驱动的。我无法理解这背后的动机,但我认为这是一个很棒的创意,可以做到docker在一个地方做的所有很酷的事情,并为未来的演变提供一个有用的api。 在下图中,我们可以看到docker守护程序提供了以下所需的所有功能:

  • 从仓库拉取镜像和推送镜像到仓库
  • 在本地仓库里快速建立镜像副本并添加存储叠加层
  • 提交镜像更改和删除本地仓库的的容器镜像
  • 让内核以正确的命名空间和cgroup运行容器

实际上,Docker守护进程完成了仓库、镜像、容器和内核的相关工作。Docker 命令行只是根据的你的指令控制Docker守护进程工作。
Podman_and_Buildah_for_Docker_users_02.png
本文没有深入讨论Docker守护进程的详细优缺点。我能理解这对于早期的Docker来说很重要,不过需要阐述的理由太多了。我只想说几个随着用户数量增长,Docker比较关注的几个点:

  • 单进程是个单点故障
  • 这个进程控制所有子进程(正在运行的容器)
  • 如果发生进程故障,会出现孤立进程
  • 构建容器会导致安全漏洞
  • 所有Docker操作都必须由root权限用户执行。

可能还有更多。这些问题是否已经修复或者你不同意这种描述并不是本文将要讨论的问题。我们社区认为Podman解决了许多这些问题。如果您想获得Podman的改进,那么本文适合您。

Podman只是通过runC容器运行时进程(不是守护进程)直接与镜像仓库,容器和镜像存储以及Linux内核进行交互。
Podman_and_Buildah_for_Docker_users_03.png

上面我们已经讨论过迁移的动机了,现在来说一下对于用户来说迁移到Podman的成本有多大。这里我们开诚布公,分别说一下关键点:

  • 安装Podman替代Docker,这就不用管理守护进程,如Docker守护进程。
  • 你熟悉的Docker命令在Podman中几乎一致。
  • Podman存放容器和镜像的路径与Docker不一样。
  • Podman镜像和Docker镜像兼容。
  • 对于Kubernetes环境,Podman比Docker更强大。
  • 什么是Buildah,我要它干嘛?

安装Podman

如果你已经在使用Docker了,你可以在决定切换至Podman时删掉Docker(译者注:千万别删除目前7.6rootless包portmapping还不能用呢,只能用host模式)。不过你可能希望在使用Podman的同时保留Docker。这里有你期望的使用教程和演示,你可以先尝试运行并了解Podman的更多信息。演示中的一个例子需要Docker来演示Podman的兼容性。

在RHEL 7.6或者更新版本的系统中安装Podman,请使用以下命令;如果是Fedora系统,使用dnf替换yum:

# yum -y install podman

Podman的命令和Docker类似

开发Podman的时候,目标就是确保Docker用户可以轻松适应Podman。所以所有命令都和Docker Cli差不多。实际上,开发团队声称,如果你之前是使用使用Docker命令编写的脚本构建容器,那么你只需给podman指令建立一个docker别名(alias docker=podman),你的所有脚本都应该正常工作。试试吧,当然,你需要先停止Docker服务(systemctl stop docker)。你可以安装podman-docker软件包来完成这个转换工作。这个软件包生成脚本/usr/bin/docker来使用相同的命令来运行podman。
你熟悉的命令——pull、push、build、run、commit、tag等,Podman都有。详见《Podman 手册》。值得注意的是,Podman部分命令添加了一些便捷参数。比如,Podman给podman rmpodman rmi命令添加了--all-a。很多用户都觉得有用。
在Podman1.0(Fedora平台)中,你可以使用普通的非root用户来运行Podman。

你可以在Federa平台上上使用非root用户运行Podman(从1.0版本开始)。RHEL7.7和8.1或更新版本支持该特性。用户空间安全性增强实现了该功能。使用普通用户运行Podman意味着默认情况下Podman把容器和镜像存储到用户目录下。这会在下一节中解释。需要了解更多关于Podman如何在非root用户环境下运行的信息,参见Dan Walsh的文章:Podman如何工作

Podman和容器镜像

当你第一次运行命令podman images,你会发现你之前用docker拉取的镜像都不在了。这是因为Podman把镜像存放到/var/lib/containers,而不是/var/lib/docker。这不是特意改变的, 这种新的存储结构基于开放式容器倡议(OCI)标准。

2015年,Docker,Red Hat,CoreOS,SUSE,Google和Linux容器行业的其他领导者创建了开放式容器倡议(OCI)标准,以便提供一个独立的机构来管理定义容器镜像和运行时的标准规范。 为了保持这种独立性,容器/镜像和容器/存储项目是在GitHub上创建的。

因为你以非root用户运行了Podman,所以需要一个单独的Podman可读写的空间。Podman在用户主目录下创建了一个仓库:~/.local/share/containers。这避免把/var/lib/containers目录设置成全局可写和导致其他潜在安全问题。这确保了每个用户都有自己专用的容器和镜像合集且同时使用Podman都不会对其他用户产生影响。当用户完成工作后,可以把镜像上传到公共仓库来分享给其他人。

当Docker用户想重置Podman的时候,会发现这个路径设计可以简化调试和让你不用在意命令rm -f /var/lib/containsers导致的问题。不得不说,一旦你开始使用Podman,你就可以使用-all选项代替podman rmpodman rmi

容器镜像同时兼容Podman和其他运行环境

尽管本地仓库使用了新的路径,但是Docker和Podman创建的镜像都兼容OCI标准。Podman可以从Quay.io和Docker Hub等流行的容器仓库以及私有仓库中拉取和推送。 例如,您可以从Docker Hub提取最新的Fedora镜像并使用Podman运行它。 未指定仓库意味着Podman将按照registries.conf中的仓库顺序依次搜索镜像。 不修改registries.conf的情况下默认Docker Hub开始搜索。

$ podman pull fedora:latest
$ podman run -it fedora bash

镜像推送到Docker仓库后可以被拉取和Podman运行。例如,我使用Docker创建的一个镜像(myfedora),推送到了Quay.io仓库(ipbabble)。可以使用Podman通过以命令式拉取并运行:

$ podman pull quay.io/ipbabble/myfedora:latest
$ podman run -it myfedora bash

Podman提供了命令行参数方便直接推送镜像到/var/lib/docker目录和/var/lib/containers目录,反之亦然。
比如:

$ podman push myfedora docker-daemon:myfedora:latest

很明显,如果没有docker-daemon就会推送到Docker Hub。使用quay.io/myquayid/myfedora作为镜像名就会推送到Quay.io仓库 (myquayid是你的仓库id):

$ podman push myfedora quay.io/myquayid/myfedora:latest

如果你想准备卸载Docker,你需要先关闭Docker守护进程然后使用包管理器删除Docker。但如果有需要保留的Docker镜像,请先确认是否已经将这些镜像推送到镜像仓库,以便到时候你从仓库拉取这些镜像。你还可以使用Podman从本地Docker仓库拉取镜像(例如:fedora)到OCI标准仓库里。在RHEL里你可以这么操作:

# systemctl stop docker
# podman pull docker-daemon:fedora:latest
# yum -y remove docker  # optional

Podman帮助用户迁移到Kubernetes

Podman提供了一些额外的功能,可以帮助Kubernetes环境中的开发人员和操作人员。 Podman提供了额外的命令,这些命令在Docker中不可用。 如果您熟悉Docker并且正在考虑使用Kubernetes / OpenShift作为您的容器平台,那么Podman可以为您提供帮助。
Podman可以通过命令podman generate kube containterid给正在容器生成Kubernetes YAML配置文件。命令podman pod可可用于调试运行Kubernetes pod以及标准容器。有关Podman如何帮助您过渡到Kubernetes的更多详细信息,详见Brent Baude的文章:Podman can now ease the transition to Kubernetes and CRI-O

Buildah是啥,有什么用

实际上Buildah更先出现。这可能会让Docker用户刚到困惑。为什么Podman用户也讨论Buildah?Podman不可以构建镜像吗?
Podman构建镜像和Docker类似,构建过程差不多。你可以使用Podman从Dockerfile构建镜像或者从镜像运行一个容器,在里边安装需要的程序然后提交更改到镜像标签。Buildah可以理解为创建和管理容器镜像的命令超集,因为它实现了对镜像更精准的操作。Podman的build命令是了Buildah的build命令功能的子集。它使用与Buildah相同的代码进行构建。
使用Buildah最好的方法是编写用于创建映像的Bash脚本 - 与编写Dockerfile的方式类似。
我想在下面说明构建功能演化。当Kubernetes根据OCI运行时规范迁移到CRI-O时,无需运行Docker守护程序,因此无需在Kubernetes集群中的任何主机上安装Docker来运行pod和容器。Kubernetes可以调用CRI-O,也可以直接调用runC。反过来,又变成了传统容器构建流程。但是,如果我们想要使用相同的Kubernetes集群来构建镜像,就像是OpenShift集群一样,那么我们需要一个新的不需要Docker守护进程和不依赖Docker安装的构建工具来构建镜像。这个工具,基于containers/storagecontainers/storage开源项目还将消除构建期间打开的Docker守护程序套接字的安全风险,这涉及许多用户。
Buildah(因为Dan Walsh用波士顿口音在说“builder”时的发音而得名)适合这个法案。 有关Buildah的更多信息,请浏览 buildah.io 并特别参阅博客和教程部分。

这是从业人员需要了解一些关于Buildah的额外内容:

  1. 它允许更精细化地控制创建镜像。这是许多容器用户长期以来一直要求的功能。需要单个层提交多次更改。
  2. Buildah的run指令和Podman的run指令不完全一致。因为Buildah是镜像构建工具,run指令和Dockerfile的RUN指令是一样的。实际上,我记得这功能被确定的时间。我正愚蠢地抱怨说我正在尝试的某些端口或文件系统挂载不能像我预期的那样工作。Dan (@rhatdan)说Buildah不应该以这种方式支持运行容器。没有端口映射,没有文件系统挂载。那些参数被删除了。buildah run指令是为了实现在容器中运行构建容器镜像的命令,比如buildah run dnf -y install nginx
  3. Buildah可以从头(scratch)开始构建镜像,从头就是指从什么都没有的镜像开始。实际上buildah from scratch指令创建的容器存储会产生一个空目录。这对于创建非常轻量级的镜像非常有用,这些镜像仅包含运行应用程序所需的文件。

用于临时构建的一个很好的示例用例是开发镜像和Java应用程序的暂存或生产镜像。 在开发期间,Java应用程序容器镜像可能需要Java编译器和Maven以及其他工具。 但在生产中,您可能只需要Java运行时和您的包。 而且,顺便说一句,您也不需要包管理器,如DNF / YUM甚至Bash。 Buildah是这种案例里的强大CLI。 见下图。 有关更多信息,请参阅
Building a Buildah Container Image for Kubernetesalso this Buildah introduction demo
Podman_and_Buildah_for_Docker_users_04.png
回到演变故事......现在我们已经用CRI-O和runC解决了Kubernetes运行时问题,并且我们已经解决了Buildah的构建问题,仍然有一个原因导致仍然需要在Kubernetes主机上使用Docker:调试。 如果我们没有这样的工具,我们如何在主机上调试容器问题? 我们需要安装Docker,然后我们回到我们开始使用主机上的Docker守护进程的地方。 Podman解决了这个问题。
Podman成为解决两个问题的工具。 它允许用户使用他们熟悉的命令检查容器和镜像。 它还为开发人员提供了相同的工具。 所以Docker用户,开发人员或运营商可以转移到Podman,和使用Docker一样能完成他们熟悉的所有任务,并做更多事情。

总结

我希望这篇文章很有用并且可以方便帮助你迁移到使用Podman(和Buildah)。
更多信息参见:

参考资料

版权

贴首声明:本文由Ryan翻译自Podman and Buildah for Docker users,禁止用于任何商业用途,仅供交流与学习,欢迎转载本文,但禁止在非授权的情况下以任何形式转载译本,任何无授权转载将追究其法律责任。

搬瓦工年付$187机房套餐补货了,电信联通优化,512M内存/500G流量/1G带宽,建站稳定,优惠码:BWH1ZBPVK,【点击购买】!
搬瓦工年付$28CN2高速线路,512M内存/500G流量/1G带宽,电信联通优化,延迟低,速度快,建站稳定,优惠码同上,【点击购买】!
Last modification:September 2nd, 2019 at 10:25 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment

2 comments

  1. 张波博客

    这么专业的东西是你写的呀?牛X

    1. Ryan
      @张波博客

      这是翻译的啊