Ubuntu 上的 Podman:使用 Dockerfile 构建和运行容器(从入门到实战指南)

目次

1. 介绍

容器技术的演进及其重要性

近年来,容器技术在应用开发和运维中的重要性迅速提升。尤其是通过对齐开发和生产环境来确保可复现性的能力,受到了工程师们的广泛支持。

Docker 长期以来一直是该领域的主导方案,但近年来,Podman 作为一种强有力的替代方案崭露头角。Podman 提供了与 Docker 几乎相同的 CLI(命令行界面),同时具备 无守护进程架构、轻量化运行以及 无需 root 权限的无特权执行 等关键优势。

为什么选择 “Podman + Dockerfile + Ubuntu”?

本文通过结合三大要素:PodmanDockerfileUbuntu,阐述 Linux 上的现代容器操作。

  • Ubuntu 是一种被广泛使用的 Linux 发行版,适合初学者和高级用户。
  • Dockerfile 充当构建容器镜像的蓝图。
  • 而 Podman 是下一代工具,能够实现更灵活、更安全的容器管理。

随着安全意识的提升,在 Ubuntu 上使用 Podman 搭配 Dockerfile 已成为个人开发者和企业环境的热门选择。

目的与受众

本文的目标是仔细阐述如何在 Ubuntu 上使用 Podman 编写 Dockerfile 并创建实用容器

本文面向的读者包括:

  • 有 Docker 使用经验并对 Podman 感兴趣的读者
  • 希望安全管理容器的 Ubuntu 用户
  • 计划在工作中采用容器技术的工程师
  • 想尝试编写 Dockerfile 并使用 Podman 构建镜像的初学者

除了基础使用外,本文还涵盖故障排除技巧、与 Docker 的关键差异以及迁移策略。

2. 什么是 Podman?

Podman 基本概述

Podman(Pod Manager) 是由 Red Hat 主导的社区开发的下一代容器管理工具。与 Docker 类似,它能够构建、运行和管理符合 OCI(开放容器倡议)标准的容器,但其设计理念和架构有显著差异。

最显著的特性是 Podman 不需要守护进程。这实现了 轻量且安全的运行。Podman 还支持 无特权模式,允许普通用户在无需提升权限的情况下管理容器。其与 Docker 的 CLI 兼容性极高,使迁移过程相对直接。

Podman 的关键特性

以下是 Podman 的主要特性:

无守护进程架构

Podman 不依赖后台守护进程来管理容器。这使得资源使用更高效,避免了不必要的后台服务。

无特权(非管理员用户)支持

Podman 允许 非管理员用户启动和管理容器。这在多用户或服务器环境中大幅提升安全性,并显著降低安全风险。

与 Docker 兼容的 CLI

Podman 使用几乎相同的命令结构与 Docker。例如,以下 Docker 命令在 Podman 中几乎可以同样使用:

podman build -t myimage .
podman run -it myimage bash

因此,Docker 用户可以几乎无缝迁移

Pod 功能

Podman 融入了 Kubernetes 的 “Pod” 概念,使 多个容器能够作为单一逻辑单元进行管理。这使得 Podman 与 Kubernetes 高度兼容,并实现了从本地开发到云环境的平滑过渡。

与 Ubuntu 的兼容性

虽然 Podman 在 Fedora 和基于 RHEL 的发行版中被广泛采用,但它也 在 Ubuntu 上运行稳定。可以通过官方仓库进行相对简单的配置安装。自 Ubuntu 20.04 LTS 起,软件包支持显著提升,降低了上手门槛。

3. 在 Ubuntu 上安装 Podman

开始之前:先决条件

在 Ubuntu 上安装 Podman 之前,首先检查你的 Ubuntu 版本。Podman 官方推荐 Ubuntu 20.04 LTS 或更高版本。在较旧的版本中,所需的软件包可能在官方仓库中不可用。

你可以使用以下命令查看 Ubuntu 版本:

lsb_release -a

