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 Linux 和 Manjaro 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 CoreOS、Fedora 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_if
、v6egress_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
系统上应安装至少一个容器运行时的最新版本。crun
或 runc
是一些可能性,Podman 会选择其中一个作为默认运行时(crun 的优先级高于 runc)。例如,Ubuntu 22.04 上有受支持的 crun
或 runc
版本。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"
构建标签 | 功能 | 依赖项 |
---|---|---|
apparmor | apparmor 支持 | libapparmor |
cni | CNI 网络 | |
exclude_graphdriver_btrfs | 排除 btrfs | libbtrfs |
exclude_graphdriver_devicemapper | 排除 device-mapper | libdm |
libdm_no_deferred_remove | 在 libdm 中排除延迟移除 | libdm |
seccomp | 系统调用过滤 | libseccomp |
selinux | selinux 进程和挂载标记 | |
systemd | journald 日志记录 | 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 run
或 podman 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"}]
}
}
}