跳转到主要内容

Podman 安装说明

在寻找图形用户界面(GUI)吗?你可以在这里找到 Podman Desktop。

在 Mac 和 Windows 上安装

虽然“容器即 Linux”,但 Podman 也可以在 Mac 和 Windows 上运行。在这两个平台上,它提供了一个原生的 podman CLI,并嵌入了一个 Linux 客户机系统来启动你的容器。这个客户机被称为 Podman machine,并通过 podman machine 命令进行管理。Mac 和 Windows 上的 Podman 也会监听 Docker API 客户端,支持直接使用基于 Docker 的工具,以及通过你选择的语言进行程序化访问。

macOS

在 Mac 上,每个 Podman machine 都由一个虚拟机支持。安装后,podman 命令可以直接在终端的 Unix shell 中运行,它会远程与在 Machine VM 中运行的 podman 服务通信。

下载 Podman 安装程序(推荐)

Podman 可以从 Podman.io 网站下载。

我们也在我们的 GitHub 发布页面上传了安装程序和其他二进制文件。

虽然不推荐,但也可以通过包管理器 Homebrew 获取 Podman。

通过 Brew 安装

由于 Brew 是一个社区维护的包管理器,我们无法保证通过 Brew 安装的 Podman 的稳定性。因此,不推荐通过 Brew 安装。

然而,如果你确实希望使用 Brew,你必须首先安装 Homebrew。设置好 brew 后,你可以使用 brew install 命令来安装 Podman。

brew install podman

安装后,你需要创建并启动你的第一个 Podman machine。

podman machine init
podman machine start

然后,你可以使用以下命令验证安装信息:

podman info

我们也在我们的 GitHub 发布页面上提供了二进制文件和一个 pkg 安装程序。

Windows

在 Windows 上,每个 Podman machine 都由一个虚拟化的 Windows Subsystem for Linux (WSLv2) 发行版支持。安装后,podman 命令可以直接从你的 Windows PowerShell(或 CMD)提示符中运行,它会远程与在 WSL 环境中运行的 podman 服务通信。或者,如果你更喜欢 Linux 提示符和 Linux 工具,你也可以直接从 WSL 实例中访问 Podman。

请参阅 Podman for Windows 指南以获取设置和使用说明。

在 Linux 上安装

Linux 发行版

Arch LinuxManjaro Linux

sudo pacman -S podman

如果你在无根模式下运行 Podman 时遇到问题,请按照此处的说明操作。

有关 ArchLinux 上的 Podman 的更多信息,请点击这里

Alpine Linux

sudo apk add podman

更多详情,请参阅 Alpine Linux wiki 上的说明。

CentOS Stream

对于 CentOS Stream 9+,Podman 在默认的 AppStream 仓库中可用。

sudo dnf -y install podman

Debian

podman 软件包在 Debian 11 (Bullseye) 及更高版本的仓库中可用。

sudo apt-get -y install podman

Fedora

sudo dnf -y install podman

要运行 podman machine ... 命令

sudo dnf -y install podman-machine

slirp4netns 不再是新安装 Podman 的无根网络默认选项,已被 passt 取代。如果你有使用 slirp4netns 的容器,请确保已安装 slirp4netns。

sudo dnf -y install slirp4netns

Fedora CoreOSFedora Silverblue

内置,无需安装

Gentoo

sudo emerge app-containers/podman

OpenEmbedded

Podman 及其依赖项的 Bitbake recipes 位于 meta-virtualization layer 中。将该层添加到你的 OpenEmbedded 构建环境,并使用以下命令构建 Podman:

bitbake podman

openSUSE

sudo zypper install podman

openSUSE Kubic

内置,无需安装

Raspberry Pi OS arm64 (beta)

Raspberry Pi OS 使用标准的 Debian 仓库,因此它与 Debian 的 arm64 仓库完全兼容。你只需按照Debian 的步骤即可安装 Podman。

RHEL

请遵循官方文档

Ubuntu

podman 软件包在 Ubuntu 20.10 及更新版本的官方仓库中可用。

# Ubuntu 20.10 and newer
sudo apt-get update
sudo apt-get -y install podman

