跳至内容

Podman

简介

注意

本文档包含对其此处找到的父文档的扩展内容。如果您需要快速操作指南,该父文档可能就足够了。

Podman (Pod Manager) 是一个兼容OCI (Open Container Initiative) 的容器和镜像管理工具。

Podman

  • 无需守护进程即可工作(可以将容器作为 systemd 服务运行)
  • 允许您作为非特权用户管理容器(无需 root 权限)
  • 包含在 Rocky Linux 存储库中,而 docker 不包含

这使得 Podman 不仅仅是与 docker 兼容的替代容器运行时,而且功能远不止于此。

安装 Podman

使用 dnf 实用程序安装 Podman

dnf install podman

您可以使用以下命令检索可用的 Podman 子命令列表

$ podman --help

Manage pods, containers and images

Usage:
  podman [options] [command]

Available Commands:
  attach      Attach to a running container
  auto-update Auto update containers according to their auto-update policy
...

以下是常用子命令的非详尽列表

子命令 描述
build 使用 Containerfiles 中的指令构建镜像
commit 基于更改的容器创建新镜像
container 管理容器
cp 在容器和本地文件系统之间复制文件/文件夹
create 创建但不启动容器
exec 在运行的容器中运行进程
image 管理镜像
images 列出本地存储中的镜像
信息 显示 Podman 系统信息
init 初始化一个或多个容器
inspect 显示由 ID 标识的对象的配置
kill 使用特定信号杀死一个或多个正在运行的容器
login 登录到容器注册表
logs 获取一个或多个容器的日志
network 管理网络
pause 暂停一个或多个容器中的所有进程
ps 列出容器
pull 从注册表中拉取镜像
push 将镜像推送到指定的目标
restart 重启一个或多个容器
rm 删除一个或多个容器
rmi 从本地存储中删除一个或多个镜像
run 在新的容器中运行命令
start 启动一个或多个容器
stats 显示容器资源使用统计信息的实时流
stop 停止一个或多个容器
system 管理 Podman
top 显示容器正在运行的进程
unpause 取消暂停一个或多个容器中的进程
volume 管理卷

注意

Podman 可以运行几乎任何 Docker 命令,因为其 CLI 接口相似。

如果您需要使用 compose 文件,请记住从 EPEL 安装 podman-compose

dnf install epel-release
dnf install podman-compose

添加容器

Nextcloud 自托管云平台为例运行

podman run -d -p 8080:80 nextcloud

注意

开箱即用,Rocky Linux 启用了 firewalld,并可能阻止端口 8080。请遵循指南打开端口,以便能够访问服务。

您将收到一个提示,要求您选择要从中下载的容器注册表。在我们的示例中,您将使用 docker.io/library/nextcloud:latest

下载 Nextcloud 镜像后,它将开始运行。

在您的 Web 浏览器中输入 ip_address:8080(假设您已在 firewalld 中打开了端口)并设置 Nextcloud

Nextcloud in container

技巧

要跟踪最后一个创建的容器的日志输出,请使用 podman logs -lf-l 指定使用最后一个创建的容器,而 -f 指定跟踪日志,因为它们正在创建。按 Ctrl+C 停止日志输出。

将容器作为 systemd 服务运行

使用 quadlet

自 4.4 版本起,Podman 提供了 Quadlet – 一个 systemd 生成器。它可用于为无 root 和有 root 的 systemd 服务生成 unit 文件。

将有 root 服务的 Quadlet 文件放在

  • /etc/containers/systemd/
  • /usr/share/containers/systemd/

将无 root 文件放在任何一个

  • $XDG_CONFIG_HOME/containers/systemd/~/.config/containers/systemd/
  • /etc/containers/systemd/users/$(UID)
  • /etc/containers/systemd/users/

除了单个容器,还支持 pod、image、network、volume 和 kube 文件。让我们专注于我们的 Nextcloud 示例。创建一个新文件 ~/.config/containers/systemd/nextcloud.container,内容如下:

[Container]
Image=nextcloud
PublishPort=8080:80

提供了许多其他选项

要运行生成器并让 systemd 知道有新服务,请运行

systemctl --user daemon-reload

要现在运行您的服务,请运行

systemctl --user start nextcloud.service

注意

如果您在有 root 服务的目录之一中创建了文件,请省略 --user 标志。

要使容器在系统启动或用户登录时自动运行,您可以向 nextcloud.container 文件添加另一个部分

[Install]
WantedBy=default.target

由于生成的服务文件被视为瞬态文件,因此 systemd 无法启用它们。为了解决这个问题,生成器会在生成过程中手动应用安装。这有效地也启用了这些服务文件。

