Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Podman systemd 脚本优化

优化以下 systemd 配置,使其支持 systemctl enable podman@gitlab-ce,即 podman@ 后面的参数支持 - 符号

[Unit]
Description=%I container
After=network-online.target
Wants=network-online.target

[Service]
User=root
Restart=always
ExecStart=/usr/bin/podman start -a %I
ExecStop=/usr/bin/podman stop -t 10 %I
LimitCORE=infinity
LimitMEMLOCK=infinity
LimitNOFILE=infinity
LimitNPROC=infinity
TasksMax=infinity
OOMScoreAdjust=-999

[Install]
WantedBy=multi-user.target

这个问题的关键点不在 Podman,而在 systemd 对“实例名转义”的机制

现在用的是 错误的占位符,导致带 - 的实例名行为不符合预期。

下面先给结论版修复,再解释为什么这样改是正确的


一、直接给「可用且规范」的优化版本(✅ 支持 podman@gitlab-ce

✅ 核心改动点

  • %I 改为 %i
  • 顺带补齐 Podman 官方推荐的 systemd 选项

✅ 修复并优化后的 unit 文件

[Unit]
Description=Podman container %i
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
Restart=always
RestartSec=5

# 使用 %i(未转义实例名,支持 -)
ExecStart=/usr/bin/podman start -a %i
ExecStop=/usr/bin/podman stop -t 10 %i

# 资源与稳定性
LimitCORE=infinity
LimitMEMLOCK=infinity
LimitNOFILE=infinity
LimitNPROC=infinity
TasksMax=infinity
OOMScoreAdjust=-999

# systemd / cgroup / podman 协作必备
KillMode=none
Delegate=yes

TimeoutStartSec=0
TimeoutStopSec=30

[Install]
WantedBy=multi-user.target

现在可以直接启用

systemctl enable podman@gitlab-ce
systemctl start podman@gitlab-ce

二、为什么原配置在「-」这里会出问题?

1️⃣ systemd 的 %I vs %i(这是核心)

占位符 含义 是否转义
%i 原始实例名 ❌ 不转义
%I 转义后的实例名 ✅ 会转义

systemd 的转义规则(重点)

  • - -> \x2d
  • / -> -
  • 其它特殊字符 -> 十六进制

也就是说:

podman@gitlab-ce

%I 中会变成类似:

gitlab\x2dce

而 Podman 并不存在这个容器名 👉 启动失败


2️⃣ 正确原则(一句话记住)

systemd 模板 unit:
只要实例名本身就是“真实资源名”(容器名、服务名),就必须用 %i,不要用 %I


三、为什么很多示例“误导性地使用 %I”?

原因是:

  • %I 适合文件路径 / mount / device 名
  • %i 适合业务标识符(container / service / app)

Podman 容器名属于 业务标识符,不是路径。


四、额外优化说明

1️⃣ KillMode=none(必须)

否则 systemd 会:

  • 直接 kill 掉 podman 进程
  • 导致容器被异常终止

Podman 官方强烈建议开启。


2️⃣ Delegate=yes(必须)

让:

  • Podman
  • systemd
  • cgroups

不互相抢控制权


3️⃣ 为什么不需要 Type=forking

ExecStart=/usr/bin/podman start -a %i
  • -a 会前台附着容器 stdout/stderr
  • 👉 systemd 正确追踪主进程
  • 👉 Type=simple 是正确选择

五、验证方式(建议你做一次)

systemctl start podman@gitlab-ce
systemctl status podman@gitlab-ce

确认:

  • 容器成功启动
  • Ctrl+C 不影响 systemd 管理
  • reboot 后自动拉起

六、最终一句话总结(给你记住)

systemd 模板 unit 中:
%i 用于真实实例名(容器名、服务名),
%I 只用于需要 systemd 转义的路径类对象。


改成 rootless Podman 专用 unit

下面是一份标准、可长期使用的「Rootless Podman 专用 systemd 模板 unit」,并把关键点一次讲清楚。


一、Rootless Podman 的正确 systemd 位置

⚠️ Rootless Podman ≠ system service

必须放在 用户级 systemd 目录:

~/.config/systemd/user/podman@.service

不要放 /usr/lib/systemd/system/

否则你会遇到:cgroup、权限、delegate、socket 全部异常


二、Rootless Podman 模板 unit(✅ 支持 -

📄 ~/.config/systemd/user/podman@.service

[Unit]
Description=Rootless Podman container %i
After=network-online.target
Wants=network-online.target

[Service]
Type=simple

# rootless 必须使用用户 session
Environment=PODMAN_SYSTEMD_UNIT=%n

Restart=always
RestartSec=5

# ⚠️ 关键:必须用 %i(不转义)
ExecStart=/usr/bin/podman start -a %i
ExecStop=/usr/bin/podman stop -t 10 %i

# systemd / podman / cgroup 正确协作
KillMode=none
Delegate=yes

# 避免 systemd 误判启动超时
TimeoutStartSec=0
TimeoutStopSec=30

# 防止被 OOM killer 优先杀
OOMScoreAdjust=-999

[Install]
WantedBy=default.target

三、启用与使用方式(rootless 正确流程)

1️⃣ 重新加载用户 systemd

systemctl --user daemon-reload

2️⃣ 启动 / 启用某个容器

systemctl --user start podman@gitlab-ce
systemctl --user enable podman@gitlab-ce

3️⃣ 查看状态

systemctl --user status podman@gitlab-ce

四、⚠️ 必须做的一步(否则重启不自启)

👉 允许用户 systemd 在无登录状态下运行

loginctl enable-linger <用户名>

例如:

loginctl enable-linger gitlab

原因(一句话)

rootless Podman 依赖 user systemd
没有 linger,用户退出登录后 unit 会被杀掉。


五、Rootless Podman 必须满足的系统条件

确认以下内核 / 系统配置正常(AlmaLinux / RHEL 常见):

1️⃣ 子 UID / GID

cat /etc/subuid
cat /etc/subgid

应包含:

gitlab:100000:65536

若没有:

usermod --add-subuids 100000-165535 gitlab
usermod --add-subgids 100000-165535 gitlab

2️⃣ cgroup v2(非常重要)

stat -fc %T /sys/fs/cgroup

输出应为:

cgroup2fs

AlmaLinux 9 / 10 默认已开启 ✔


六、Rootless vs Root Podman(一句话对比)

项目 Rootless Root
安全性 ✅ 极高
systemd 类型 user unit system unit
端口 <1024 ❌(需 rootlesskit)
推荐场景 服务 / CI / GitLab 基础设施

七、常见坑(你一定会踩)

❌ 用 %I

-> 带 - 的容器名直接翻车

❌ 用 /usr/lib/systemd/system

-> rootless 直接异常

❌ 忘了 Delegate=yes

-> cgroup 管理混乱

❌ 忘了 loginctl enable-linger

-> 重启后容器不在