自去年发了这篇《Podman 安装和使用初体验》的文章后,我就在开发环境上开始了 Docker 到 Podman 的切换之旅。经过这几个月的实际体验,暂未发现任何不适或异常。作为使用的总结记录,今天就来分享一下使用 Podman 制作容器镜像的过程。
使用 Dockerfile
Podman 是一个高度兼容 Docker 的容器引擎和管理工具。所以使用 Podman 时同样也可以继续使用之前的 Dockerfile 镜像构建配置文件。
比如有这样一份自定义 PHP 镜像的构建配置文件:
FROM php:8.1-fpm
RUN sed -i \
"s@http://\(deb\|security\).debian.org@https://mirrors.aliyun.com@g" \
/etc/apt/sources.list
RUN apt update -y
RUN apt install -y libpng-dev libjpeg-dev libfreetype-dev
RUN docker-php-ext-configure gd --with-freetype --with-jpeg
RUN docker-php-ext-install gd
如果使用 Podman 来构建这份镜像配置,只需要运行以下命令:
podman build -t localhost/php .
是不是和 Docker 的 build
命令看起来别无二致?
关于 Podman 这个 build
命令的详细的参数说明和示例,可以通过查阅它的官方文档来了解更多:
点进这个链接,会在命令描述的部分看到这样一段话:
NOTE:
podman build
uses code sourced from the Buildah project to build container images.This Buildah code creates Buildah containers for the RUN options in container storage. ...
由此可知,Podman 提供的 build
命令来自于一个叫 Buildah 的项目。既然如此,那就看看 Buildah 是如何构建镜像的。
使用 Buildah
作为 Podman 这个容器引擎的好搭档,Buildah 的用途非常纯粹,就是专门用来构建镜像的工具。至于 Buildah 和 Dockerfile 构建镜像的区别,下面会直接通过构建过程来展现。相信看完这个完整的过程后就会有自己的答案。
使用之前需要先安装,在 Arch Linux 上的安装命令如下:
sudo pacman -S buildah
使用其他 Linux 系统只要把 pacman
替换为系统对应的包管理命令即可。
同样还是以构建上面的 PHP 镜像举例。首先打开命令窗口,输入以下命令定义一个基础来源镜像:
container=$(buildah from php:8.1-fpm)
按回车键执行命令,会开始拉取基础镜像。
接下来修改基础镜像中的软件源镜像地址:
buildah run $container sed -i "s@http://\(deb\|security\).debian.org@https://mirrors.aliyun.com@g" /etc/apt/sources.list
注意命令中的 $container
,它是一个变量,代表目前 buildah 命令操作的容器对象。这也是和使用 Dockerfile 构建镜像时最显著的区别。主要有两点:
- 代表这个基础镜像目前是运行状态的,它并没有因为一行命令执行结束而终止。
- 意味着使用 Buildah 构建镜像是交互式的,而不是像 Dockerfile 那样必须每次调整一下配置都必须从头开始构建。
- 再也不用担心 Dockerfile 使用构建命令时的「分层」问题。
回到未完成的构建过程上来:
buildah run $container apt update -y
buildah run $container apt install -y libpng-dev libjpeg-dev libfreetype-dev
buildah run $container docker-php-ext-configure gd --with-freetype --with-jpeg
buildah run $container docker-php-ext-install gd
上面的构建命令随时可以根据需要进行回测或重试,而不必重新从第一条命令逐条开始。这在入手不熟悉的基础镜像时,带来了极大的便捷性和自由度。所以我在首次使用 Buildah 构建完一个镜像后,就再也回不到 Dockerfile 方式了。
在最终完成镜像的所有设置和清理工作后,就可以通过下面的命令来提交镜像:
buildah commit $container php:8.1-fpm-with-gd
命令执行完成后,就可以使用 podman images
来查看并使用新构建的自定义镜像了。
使用 buildah ps
可以查看还在运行中的基础镜像。
在确定构建的新镜像没有问题后,可以通过 buildah rm
命令来删除这些运行中的基础镜像。这样使用 Buildah 构建一个镜像的过程就完成了。因为是基于 Shell 命令的构建流程,所以也可以把这个过程中的命令整理到一个脚本文件中:
#!/bin/sh
set -x
container=$(buildah from php:8.1-fpm)
buildah run $container sed -i "s@http://\(deb\|security\).debian.org@https://mirrors.aliyun.com@g" /etc/apt/sources.list
buildah run $container apt update -y
buildah run $container apt install -y libpng-dev libjpeg-dev libfreetype-dev
buildah run $container docker-php-ext-configure gd --with-freetype --with-jpeg
buildah run $container docker-php-ext-install gd
buildah commit $container php:8.1-fpm-with-gd
buildah rm $container
下载再构建这个镜像时,就只需要执行一下这个 Shell 脚本。这样就跟 Dockerfile 有异曲同工之妙了。因为用的是 Shell 脚本,所以在可控制性,灵活性和自由度上,我觉得更高一筹。
另外 Buildah 不依赖于 Podman,所以即便使用的是 Docker,也可以尝试一下这个灵活的镜像构建工具。