波德曼 是迄今为止我最喜欢的容器管理工具之一。 它具有无守护进程架构,允许非特权用户在没有 root 访问权限的情况下运行容器,进一步增强了系统安全性。
这并不意味着 Podman 是完美的,没有问题。 令人头疼的一个问题是它的重启政策。 服务器重新启动后,容器不会自动重新启动。
问题:容器重启策略
如果您查看的手册页 podman-run
,你会注意到 --restart
选项不会在系统重新启动时再次启动容器。
它说:“请注意, --restart
将要 不是 系统重启后重启容器。”
这与您可能习惯使用的 Docker 不同。 行为背后的原因是 Podman 的无守护进程架构。
Docker 管理的容器在每次重新启动时都会遵守这一点,因为 Docker 守护程序在启动时启动并启动指定的容器。
但是,没有守护进程意味着 Podman 不会在启动时启动,因此容器也不会在启动时启动。
解决方案:systemd
爱它或恨它,您选择的发行版可能使用 systemd 作为初始化系统。 最好用好! 🙂
第 1 步:启动并运行容器
您可能希望以多种方式启动容器。 也许您想要一个简单的容器并且正在使用 podman run
命令。 如果您有复杂的配置,您可能会使用 docker 文件。
出于演示目的,我将创建一个基于 mariadb
容器图像并命名我的容器 chitragupta-db
.
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
422eed872347 docker.io/library/mariadb:latest --transaction-iso... 58 seconds ago Up 58 seconds ago chitragupta-db
现在容器正在运行,我将继续下一步。
第 2 步:创建 systemd 服务
正如我之前提到的,Podman 是一个无守护进程的容器管理软件。 因此,podman 管理的容器的启动需要外部管理。
我将使用 systemd 演示如何做到这一点。
systemd 是一个 init 系统,用于管理基于 Linux 的操作系统上的服务/守护进程。 因此,它是解决我们问题的完美候选者。
步骤 2A:创建一个 systemd 单元文件
不需要手动创建容器的 systemd 单元文件。 有一个方便的命令。 该命令是 podman generate systemd
语法如下:
podman generate systemd --name CONTAINER_NAME
要为您的容器生成 systemd 单元文件,请使用 podman generate systemd
命令以及容器的名称。
就我而言,我命名了我的容器 chitragupta-db
,所以我会使用它。
如您所见,这个特定的 podman 命令为我们完成了所有工作。 但这并不是特别有用……还没有。
的输出 podman generate systemd
是您的服务单位文件中应该包含的内容。 但是为什么要复制粘贴呢? podman 命令还带有一个方便的选项,即 --files
(或者 -f
简称)选项。
使用 --files
选项将使用必要的内容填充文件,而不是将其打印到您的控制台/终端。 使用此选项将创建一个名为 container-CONTAINER_NAME.service
在您当前的工作目录中。
$ podman generate systemd --name chitragupta-db -f
/home/pratham/container-chitragupta-db.service
$ ls *.service
container-chitragupta-db.service
就我而言,我的容器的名称是 chitragupta-db
,它创建了一个名为 container-chitragupta-db.service
在我当前的工作目录中。
由于 podman generate systemd
命令正在创建一个 systemd 单元文件,您也可以使用 --after=
, --requires=
, --wants=
为您的容器指定相应依赖项的选项。
步骤 2B:使用正确的位置
您可能已经注意到,指定的 podman 命令将在您当前的工作目录中创建一个新的 systemd 单元文件。 但是,由于容器(至少在我的用例中)是无根的,它需要以普通用户身份运行,而不是 root
.
为此,需要将生成的 systemd 单元文件放在 ~/.config/systemd/user/
目录。 更改目录并在指定目录中生成 systemd 文件。
$ podman generate systemd --name chitragupta-db -f
/home/pratham/.config/systemd/user/container-chitragupta-db.service
systemd 单元文件是在没有任何用户输入的情况下生成的,它被放置在正确的目录中。
现在剩下的就是启用它。
第 3 步:启用 systemd 服务
现在 podman 已经在正确的位置自动生成了一个 systemd 单元文件(~/.config/systemd/user/
),是时候启用此服务了。
为特定用户启用 systemd 服务是使用 --user
选项。
使用以下命令语法来执行此操作:
systemctl --user enable SERVICE_NAME.service
您的输出应类似于下图所示:
$ systemctl --user enable container-chitragupta-db.service
Created symlink /home/pratham/.config/systemd/user/default.target.wants/container-chitragupta-db.service → /home/pratham/.config/systemd/user/container-chitragupta-db.service.
启用后,您可以检查此 systemd 服务的状态,请务必使用 --user
选项,因为此服务正在以当前用户身份运行,而不是由 root
.
$ systemctl --user status container-chitragupta-db.service
○ container-chitragupta-db.service - Podman container-chitragupta-db.service
Loaded: loaded (/home/pratham/.config/systemd/user/container-chitragupta-db.service; enabled; vendor preset: disabled)
Active: inactive (dead)
Docs: man:podman-generate-systemd(1)
不用担心服务状态是 inactive (dead)
. 容器 chitragupta-db
仍在运行,您尚未重新启动;)
第 4 步:启用用户逗留
如您所知,此服务由普通用户运行(pratham
是我的用户)而不是root用户。 这意味着所述用户需要在启动时登录并且即使他们从 GUI 或 TTY 会话中注销也应该保持活动状态。
这可以通过使用 loginctl
命令。 从用户的终端会话中,运行以下命令:
sudo loginctl enable-linger
此命令将确保您的用户的用户会话在启动时生成,并且即使在从 GUI 或 tty 会话注销后也保持活动状态。
最后,启用了 Podman 管理的容器在启动时的重新启动。 重新启动将自动重新启动您已为其创建 systemd 单元文件并启用它们的容器。
这是一个相当长的过程,但幸运的是不需要人工干预。
结论
本教程将指导您创建 systemd 单元文件以在启动时管理由 Podman 管理的容器的自动启动。 systemd 的使用有助于管理员使用许多人熟悉的 systemd 界面来关注容器。
请发表评论,让我们知道您对此的想法。 如果您有其他方法可以做到这一点,请在下面评论。