在现代 Linux 环境中,Podman 是一种无守护进程、支持 rootless 模式的容器引擎,允许用户在没有 root 权限的情况下运行和管理容器。本文将介绍如何利用 Podman 生成 Systemd 服务文件,以便自动化管理容器,同时支持用户级别的服务配置。

使用 Podman 生成 systemd 服务文件

Podman 提供了一个方便的命令 podman generate systemd,用于自动生成 systemd 服务文件。这使得容器的管理更加系统化,并提供了开机启动和故障自动重启等功能。以下是生成 systemd 服务文件的步骤:

步骤 1: 创建和运行容器

首先,以普通用户身份运行容器。假设我们要运行一个 nginx 容器,并将主机目录挂载到容器中:

1
podman run -d --name nginx -p 8080:80 -v /home/user/share:/usr/share/nginx/html:ro docker.io/library/nginx

步骤 2: 生成 systemd 服务文件

使用 Podman 的 generate systemd 命令生成服务文件:

1
podman generate systemd --name nginx --files --new

生成的 .service 文件将保存在当前目录中。你可以查看文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
% cat container-nginx.service
# container-nginx.service
# autogenerated by Podman 4.3.1
# Wed Aug 7 14:44:39 CST 2024

[Unit]
Description=Podman container-nginx.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm \
-f %t/%n.ctr-id
ExecStart=/usr/bin/podman run \
--cidfile=%t/%n.ctr-id \
--cgroups=no-conmon \
--rm \
--sdnotify=conmon \
--replace \
--name nginx \
-p 8080:80 \
-v /home/user/share:/usr/share/nginx/html:ro \
-d docker.io/library/nginx
ExecStop=/usr/bin/podman stop \
--ignore -t 10 \
--cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm \
-f \
--ignore -t 10 \
--cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all

[Install]
WantedBy=default.target

步骤 3: 配置用户服务

将生成的服务文件移动到用户的 systemd 用户服务目录,以便系统能够管理该服务:

1
2
mkdir -p ~/.config/systemd/user
mv container-nginx.service ~/.config/systemd/user/

步骤 4: 启用和启动用户服务

使用 systemd 的用户服务管理工具来启用和启动该服务:

  1. 重载用户 systemd 配置
1
systemctl --user daemon-reload
  1. 启用并启动服务
1
systemctl --user --now start container-nginx.service
  1. 检查服务状态
1
systemctl --user status container-nginx.service

启用 Linger 模式

为确保用户在注销后用户级别的服务仍能运行,可以使用 loginctl 命令启用 linger 模式。启用后,即使用户会话结束,服务仍然保持活动状态。

启用 linger 模式

1
sudo loginctl enable-linger your_username

将 your_username 替换为目标用户的实际用户名。这样可以确保服务在用户注销后继续运行。

查看 Linger 状态

1
loginctl show-user your_username --property=Linger

此命令将返回该用户的 linger 状态(yes 表示启用,no 表示未启用)。