安装 Podman 需要 sudo 权限。即使你计划以无根模式使用 Podman,安装过程中仍然需要管理员权限。

从 Ubuntu 官方仓库安装 Podman

在最近的 Ubuntu 版本(如 20.04 或 22.04)上,Podman 可以通过 APT 轻松安装。

sudo apt update
sudo apt install -y podman

安装完成后,通过检查版本来验证 Podman 是否正确安装:

podman --version

使用官方 PPA 安装最新版本

Ubuntu 默认仓库中提供的 Podman 版本往往略显陈旧。如果你想使用最新特性,可以从 官方 PPA 安装 Podman。

. /etc/os-release
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/xUbuntu_${VERSION_ID}/Release.key | sudo apt-key add -
sudo apt update
sudo apt install -y podman

此方法可让你使用 相当于 Red Hat 和 Fedora 系统上的最新 Podman 版本

基本 Podman 功能测试

安装后,执行一个简单的测试以确认 Podman 正常工作:

podman info

该命令会显示 Podman 的配置信息、版本以及支持的功能(如无根模式)。

你还可以通过运行官方的 Alpine Linux 镜像来测试容器执行:

podman run --rm -it alpine sh

如果 shell 成功启动,说明 Podman 正常运行。

4. Dockerfile 基础及在 Podman 中的使用

什么是 Dockerfile?

Dockerfile 是用于构建容器镜像的蓝图。它是一个文本文件,定义了诸如基础镜像、要安装的包以及要复制的文件等指令。

基于该文件,Podman 和 Docker 等容器工具可以 自动构建一致的环境

常见的 Dockerfile 指令包括:

FROM ubuntu:22.04
RUN apt update && apt install -y curl
COPY ./app.sh /usr/local/bin/app.sh
CMD ["bash", "/usr/local/bin/app.sh"]

此示例在 Ubuntu 基础镜像上安装软件包,复制脚本,并定义默认执行命令。

在 Podman 中使用 Dockerfile

Podman 可以像 Docker 一样,从 Dockerfile 构建容器镜像。

1. 准备项目目录

创建如下目录结构:

project/
├── Dockerfile
└── app.sh

app.sh 文件可以包含一个简单脚本:

#!/bin/bash
echo "Hello from Podman container!"

为脚本添加可执行权限:

chmod +x app.sh

2. 使用 Podman 构建镜像

在包含 Dockerfile 的目录中运行以下命令:

podman build -t mypodmanapp .

这会创建一个名为 mypodmanapp 的容器镜像。

3. 验证构建的镜像

你可以使用以下命令列出可用镜像:

podman images

4. 运行容器

使用构建好的镜像启动容器:

podman run --rm mypodmanapp

如果配置正确,输出 Hello from Podman container! 将会显示。

Dockerfile 与 Containerfile

在 Podman 中,使用 Dockerfile 语法的文件也可以称为 Containerfile。这种命名体现了对 Docker 独立术语的需求。

Dockerfile 与 Containerfile 在功能上没有区别。两者都被 Podman 完全支持。

podman build -f Containerfile -t myimage .

您可以使用 -f 选项显式指定文件名。

5. 实用示例:创建基于 Ubuntu 的容器

基于 Ubuntu 创建 Dockerfile

接下来,我们将逐步演示一个实用示例,基于 Ubuntu 创建 Dockerfile,以及 使用 Podman 构建和运行容器镜像

首先,创建以下简单的 Dockerfile

FROM ubuntu:22.04

RUN apt update && \
    apt install -y curl && \
    apt clean

COPY hello.sh /usr/local/bin/hello.sh
RUN chmod +x /usr/local/bin/hello.sh

CMD ["/usr/local/bin/hello.sh"]

此 Dockerfile 执行以下操作:

  • 使用官方的 Ubuntu 22.04 镜像作为基础
  • 安装 curl 软件包
  • 将主机上的 hello.sh 复制到容器中
  • hello.sh 设置为默认执行脚本

