1. 简介

本文将介绍 Podman(全称 “Pod Manager”)的基本概念、核心特性及其使用方式。

2. Podman 概述

Podman 是一个开源的容器管理工具,用于开发、管理和运行符合 OCI(Open Container Initiative)标准的容器。相比其他容器管理工具,它有以下几个显著优势:

镜像兼容性强
Podman 创建的镜像遵循 OCI 标准,因此可以推送到 Docker Hub 等主流镜像仓库,实现与其他容器工具的无缝对接。

支持无 root 权限运行
普通用户无需 root 权限即可运行 Podman。它通过创建一个用户命名空间,在该命名空间内获取 root 权限,从而实现文件系统挂载和容器配置等操作。

支持 Pod 管理
与传统容器运行时不同,Podman 支持 Pod(一组协同工作的容器)的创建、查看、管理等操作。

当然,Podman 也有一些限制:

仅支持 Linux 系统
目前 Podman 仅能在 Linux 系统上运行,暂不提供 macOS 或 Windows 的封装支持。

缺少 Docker Compose 的完整替代方案
虽然社区正在开发基于 Podman 的 podman-compose 项目,但目前仍处于开发阶段,功能尚未完全覆盖 Docker Compose 的全部能力。

3. 与 Docker 的对比

了解完 Podman 的基本特性后,我们将其与目前最流行的容器管理工具 Docker 进行对比。

3.1. 命令行接口(CLI)

Podman 的命令与 Docker 高度兼容,两者之间命令基本一一对应。例如 podman rundocker run 功能相似。

⚠️ 但需注意:podman pspodman images 不会显示 Docker 创建的容器或镜像。因为 Podman 的本地仓库路径为 /var/lib/containers,而 Docker 使用的是 /var/lib/docker

3.2. 容器模型

Docker 采用客户端-服务端架构,通过 Docker Daemon 协调 API 请求。

Podman 则采用 Linux 常见的 fork-exec 模型,创建的容器是 Podman 进程的子进程。这意味着 Podman 本身就是一个运行中的进程,不需要后台守护进程。

例如运行 docker version 会显示客户端与服务端版本信息:

Client:
 Version:       17.12.0-ce
 API version:   1.35
 Go version:    go1.9.2
 Git commit:    c97c6d6
 Built: Wed Dec 27 20:11:19 2017
 OS/Arch:       linux/amd64

Server:
 Engine:
  Version:      17.12.0-ce
  API version:  1.35 (minimum version 1.12)
  Go version:   go1.9.2
  Git commit:   c97c6d6
  Built:        Wed Dec 27 20:09:53 2017
  OS/Arch:      linux/amd64
  Experimental: false

而运行 podman version 仅显示 Podman 自身的版本信息:

Version:       0.3.2-dev
Go Version:    go1.9.4
Git Commit:    "4f4a78abb40fa0e8407e8a55d5a67a2650d8fd96"
Built:         Mon Mar  5 11:10:35 2018
OS/Arch:       linux/amd64

3.3. 无 root 模式(Rootless Mode)

如前所述,Podman 不需要 root 权限即可运行。而 Docker 必须依赖 daemon 进程,因此用户必须是 docker 用户组成员或具有 root 权限

$ sudo usermod -aG docker $USER

4. 安装与使用

我们从安装 Podman 开始。可以参考 Podman 官方安装指南 进行安装。

安装完成后,使用以下命令查看系统信息以验证安装状态:

$ podman info

输出内容包括主机信息(如内核版本、内存使用等)和 Podman 配置信息(如镜像仓库、存储路径等):

host:
  MemFree: 546578432
  MemTotal: 1040318464
  SwapFree: 4216320000
  SwapTotal: 4216320000
  arch: amd64
  cpus: 2
  hostname: base-xenial
  kernel: 4.4.0-116-generic
  os: linux
  uptime: 1m 2.64s
insecure registries:
  registries: []
registries:
  registries:
  - docker.io
  - registry.fedoraproject.org
  - registry.access.redhat.com
store:
  ContainerStore:
    number: 0
  GraphDriverName: overlay
  GraphOptions: null
  GraphRoot: /var/lib/containers/storage
  GraphStatus:
    Backing Filesystem: extfs
    Native Overlay Diff: "true"
    Supports d_type: "true"
  ImageStore:
    number: 0
  RunRoot: /var/run/containers/storage

4.1. 构建镜像

首先创建一个 Dockerfile:

FROM centos:latest
RUN yum -y install httpd
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
EXPOSE 80

然后使用以下命令构建镜像:

$ podman build .

⚠️ 注意:构建时默认使用当前目录作为上下文,建议不要将无关文件放入该目录。

4.2. 查看镜像列表

使用以下命令查看本地镜像:

$ podman images

输出示例:

REPOSITORY                 TAG      IMAGE ID         CREATED         SIZE
docker.io/library/centos   latest  0f3e07c0138f    2 months ago      227MB
<none>                     <none   49030e844ce7   27 seconds ago     277MB

4.3. 运行容器

使用 run 命令启动容器:

$ podman run  -p 80:80 -dit centos
  • -p 80:80 表示将容器的 80 端口映射到宿主机的 80 端口
  • -dit 表示以分离模式运行并保持交互状态

4.4. 删除镜像

使用 rmi 删除本地镜像:

$ podman rmi 785188cd988c

-a 可删除所有镜像:

$ podman rmi -a

4.5. 查看容器列表

查看所有容器(包括未运行的):

$ podman ps -a

输出示例:

CONTAINER ID   IMAGE    COMMAND     CREATED AT                      STATUS              PORTS                                    NAMES
eed30719cd37   centos   /bin/bash   2019-12-09 02:57:37 +0000 UTC   Up 14 minutes ago   0.0.0.0:80->80/udp, 0.0.0.0:80->80/tcp   reverent_liskov

4.6. 删除容器

先停止容器再删除:

$ podman stop eed30719cd37
$ podman rm eed30719cd37

4.7. 创建 Pod

使用以下命令创建一个 Pod:

$ podman pod create

默认会创建一个 infra 容器,用于 Pod 内部网络通信。可通过以下命令禁用:

$ podman pod create --infra=false

4.8. 查看 Pod 列表

使用以下命令查看所有 Pod:

$ podman pod list

输出示例:

POD ID         NAME             STATUS      CREATED       # OF CONTAINERS   INFRA ID
7e0a68528aed   gallant_raman    Running    5 seconds ago        1           c6d06673c667

完整命令参考请查看 Podman 官方文档

5. 小结

本文介绍了 Podman 的基本概念、主要特性,并与 Docker 进行了对比,同时演示了常用命令的使用方法。

如需获取本文所用代码示例,可访问 GitHub 仓库


原始标题:An Introduction to Podman