Linux Mint

请按照 Ubuntu 的步骤操作(如果你使用 LMDE,则按照 Debian 的步骤)。

安装 Podman 的开发版本

Fedora

你可以在 Fedora 的 updates-testing 仓库中测试最新的 Podman,然后再将其发布给所有 Fedora 用户。

sudo dnf update --refresh --enablerepo=updates-testing podman

如果你使用了 Fedora 的 updates-testing 仓库中更新的 Podman 软件包,我们希望你能在 Bodhi(Fedora 的更新管理系统)中给予 +1 反馈。

安装 Podman 的前沿版本

如果你喜欢冒险,并有兴趣在 Fedora、CentOS Stream 9+ 和 RHEL9+ 上测试 Podman 最新未发布的版本,我们有一个 Copr 仓库

注意:此仓库包含使用上游容器工具仓库的 main 分支生成的 rpm 构建,绝不推荐用于任何生产环境。

启用 Copr 并安装 podman。

sudo dnf copr enable rhcontainerbot/podman-next -y
sudo dnf install podman

FreeBSD 14.0 上安装

[!警告]Podman 容器引擎的 FreeBSD 移植版本是实验性的,应仅用于评估和测试目的。

你可以使用 pkg 在 FreeBSD 上安装 Podman。

pkg install podman

还有一个 podman-suite 元软件包,它会为你引入其他软件包(buildah, skopeo)。

初始配置

为了正确支持 Podman 的容器重启策略,conmon 需要将 fdescfs(5) 挂载到 /dev/fd

如果 /dev/fd 尚未挂载

mount -t fdescfs fdesc /dev/fd

要使其永久生效,请将以下行添加到 /etc/fstab

fdesc   /dev/fd         fdescfs         rw      0       0

要在重启后启动 Podman

service podman enable
网络

容器网络依赖 NAT 来允许容器网络数据包发送到主机的网络。这需要一个 PF 防火墙来执行转换。这里提供了一个简单的示例——要使用它:

cp /usr/local/etc/containers/pf.conf.sample /etc/pf.conf

编辑 /etc/pf.conf 并将 v4egress_ifv6egress_if 变量设置为你的网络接口。

启用并启动 pf

service pf enable
service pf start

示例 PF 配置包括对端口重定向的支持。这些被实现为 cni-rdr 下嵌套的锚点中的重定向规则。

FreeBSD 13.3 及更高版本支持将从容器主机到容器内运行的服务的连接进行重定向。要启用此功能,首先加载 pf 内核模块,并使用 sysctl 启用 PF 对这些重定向的支持:

echo 'pf_load="YES"' >> /boot/loader.conf
kldload pf
sysctl net.pf.filter_local=1
echo 'net.pf.filter_local=1' >> /etc/sysctl.conf.local
service pf restart

如果目标地址是 localhost(例如 127.0.0.1 或 ::1),重定向规则将起作用——要启用此功能,必须在你的 /etc/pf.conf 中包含以下行:

nat-anchor "cni-rdr/*"

如果从旧版本升级,需要将此行添加到 /etc/pf.conf

例如,如果主机端口 1234 被重定向到容器中运行的 http 服务,你可以使用以下命令连接到它:

fetch -o- http://$(hostname):1234

fetch -o- https://:1234
存储

容器镜像和相关状态存储在 /var/db/containers 中。建议为此使用 ZFS:

zfs create -o mountpoint=/var/db/containers zroot/containers

如果你的系统不能使用 ZFS,请更改 storage.conf 以使用 vfs 存储驱动程序:

sed -I .bak -e 's/driver = "zfs"/driver = "vfs"/' /usr/local/etc/containers/storage.conf
验证

完成这些步骤后,你应该能够运行原生镜像:

podman run --rm docker.io/dougrabson/hello
Linux 仿真

可以使用 FreeBSD 的 Linux 仿真功能运行许多 Linux 容器镜像:

sudo sysrc linux_enable=YES
sudo service linux start
sudo podman run --rm --os=linux docker.io/library/alpine cat /etc/os-release | head -1
NAME="Alpine Linux"