接下来,创建一个名为 hello.sh 的简单 shell 脚本:

#!/bin/bash
echo "Hello, this output is from a Podman container!"

为脚本授予执行权限:

chmod +x hello.sh

使用 Podman 构建镜像

文件准备好后,使用以下命令构建镜像:

podman build -t ubuntu-hello .

-t ubuntu-hello 选项为镜像分配标签名称,末尾的 . 指定包含 Dockerfile 的目录。

如果构建成功完成,镜像将被存储在本地。

podman images

您可以使用此命令验证镜像是否已创建。

运行并验证已构建的镜像

使用以下命令从新构建的镜像运行容器:

podman run --rm ubuntu-hello

示例输出:

Hello, this output is from a Podman container!

--rm 选项在执行后自动删除容器,非常适合用于测试。

可选:运行交互式容器

如果您想直接与容器交互,可以使用 -it 选项启动容器并运行 Bash:

podman run -it ubuntu-hello bash

这使您可以将容器用作轻量级的基于 Ubuntu 的开发环境。

6. 有用的 Podman 功能与技巧

Podman 的优势:灵活性与安全性

在保持与 Docker 兼容性的同时,Podman 提供了 实现更灵活、更安全的容器操作的功能。本节介绍了在日常工作流中特别有用的实用功能和技巧。

使用无根模式实现安全操作

Podman 最强大的功能之一是 无根模式,它允许 普通用户在无需管理员权限的情况下启动、停止和管理容器

您可以像下面这样在不使用 sudo 的情况下运行容器:

podman run -it ubuntu bash

由于此操作限制在用户的主目录中,对系统整体的影响被降到最低。无根模式在共享服务器和开发环境中尤为有用。

使用 systemd 集成实现自动启动

Podman 支持 与 systemd 的原生集成,使容器能够自动作为 Linux 服务运行。

您可以使用以下命令为容器生成 systemd 服务单元:

podman generate systemd --name mycontainer --files --restart-policy=always

此命令将在 ~/.config/systemd/user/ 下创建单元文件。生成后,按如下方式启用并启动服务:

systemctl --user daemon-reexec
systemctl --user enable --now container-mycontainer.service

此配置确保 容器在系统启动时自动启动

使用 podman-compose 管理多个容器

除了管理单个容器外,Podman 还支持 多容器编排。通过使用 podman-compose,您可以实现类似 Docker Compose 的功能。

使用 pip 安装 podman-compose:

pip install podman-compose

由于它在很大程度上兼容 docker-compose.yml 文件,您通常可以重用现有的配置。

启动服务只需运行:

podman-compose up -d

即使使用 Podman,也能让您 瞬间重现完整的开发环境

其他有用的命令和技巧

清理未使用的镜像和容器

podman system prune -a

此命令会删除未使用的容器、镜像和临时文件,帮助保持存储空间的整洁。

启用命令补全(bash/zsh)

您可以通过以下软件包安装命令补全支持:

sudo apt install podman-docker

这为 Podman 启用了类似 Docker 的命令补全,提高了工作效率。

7. 迁移指南:从 Docker 到 Podman

为什么迁移到 Podman 正受到关注

Docker 长期以来一直是容器技术的代名词,但近年来,向更轻量、更安全的替代方案 Podman 转变的趋势日益增强。尤其是 Red Hat Enterprise Linux(RHEL)和 Fedora 已减少对 Docker 的支持,并将 Podman 设为默认容器引擎,这促使许多组织考虑迁移。

本节阐述 从 Docker 平稳迁移到 Podman 的实用步骤和重要注意事项

Docker 与 Podman 之间的命令兼容性

Podman 保持了与 Docker 高度兼容的 CLI,允许大多数命令 直接替换且无需修改

DockerPodman
docker build -t myapp .podman build -t myapp .
docker run -it myapppodman run -it myapp
docker imagespodman images
docker pspodman ps

