跳至主要内容

Podman 安装说明

正在寻找 GUI?您可以在此处找到 Podman Desktop 此处

在 Mac 和 Windows 上安装

虽然“容器是 Linux”,但 Podman 也可以在 Mac 和 Windows 上运行,它提供原生 podman CLI 并嵌入一个访客 Linux 系统来启动您的容器。此访客称为 Podman 机器,并使用 podman machine 命令进行管理。Mac 和 Windows 上的 Podman 还会侦听 Docker API 客户端,支持直接使用基于 Docker 的工具以及从您选择的语言进行编程访问。

macOS

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

下载 Podman 安装程序(推荐)

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

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

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

通过 Brew 安装

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

但是,如果您确实希望使用 Brew,则必须首先安装 Homebrew。设置好 brew 后,您可以使用 brew install 命令安装 Podman

brew install podman

安装后,您需要创建并启动您的第一个 Podman 机器

podman machine init
podman machine start

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

podman info

我们还在我们的 Github 发布页面 上提供了二进制文件和 pkginstaller。

Windows

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

请参阅 适用于 Windows 的 Podman 指南,了解设置和使用说明。

在 Linux 上安装

Linux 发行版

Arch LinuxManjaro Linux

sudo pacman -S podman

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

有关 ArchLinux 上 Podman 的更多信息,请点击此处

Alpine Linux

sudo apk add podman

有关更多详细信息,请参阅 Alpine Linux wiki 上的说明。

CentOS Stream

Podman 在 CentOS Stream 9+ 的 AppStream 存储库中默认可用。

sudo dnf -y install podman

Debian

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

sudo apt-get -y install podman

Fedora

sudo dnf -y install podman

Fedora CoreOSFedora Silverblue

内置,无需安装

Gentoo

sudo emerge app-containers/podman

OpenEmbedded

Podman 及其依赖项的 Bitbake 配方在 meta-virtualization 层 中可用。将该层添加到您的 OpenEmbedded 构建环境中,并使用以下命令构建 Podman

bitbake podman

openSUSE

sudo zypper install podman

openSUSE Kubic

内置,无需安装

Raspberry Pi OS arm64(测试版)

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 的步骤操作)。

对于 Ubuntu 步骤,请将 $(lsb_release -rs) 替换为 $(grep DISTRIB_RELEASE= /etc/upstream-release/lsb-release | cut -d "=" -f 2)

安装 Podman 的开发版本

Fedora

您可以在 Podman 推送到所有 Fedora 用户之前,在 Fedora 的 updates-testing 存储库中测试最新的 Podman。

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

如果目标地址是本地主机(例如 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://127.0.0.1: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 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 \
crun \
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 \
pkg-config \
uidmap

netavark 包可能在较旧的 Debian/Ubuntu 版本上不可用。请改用安装 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' > /etc/sysctl.d/userns.conf

构建缺失的依赖项

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

golang

请务必仔细检查 golang 版本是否足够新(即 go version),截至 2022 年 1 月,需要 1.16.x 或更高版本。可以在 go.mod 文件中找到当前所需的最低版本。如果需要,可以在 https://golang.ac.cn/dl/ 获取 golang 工具包。或者,可以按如下方式从源代码构建 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.16.x 或更高版本。如果需要,上述说明将帮助您编译更新版本的 Go。然后我们可以构建 Podman

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

构建标签

否则,如果您不想构建带有 seccomp 或 selinux 支持的 Podman,可以在运行 make 时添加 BUILDTAGS=""

make BUILDTAGS=""
sudo make install

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

make BUILDTAGS='seccomp apparmor'

如果您在 RHEL8 上构建,则由于 已移除,因此您需要在没有 btrfs 支持的情况下进行构建。

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

请注意,Podman 不正式支持设备映射器。因此,exclude_graphdriver_devicemapper 标签是必需的。

供应商 - 依赖项管理

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

Ansible

还提供了一个 Ansible 角色 来自动化在其支持的操作系统上安装上述静态链接的二进制文件。

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 是配置文件,用于指定在完成不包含注册表或域部分的镜像名称时应查询哪些容器注册表。

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"}]
}
}
}