从源码构建

构建和运行依赖项

必需

在 Fedora 上

# Install build dependencies
sudo dnf -y builddep rpm/podman.spec

# Install runtime dependencies
sudo dnf -y install catatonit conmon containers-common-extra

在所有 RHEL 和 CentOS Stream 上,首先安装 dnf-builddep

sudo dnf -y install 'dnf-command(builddep)'

安装构建依赖项

# CentOS Stream 9+
sudo dnf -y builddep rpm/podman.spec --enablerepo=crb

# RHEL 9+
sudo dnf -y builddep rpm/podman.spec --enablerepo=codeready-builder-for-rhel-$(rpm --eval %{?rhel})-$(uname -m)-rpms

安装运行时依赖项

sudo dnf -y install \
conmon \
containers-common \
crun \
iptables \
netavark \
nftables \
slirp4netns

Debian、Ubuntu 及相关发行版

sudo apt-get install \
btrfs-progs \
gcc \
git \
golang-go \
go-md2man \
iptables \
libassuan-dev \
libbtrfs-dev \
libc6-dev \
libdevmapper-dev \
libglib2.0-dev \
libgpgme-dev \
libgpg-error-dev \
libprotobuf-dev \
libprotobuf-c-dev \
libseccomp-dev \
libselinux1-dev \
libsystemd-dev \
make \
netavark \
passt \
pkg-config \
runc \
uidmap

在旧的 Debian / Ubuntu 版本上可能没有 netavark 软件包。请改为安装 containernetworking-plugins 软件包。

在 openSUSE Leap 15.x 和 Tumbleweed 上

sudo zypper -n in libseccomp-devel libgpgme-devel

在 Manjaro(以及可能的其他 Linux 发行版)上

确保 Linux 内核支持用户命名空间

> zgrep CONFIG_USER_NS /proc/config.gz
CONFIG_USER_NS=y

如果不支持,请更新内核。对于 Manjaro Linux,说明可以在这里找到:https://wiki.manjaro.org/index.php/Manjaro_Kernels

之后启用用户命名空间

sudo sysctl kernel.unprivileged_userns_clone=1

要永久启用用户命名空间

echo 'kernel.unprivileged_userns_clone=1' | sudo tee /etc/sysctl.d/userns.conf > /dev/null

构建缺失的依赖项

如果任何依赖项无法安装或版本不够新,它们必须从源代码构建。这主要会影响 Debian、Ubuntu 及相关发行版,或者没有激活订阅的 RHEL(例如云虚拟机)。

golang

请仔细检查 golang 的版本是否足够新(即 go version),截至 2025 年 8 月,需要 1.23.x 或更高版本。当前的最低要求版本始终可以在 go.mod 文件中找到。如果需要,golang 工具包可在 https://golang.ac.cn/dl/ 获取。或者,go 可以从源代码构建,如下所示(保留系统安装的 go 会很有帮助,以避免需要引导 go):

export GOPATH=~/go
git clone https://go.googlesource.com/go $GOPATH
cd $GOPATH
cd src
./all.bash
export PATH=$GOPATH/bin:$PATH

conmon

系统上应安装最新版本的 conmon。Conmon 用于监控 OCI 运行时。要从源代码构建,请使用以下命令:

git clone https://github.com/containers/conmon
cd conmon
export GOCACHE="$(mktemp -d)"
make
sudo make podman

crun / runc

系统上应安装至少一个容器运行时的最新版本。crunrunc 是一些可能性,Podman 会选择其中一个作为默认运行时(crun 的优先级高于 runc)。例如,Ubuntu 22.04 上有受支持的 crunrunc 版本。runc 1.0.0-rc4 是最低要求版本,自 Ubuntu 18.04 起可用。

要仔细检查,runc --version 应该至少产生 spec: 1.0.1,否则请自行构建:

git clone https://github.com/opencontainers/runc.git $GOPATH/src/github.com/opencontainers/runc
cd $GOPATH/src/github.com/opencontainers/runc
make BUILDTAGS="selinux seccomp"
sudo cp runc /usr/bin/runc

添加配置

