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 对“实例名转义”的机制。
现在用的是 错误的占位符,导致带 - 的实例名行为不符合预期。
下面先给结论版修复,再解释为什么这样改是正确的。
- 把
%I改为%i - 顺带补齐 Podman 官方推荐的 systemd 选项
[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
| 占位符 | 含义 | 是否转义 |
|---|---|---|
%i |
原始实例名 | ❌ 不转义 |
%I |
转义后的实例名 | ✅ 会转义 |
-->\x2d/->-- 其它特殊字符 -> 十六进制
也就是说:
podman@gitlab-ce
在 %I 中会变成类似:
gitlab\x2dce
而 Podman 并不存在这个容器名 👉 启动失败
systemd 模板 unit:
只要实例名本身就是“真实资源名”(容器名、服务名),就必须用%i,不要用%I
原因是:
%I适合文件路径 / mount / device 名%i适合业务标识符(container / service / app)
Podman 容器名属于 业务标识符,不是路径。
否则 systemd 会:
- 直接 kill 掉 podman 进程
- 导致容器被异常终止
Podman 官方强烈建议开启。
让:
- Podman
- systemd
- cgroups
不互相抢控制权
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 专用 systemd 模板 unit」,并把关键点一次讲清楚。
⚠️ Rootless Podman ≠ system service
必须放在 用户级 systemd 目录:
~/.config/systemd/user/podman@.service
不要放
/usr/lib/systemd/system/
否则你会遇到:cgroup、权限、delegate、socket 全部异常
[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
systemctl --user daemon-reload
systemctl --user start podman@gitlab-ce
systemctl --user enable podman@gitlab-ce
systemctl --user status podman@gitlab-ce
loginctl enable-linger <用户名>
例如:
loginctl enable-linger gitlab
rootless Podman 依赖 user systemd,
没有 linger,用户退出登录后 unit 会被杀掉。
确认以下内核 / 系统配置正常(AlmaLinux / RHEL 常见):
cat /etc/subuid
cat /etc/subgid
应包含:
gitlab:100000:65536
若没有:
usermod --add-subuids 100000-165535 gitlab
usermod --add-subgids 100000-165535 gitlab
stat -fc %T /sys/fs/cgroup
输出应为:
cgroup2fs
AlmaLinux 9 / 10 默认已开启 ✔
| 项目 | Rootless | Root |
|---|---|---|
| 安全性 | ✅ 极高 | ❌ |
| systemd 类型 | user unit | system unit |
| 端口 <1024 | ❌(需 rootlesskit) | ✅ |
| 推荐场景 | 服务 / CI / GitLab | 基础设施 |
-> 带 - 的容器名直接翻车
-> rootless 直接异常
-> cgroup 管理混乱
-> 重启后容器不在