在 VyOS 上用 podman run 拉起来的容器,重启后就没了。要让容器像系统服务一样开机自启、崩溃自动拉起,正规做法是用 Podman 的 Quadlet 机制:写一个 .container 描述文件,systemd 的 generator 会在启动时把它变成真正的 service。
手动写 Quadlet 文件容易抄错参数,podlet 可以从一条现成的 podman run 命令直接生成这个文件。本文就是完整流程:装 podlet → 建容器网络 → 跑容器 → 生成 Quadlet → 交给 systemd 持久化。
💡 提示: 本文基于大卫佬在 7829.eu.org 的原始笔记整理,并修正了其中的几处笔误(详见文末「与原文的差异」)。所有示例命令里的镜像、IP、IPv6 前缀均为示例值,请按你的实际环境替换。
1. 安装 podlet
podlet 的发布页在 https://github.com/containers/podlet/releases,注意两点:
- 下载下来的是
.tar.xz压缩包(不是单个二进制),要先解压; - 按你的 CPU 架构选文件,x86_64 机器选
podlet-x86_64-unknown-linux-gnu.tar.xz。
# 下载并解压(以 v0.3.2、x86_64 为例,版本号以发布页最新为准)
cd /tmp
curl -LO https://github.com/containers/podlet/releases/download/v0.3.2/podlet-x86_64-unknown-linux-gnu.tar.xz
tar xf podlet-x86_64-unknown-linux-gnu.tar.xz
# 安装到系统路径并加执行权限
sudo mv podlet-x86_64-unknown-linux-gnu/podlet /usr/local/bin/
sudo chmod +x /usr/local/bin/podlet
podlet --version # 输出 podlet 0.3.2 即安装成功2. 创建容器专用网络
给容器单独划一个桥接网络,网段不要和宿主机的管理网段重叠:
set container network ct-network prefix '172.23.0.0/24'
set container network ct-network prefix 'fd99::/64'
commitIPv6 前缀按需添加;只用 IPv4 的话第二条可以不加。
3. 启动容器
以下用 smbox 容器做示例,两种方式任选其一。
方式一:在线拉取镜像
sudo podman run -d \
--privileged \
--network=ct-network \
--ip=172.23.0.99 \
-v /config/containers/smbox:/root/config \
--name smbox \
--restart=always \
docker.io/zj3721cn/smbox:latest方式二:离线导入本地镜像包
离线环境下先把容器包(.tar)上传到 VyOS,然后导入:
# 导入镜像包(进入包所在目录执行)
podman load -i /home/gary/smbox-container-amd64.tar
# 确认导入成功
podman images
# 运行容器,--pull=never 表示永远不尝试在线拉取
sudo podman run -d \
--privileged \
--network=ct-network \
--ip=172.23.0.99 \
-v /config/containers/smbox:/root/config \
--name smbox \
--restart=always \
--pull=never \
docker.io/library/smbox:amd64-1.0.7需要 IPv6 的话,在 run 命令里加一行 --ip6=fd99::9999 即可(放在 --ip 后面)。
确认容器已运行:
sudo podman ps -a4. 用 podlet 生成 Quadlet 文件
先创建 Quadlet 目录(注意:是 /etc/containers/systemd/,不是 /usr/share/containers/systemd/——后者是发行版自带文件的位置,手动部署一律用前者):
sudo mkdir -p /etc/containers/systemd/两种写法功能相同,任选其一。
写法一:输出到文件(自己指定文件名):
podlet --install --wanted-by default.target \
generate container smbox \
> /etc/containers/systemd/smbox.container写法二:自动生成文件(--unit-directory 让 podlet 直接写入 Quadlet 目录,文件名取自容器名):
podlet --install --unit-directory --wanted-by default.target \
generate container smbox⚠️ 注意:
generate container是从正在运行的容器反推配置,所以第 3 步的容器必须先跑起来。如果想跳过「先跑容器」这一步,也可以直接把podman run命令改成podlet podman run ...(实测命令里的-d要写成--detach=true),podlet 会直接从命令生成文件,不需要容器真的存在。
各参数的作用:
| 参数 | 作用 |
|---|---|
generate container smbox | 从现有容器 smbox 生成 Quadlet .container 文件 |
--install | 在文件里加 [Install] 段,让服务可以被 enable/随目标启动 |
--wanted-by default.target | 服务挂在 default.target 下,随系统启动而启动 |
--unit-directory | 直接把文件写入 Quadlet 目录(默认 /etc/containers/systemd/) |
生成后可以在 /etc/containers/systemd/smbox.container 里核对内容,形如:
[Container]
ContainerName=smbox
Image=docker.io/library/smbox:amd64-1.0.7
IP=172.23.0.99
Network=ct-network
Volume=/config/containers/smbox:/root/config
[Service]
Restart=always
[Install]
WantedBy=default.target5. 交给 systemd,完成持久化
sudo ln -s /usr/bin/podman /usr/local/bin/podman
systemctl daemon-reload && systemctl start smbox第一条软链接是为了避免部分环境下 systemd 找不到 podman 可执行文件而报错;如果启动正常可以不做。
查看服务状态:
systemctl status smbox到这里就完成了:设备重启后 systemd 会自动把容器拉起来,日常也用 systemctl start/stop/restart smbox 管理。
6. 常用管理命令
systemctl cat smbox # 查看生成的完整 unit 内容
systemctl status smbox # 查看运行状态
podman ps -a # 查看容器状态关于 systemctl stop: stop 会把容器停掉(相当于删除这个容器实例),但因为 .container 文件还在,下次开机或 systemctl start smbox 时容器又会重新建出来。
彻底删除(连 Quadlet 一起清掉):
systemctl stop smbox
systemctl disable smbox
rm -f /etc/containers/systemd/smbox.container
systemctl daemon-reload7. 原理:Quadlet 是怎么工作的
Quadlet 是 Podman 官方的 systemd 集成方案:systemd 启动时运行一个 generator,读取 /etc/containers/systemd/(及 /run/containers/systemd/、/usr/share/containers/systemd/)下的 .container、.network、.volume 等文件,为每个文件生成一个同名的 .service,之后就能像普通服务一样被 systemd 管理。这也解释了为什么改完文件要 systemctl daemon-reload——generator 只在开机和 reload 时重新读取。
与原文的差异
整理时对原始笔记做了以下修正:
- 下载说明:原只写「下载 podlet 放到 /usr/local/bin」,实际发布产物是
.tar.xz压缩包,需先解压,且要按架构选文件; - Quadlet 目录:原文先写了
/usr/share/containers/systemd/再自我纠正,本文统一为/etc/containers/systemd/; -d参数:走podlet podman run直接生成时,-d会报equal sign is needed,需写成--detach=true;- 删除流程:原文写
rm -f /run/systemd/generator/smbox.service——该文件是 generator 每次 reload 自动生成的,删了也会被重新生成,正确做法是删/etc/containers/systemd/下的源文件后daemon-reload; - 命令笔误:原文
prefix 'fd99::/64缺右引号,已补齐。
总结
VyOS 上容器持久化的关键就是:容器跑通 → podlet 生成 .container 文件放进 /etc/containers/systemd/ → daemon-reload 交给 systemd。之后重启自启、崩溃拉起都不用再操心,日常管理也统一到 systemctl。