sudo mkdir -p /etc/containers
sudo curl -L -o /etc/containers/registries.conf https://raw.githubusercontent.com/containers/image/main/registries.conf
sudo curl -L -o /etc/containers/policy.json https://raw.githubusercontent.com/containers/image/main/default-policy.json

可选软件包

Fedora、CentOS、RHEL 及相关发行版

(无可选软件包)

Debian、Ubuntu 及相关发行版

apt-get install -y \
libapparmor-dev

获取源代码

首先,确保在 $PATH 中首先找到的 go version 是 1.23.x 或更高版本。如果需要,上面的说明将帮助你编译更新版本的 Go。然后我们可以构建 Podman:

git clone https://github.com/containers/podman/
cd podman
make BUILDTAGS="selinux seccomp" PREFIX=/usr
sudo env PATH=$PATH make install PREFIX=/usr

构建标签

另外,如果你不想在构建 Podman 时包含 seccomp 或 selinux 支持,你可以在运行 make 时添加 BUILDTAGS=""

make BUILDTAGS=""
sudo make install

Podman 支持可选的构建标签,用于编译各种功能的支持。要向 make 选项添加构建标签,必须设置 BUILDTAGS 变量,例如:

make BUILDTAGS='seccomp apparmor'

如果你在 RHEL8 上构建,由于 btrfs 已被移除,你需要构建时不带 btrfs 支持。

make BUILDTAGS="btrfs_noversion exclude_graphdriver_btrfs"
构建标签功能依赖项
apparmorapparmor 支持libapparmor
cniCNI 网络
exclude_graphdriver_btrfs排除 btrfslibbtrfs
exclude_graphdriver_devicemapper排除 device-mapperlibdm
libdm_no_deferred_remove在 libdm 中排除延迟移除libdm
seccomp系统调用过滤libseccomp
selinuxselinux 进程和挂载标记
systemdjournald 日志记录libsystemd

请注意,Podman 不正式支持 device-mapper。因此,exclude_graphdriver_devicemapper 标签是强制性的。

Vendoring - 依赖管理

该项目使用 go modules 进行依赖管理。如果 CI 抱怨拉取请求留下了不干净的状态,那很可能是对的。更改依赖项后,请确保运行 make vendor 以将代码与 go 模块同步,并重新填充 ./vendor 目录。

Ansible

还有一个 Ansible Role 可用于在其支持的操作系统上自动安装上述静态链接的二进制文件。

sudo su -
mkdir -p ~/.ansible/roles
cd ~/.ansible/roles
git clone https://github.com/alvistack/ansible-role-podman.git podman
cd ~/.ansible/roles/podman
pip3 install --upgrade --ignore-installed --requirement requirements.txt
molecule converge
molecule verify

配置文件

registries.conf

手册页:registries.conf.5

/etc/containers/registries.conf

registries.conf 是一个配置文件,用于指定在补全不包含注册表或域部分的镜像名称时应查询哪些容器注册表。

注意:在 macOS 或 Windows 上,请运行 podman machine ssh 命令进入 machine VM,并使用相同的配置内容编辑 /etc/containers/registries.conf 文件。如果遇到权限问题,请运行 podman machine set --rootful 后重试。

来自 Fedora containers-common 软件包的示例