支持其他文件类型:pod、volume、network、image 和 kube。例如,Pod 可用于对容器进行分组 – 生成的 systemd 服务及其依赖项(在容器之前创建 Pod)由 systemd 自动管理。

使用 podman generate systemd

Podman 还提供了 generate systemd 子命令。使用此子命令生成 systemd 服务文件。

警告

generate systemd 已弃用,将不再提供新功能。建议使用 Quadlet。

现在让我们用 Nextcloud 来做。运行

podman ps

您将获得正在运行的容器列表

04f7553f431a  docker.io/library/nextcloud:latest  apache2-foregroun...  5 minutes ago  Up 5 minutes  0.0.0.0:8080->80/tcp  compassionate_meninsky

如上所述,我们的容器名称是 compassionate_meninsky

要为 Nextcloud 容器创建一个 systemd 服务并在重启时启用它,请运行以下命令

podman generate systemd --name compassionate_meninsky > /usr/lib/systemd/system/nextcloud.service
systemctl enable nextcloud

compassionate_meninsky 替换为您容器的指定名称。

当您的系统重启时,Nextcloud 将在 Podman 中重新启动。

Containerfiles

Containerfile 是 Podman 用于创建容器镜像的文件。Containerfiles 使用与 Dockerfiles 相同的语法,因此您可以使用 Podman 构建容器镜像,就像使用 Docker 一样。

从 Containerfile 创建 Web 服务器

您将基于 RockyLinux 9 创建一个 httpd 服务器。

创建一个专门用于我们镜像的文件夹

mkdir myrocky && cd myrocky

创建一个将在我们的 Web 服务器中运行的 index.html 文件

echo "Welcome to Rocky" > index.html

创建一个 Containerfile 文件,内容如下:

# Use the latest rockylinux image as a start
FROM rockylinux:9

# Make it uptodate
RUN dnf -y update
# Install and enable httpd
RUN dnf -y install httpd
RUN systemctl enable httpd
# Copy the local index.html file into our image
COPY index.html /var/www/html/

# Expose the port 80 to the outside
EXPOSE 80

# Start the services
CMD [ "/sbin/init" ]

您已准备好构建名为 myrockywebserver 的镜像

$ podman build -t myrockywebserver .

STEP 1/7: FROM rockylinux:9
Resolved "rockylinux" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull docker.io/library/rockylinux:9...
Getting image source signatures
Copying blob 489e1be6ce56 skipped: already exists
Copying config b72d2d9150 done
Writing manifest to image destination
STEP 2/7: RUN dnf -y update
Rocky Linux 9 - BaseOS                          406 kB/s | 2.2 MB     00:05    
Rocky Linux 9 - AppStream                       9.9 MB/s | 7.4 MB     00:00    
Rocky Linux 9 - Extras                           35 kB/s |  14 kB     00:00    
Dependencies resolved.
================================================================================
 Package                   Arch      Version                 Repository    Size
================================================================================
Upgrading:
 basesystem                noarch    11-13.el9.0.1           baseos       6.4 k
 binutils                  x86_64    2.35.2-42.el9_3.1       baseos       4.5 M
...
Complete!
--> 2e8b93d30f31
STEP 3/7: RUN dnf -y install httpd
Last metadata expiration check: 0:00:34 ago on Wed Apr  3 07:29:56 2024.
Dependencies resolved.
================================================================================
 Package                Arch       Version                  Repository     Size
================================================================================
Installing:
 httpd                  x86_64     2.4.57-5.el9             appstream      46 k
...
Complete!
--> 71db5cabef1e
STEP 4/7: RUN systemctl enable httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service  /usr/lib/systemd/system/httpd.service.
--> 423d45a3cb2d
STEP 5/7: COPY index.html /var/www/html/
--> dfaf9236ebae
STEP 6/7: EXPOSE 80
--> 439bc5aee524
STEP 7/7: CMD [ "/sbin/init" ]
COMMIT myrockywebserver
--> 7fcf202d3c8d
Successfully tagged localhost/myrockywebserver:latest
7fcf202d3c8d059837cc4e7bc083a526966874f978cd4ab18690efb0f893d583

您可以运行您的 Podman 镜像并确认它已启动

$ podman run -d --name rockywebserver -p 8080:80 localhost/myrockywebserver
282c09eecf845c7d9390f6878f9340a802cc2e13d654da197d6c08111905f1bd

$ podman ps
CONTAINER ID  IMAGE                              COMMAND     CREATED         STATUS         PORTS                 NAMES
282c09eecf84  localhost/myrockywebserver:latest  /sbin/init  16 seconds ago  Up 16 seconds  0.0.0.0:8080->80/tcp  rockywebserver

