VyOS 容器持久化:用 podlet + Quadlet 让 podman 容器开机自启

在 VyOS 上用 podman 跑容器,重启就丢?本文用 podlet 生成 Quadlet 文件,把容器变成 systemd 服务,实现开机自启的终极持久化。

在 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'
commit

IPv6 前缀按需添加;只用 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 -a

4. 用 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.target

5. 交给 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-reload

7. 原理: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

参考:Podman Quadlet 官方文档podlet 项目