$ cat /etc/containers/registries.conf
# For more information on this configuration file, see containers-registries.conf(5).
#
# NOTE: RISK OF USING UNQUALIFIED IMAGE NAMES
# We recommend always using fully qualified image names including the registry
# server (full dns name), namespace, image name, and tag
# (e.g., registry.redhat.io/ubi8/ubi:latest). Pulling by digest (i.e.,
# quay.io/repository/name@digest) further eliminates the ambiguity of tags.
# When using short names, there is always an inherent risk that the image being
# pulled could be spoofed. For example, a user wants to pull an image named
# `foobar` from a registry and expects it to come from myregistry.com. If
# myregistry.com is not first in the search list, an attacker could place a
# different `foobar` image at a registry earlier in the search list. The user
# would accidentally pull and run the attacker's image and code rather than the
# intended content. We recommend only adding registries which are completely
# trusted (i.e., registries which don't allow unknown or anonymous users to
# create accounts with arbitrary names). This will prevent an image from being
# spoofed, squatted or otherwise made insecure. If it is necessary to use one
# of these registries, it should be added at the end of the list.
#
# # An array of host[:port] registries to try when pulling an unqualified image, in order.
unqualified-search-registries = ["registry.fedoraproject.org", "registry.access.redhat.com", "docker.io"]
#
# [[registry]]
# # The "prefix" field is used to choose the relevant [[registry]] TOML table;
# # (only) the TOML table with the longest match for the input image name
# # (taking into account namespace/repo/tag/digest separators) is used.
# #
# # If the prefix field is missing, it defaults to be the same as the "location" field.
# prefix = "example.com/foo"
#
# # If true, unencrypted HTTP as well as TLS connections with untrusted
# # certificates are allowed.
# insecure = false
#
# # If true, pulling images with matching names is forbidden.
# blocked = false
#
# # The physical location of the "prefix"-rooted namespace.
# #
# # By default, this equal to "prefix" (in which case "prefix" can be omitted
# # and the [[registry]] TOML table can only specify "location").
# #
# # Example: Given
# # prefix = "example.com/foo"
# # location = "internal-registry-for-example.net/bar"
# # requests for the image example.com/foo/myimage:latest will actually work with the
# # internal-registry-for-example.net/bar/myimage:latest image.
# location = "internal-registry-for-example.com/bar"
#
# # (Possibly-partial) mirrors for the "prefix"-rooted namespace.
# #
# # The mirrors are attempted in the specified order; the first one that can be
# # contacted and contains the image will be used (and if none of the mirrors contains the image,
# # the primary location specified by the "registry.location" field, or using the unmodified
# # user-specified reference, is tried last).
# #
# # Each TOML table in the "mirror" array can contain the following fields, with the same semantics
# # as if specified in the [[registry]] TOML table directly:
# # - location
# # - insecure
# [[registry.mirror]]
# location = "example-mirror-0.local/mirror-for-foo"
# [[registry.mirror]]
# location = "example-mirror-1.local/mirrors/foo"
# insecure = true
# # Given the above, a pull of example.com/foo/image:latest will try:
# # 1. example-mirror-0.local/mirror-for-foo/image:latest
# # 2. example-mirror-1.local/mirrors/foo/image:latest
# # 3. internal-registry-for-example.net/bar/image:latest
# # in order, and use the first one that exists.
#
# short-name-mode="enforcing"

[[registry]]
location="localhost:5000"
insecure=true

mounts.conf

/usr/share/containers/mounts.conf 和可选的 /etc/containers/mounts.conf

mounts.conf 文件指定了在执行 podman runpodman build 命令时自动挂载到容器内的卷挂载目录。容器进程随后可以使用这些内容。卷挂载的内容不会被提交到最终镜像中。

通常这些目录用于传递软件包软件访问远程软件包仓库所需的机密或凭据。

例如,一个包含 "/usr/share/rhel/secrets:/run/secrets" 行的 mounts.conf 文件,会将 /usr/share/rhel/secrets 目录的内容挂载到容器内的 /run/secrets。此挂载点允许在容器内使用来自主机的 Red Hat Enterprise Linux 订阅。

请注意,这不是一个卷挂载。卷的内容被复制到容器存储中,而不是直接从主机绑定挂载。

来自 Fedora containers-common 软件包的示例:

cat /usr/share/containers/mounts.conf
/usr/share/rhel/secrets:/run/secrets

seccomp.json

/usr/share/containers/seccomp.json

seccomp.json 包含了允许在容器内使用的 seccomp 规则白名单。此文件通常由 containers-common 软件包提供。

上面的链接将带你到 seccomp.json

policy.json

/etc/containers/policy.json

手册页:policy.json.5

来自 Fedora containers-common 软件包的示例:

cat /etc/containers/policy.json
{
"default": [
{
"type": "insecureAcceptAnything"
}
],
"transports":
{
"docker-daemon":
{
"": [{"type":"insecureAcceptAnything"}]
}
}
}