如何自动启动 Podman 容器?

波德曼 是迄今为止我最喜欢的容器管理工具之一。 它具有无守护进程架构,允许非特权用户在没有 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 界面来关注容器。

请发表评论,让我们知道您对此的想法。 如果您有其他方法可以做到这一点,请在下面评论。