这使得 无需更改工作流程即可切换到 Podman,这也是其最大优势之一。

通过 podman-docker 实现完整兼容性

如果现有脚本、CI/CD 流水线或工具假设存在 docker 命令,您可以安装 podman-docker 软件包,使 Podman 成为即插即用的替代品。

sudo apt install podman-docker

安装后,docker 命令将成为指向 Podman 的符号链接:

which docker
# → /usr/bin/docker → symbolic link to podman

这使得 基于 Docker 的现有脚本可以在 Podman 上运行且无需修改

用 podman-compose 替代 docker-compose

对于使用 Docker Compose 定义多容器环境的项目,podman-compose 提供了兼容的替代方案。

虽然兼容性总体较高,但请注意以下限制:

  • 某些 Compose 选项(如 depends_on)可能不受支持或行为不同
  • 事件日志和健康检查行为可能存在差异

对于典型的配置,如 Web 服务器与数据库的组合,迁移通常相当直接。

迁移镜像和卷

本地存储的 Docker 镜像无法被 Podman 直接访问。您必须重新拉取或导出后再导入。

选项 1:使用 Podman 重新拉取镜像

podman pull ubuntu:22.04

选项 2:从 Docker 导出并导入到 Podman

# Export from Docker
docker save myimage > myimage.tar

# Import into Podman
podman load < myimage.tar

这使得 Docker 构建的镜像可以在 Podman 中复用

其他迁移注意事项

  • 无根操作差异:Docker 通常假设以 root 身份运行,而 Podman 设计为无根操作
  • 守护进程架构:Podman 无守护进程,这改变了后台进程的管理方式
  • 日志和数据存储位置 不同,迁移时应进行审查

8. 常见问题解答 (FAQ)

Q1. Podman 与 Docker 的主要区别是什么?

A1. 最显著的区别是 Podman 在没有守护进程的情况下运行。这使得操作更轻量、更安全。Podman 还支持 无根模式,能够在不提升权限的情况下管理容器。与 Docker 的 CLI 兼容性非常高。

Q2. Dockerfile 与 Containerfile 有何区别?

A2. 实际上 没有功能上的区别。两者都使用相同的语法来描述容器构建指令。
在符合 OCI 标准的项目中更倾向使用 Containerfile 这个名称,以避免 Docker 专有的术语。实际使用中,Dockerfile 在 Podman 中也能完美工作。

Q3. Docker Compose 能在 Podman 中使用吗?

A3. Docker Compose 并未直接受支持,但可以使用 podman-compose 作为替代方案。它能够在 Podman 环境中解释 docker-compose.yml 文件。

某些选项(例如 depends_on)存在限制,因此 对于复杂的部署建议进行测试

Q4. Podman 在 Ubuntu 上运行稳定吗?

A4. 是的。Podman 在 Ubuntu 20.04 LTS 及以后版本 上运行稳定。它已收录在官方的 Ubuntu 软件源中,可通过 apt 轻松安装。对于更新的版本,也可以使用 PPA 进行安装。

Q5. 使用无根模式是否有局限?

A5. 无根模式会限制某些特权操作以及绑定 1024 以下的端口。不过,这些限制通常可以通过端口转发来绕过。对于大多数使用场景,无根模式是完全可行的。

Q6. Podman 能拉取与 Docker Hub 相同的镜像吗?

A6. 可以。Podman 默认可以从 Docker Hub 拉取镜像。在某些环境下,可能需要显式指定注册表和命名空间:

podman pull docker.io/library/ubuntu

Podman 还支持其他注册表,例如 Quay.io 和 GitHub Container Registry。

Q7. Podman 适合生产环境吗?

A7. 可以。Podman 包含生产使用所需的功能,例如 兼容 Kubernetes 的 pod 概念 和 systemd 集成。在对安全性要求较高的环境中,Podman 可能比 Docker 更合适。

Podman 已经是 RHEL 和 Fedora 的默认容器引擎,并在生产环境中得到广泛采用。