您以守护进程模式 (-d) 启动了您的 Podman 镜像,并将其命名为 rockywebserver(选项 --name)。

您使用 -p 选项将端口 80(受保护)重定向到端口 8080。使用以下命令查看端口是否正在监听:

ss -tuna | grep "*:8080"
tcp   LISTEN    0      4096                *:8080             *:*

验证 index.html 文件是否可访问

$ curl https://:8080
Welcome to Rocky

恭喜!现在您可以停止并销毁正在运行的镜像,使用您在创建时提供的名称

podman stop rockywebserver && podman rm rockywebserver

技巧

您可以在停止后添加 --rm 开关以自动删除容器。

如果您重新启动构建过程,podman 将在构建的每个步骤中使用缓存

$ podman build -t myrockywebserver .

STEP 1/7: FROM rockylinux:9
STEP 2/7: RUN dnf -y update
--> Using cache 2e8b93d30f3104d77827a888fdf1d6350d203af18e16ae528b9ca612b850f844
--> 2e8b93d30f31
STEP 3/7: RUN dnf -y install httpd
--> Using cache 71db5cabef1e033c0d7416bc341848fbf4dfcfa25cd43758a8b264ac0cfcf461
--> 71db5cabef1e
STEP 4/7: RUN systemctl enable httpd
--> Using cache 423d45a3cb2d9f5ef0af474e4f16721f4c84c1b80aa486925a3ae2b563ba3968
--> 423d45a3cb2d
STEP 5/7: COPY index.html /var/www/html/
--> Using cache dfaf9236ebaecf835ecb9049c657723bd9ec37190679dd3532e7d75c0ca80331
--> dfaf9236ebae
STEP 6/7: EXPOSE 80
--> Using cache 439bc5aee524338a416ae5080afbbea258a3c5e5cd910b2485559b4a908f81a3
--> 439bc5aee524
STEP 7/7: CMD [ "/sbin/init" ]
--> Using cache 7fcf202d3c8d059837cc4e7bc083a526966874f978cd4ab18690efb0f893d583
COMMIT myrockywebserver
--> 7fcf202d3c8d
Successfully tagged localhost/myrockywebserver:latest
7fcf202d3c8d059837cc4e7bc083a526966874f978cd4ab18690efb0f893d583

您可以使用 prune 子命令清除该缓存

podman system prune -a -f
选项 描述
-a 删除所有未使用的数据,不仅限于 Podman 外部的数据
-f 无确认提示
--volumes 清理卷

Pod

Pod 是一种将容器分组的方式。Pod 中的容器共享一些设置,例如挂载、资源分配或端口映射。

在 Podman 中,您使用 podman pod 子命令来管理 Pod,类似于许多 Podman 命令来控制容器

命令 描述
clone 创建现有 Pod 的副本。
create 创建新 Pod。
exists 检查 Pod 是否存在于本地存储中。
inspect 显示描述 Pod 的信息。
kill 杀死一个或多个 Pod 中每个容器的主进程。
logs 显示带有零个或多个容器的 Pod 的日志。
pause 暂停一个或多个 Pod。
prune 删除所有已停止的 Pod 及其容器。
ps 打印 Pod 的信息。
restart 重启一个或多个 Pod。
rm 删除一个或多个已停止的 Pod 和容器。
start 启动一个或多个 Pod。
stats 显示一个或多个 Pod 中容器的实时资源使用统计信息流。
stop 停止一个或多个 Pod。
top 显示 Pod 中容器的正在运行的进程。
unpause 取消暂停一个或多个 Pod。

分组到 Pod 中的容器可以通过使用 localhost 相互访问。例如,当使用 Postgres 等专用数据库设置 Nextcloud 时,这很有用。Nextcloud 可以访问数据库,但数据库不需要从容器外部访问。

要创建一个包含 Nextcloud 和专用数据库的 Pod,请运行以下命令:

# Create the pod with a port mapping
podman pod create --name nextcloud -p 8080:80

# Add a Nextcloud container to the pod – the port mapping must not be specified again!
podman create --pod nextcloud --name nextcloud-app nextcloud

# Add a Postgres database. This container has a postgres specific environment variable set.
podman create --pod nextcloud --name nextcloud-db -e POSTGRES_HOST_AUTH_METHOD=trust postgres

要运行您新创建的 Pod,请运行:

podman pod start nextcloud

您现在可以使用本地数据库设置 Nextcloud

Nextcloud setting up a database

作者:Neel Chauhan,Antoine Le Morvan

贡献者:Steven Spencer,Ganna Zhyrnova,Christian Steinert