Linux Podman + Systemd 定时启停青龙面板配置指南

1核1GB 内存 的轻量级服务器上,为了最大化节省系统资源,可以将青龙面板配置为仅在有定时任务需要执行时启动(如 00:05 - 00:20),运行完毕后自动关闭

本文档采用 单 Timer + RuntimeMaxSec 自动限时 方案,配置最少、不泄露内存,且对服务器资源消耗最低。


方案优势分析

  1. 资源极省:避免青龙面板及 Node.js / PM2 进程 24 小时常驻内存(可省下 200MB - 400MB 内存)。
  2. 绝对安全:依靠 Systemd 底层的 RuntimeMaxSec 硬性倒计时,即使青龙内部脚本死锁或卡死,到点也会强行优雅关闭,防止 OOM(内存溢出)。
  3. 彻底无日志:禁用容器控制台及 Podman 日志输出,减少 CPU 开销与磁盘 I/O 读写。

完整配置步骤

1. 创建 Service 服务文件

创建配置文件 /etc/systemd/system/qinglong-task.service

[Unit]
Description=Run qinglong container for 15 minutes

[Service]
Type=exec

# 1. 启动容器并挂起前台(-a 必须保留,以便 Systemd 进行倒计时监控)
# --log-driver=none 禁用 Podman 记录容器日志,不支持,已经--log-driver=none删除
ExecStart=/usr/bin/podman start -a qinglong

# 2. 自动停止命令:超时或被终止时优雅关闭容器
ExecStop=/usr/bin/podman stop -t 10 qinglong

# 3. 运行时间上限:强制限制服务最多运行 15 分钟(00:05 - 00:20)
RuntimeMaxSec=15m

# 4. 屏蔽 Systemd 收集容器的标准输出与错误日志,节省磁盘空间
StandardOutput=null
StandardError=null

[Install]
WantedBy=multi-user.target

2. 创建 Timer 定时器文件

创建配置文件 /etc/systemd/system/qinglong-task.timer

[Unit]
Description=Timer to start qinglong at 00:05 daily

[Timer]
# 每天 00:05:00 触发
OnCalendar=*-*-* 00:05:00

# 若开机时已错过触发时间(如当时处于关机状态),开机后立即补跑一次
Persistent=true

[Install]
WantedBy=timers.target

3. 加载配置与启用服务

在终端按顺序执行以下命令:

# 重新加载 Systemd 配置
systemctl daemon-reload

# 设置定时器开机自启并立即激活
systemctl enable --now qinglong-task.timer

验证与测试命令

1. 检查 Timer 调度状态

检查下一次触发时间是否为预期的每天 00:05:00

systemctl list-timers | grep qinglong

2. 手动测试运行

无需等到午夜,可手动触发一次 Service 验证启停逻辑:

# 启动任务
systemctl start qinglong-task.service

# 查看 Podman 容器状态(此时应能看到 qinglong 正常运行)
podman ps

# 手动结束测试(或等待 15 分钟测试自动关闭)
systemctl stop qinglong-task.service

补充优化:青龙面板内部日志清理

除系统层面关闭日志外,建议在青龙面板 Web 界面中调整内部日志保留策略:

  1. 登录青龙面板 Web 界面,点击 配置文件 (config.sh)。
  2. 将日志保留天数修改为 1 天

    AutoCleanMaxHistory="1"
    
  3. 确保青龙内置的 ql clean(清理日志)定时任务处于开启状态。

常见疑问说明

为什么 ExecStart 必须包含 -a 参数?

在设置了 RuntimeMaxSec 的机制下:

  • -a (--attach) 参数会让 Podman 进程挂起等待容器。
  • 只有当进程保持运行状态时,Systemd 才会开启 15 分钟的倒计时。
  • 15 分钟一到,Systemd 就会主动调用 ExecStop 优雅关闭容器。
  • 挂起的 Podman 进程在内核中处于 休眠状态(Sleep),CPU 占用率为 0%,不会对 1核1G 服务器造成额外负担。

是的,默认情况下必须保持同名(qinglong-task)。

Systemd 内部有一套标准的隐式推断规则,它的工作机制如下:


1. 默认同名关联规则(默认行为)

当你执行 systemctl enable --now qinglong-task.timer 时,Systemd 会在同一个目录下寻找主文件名完全一致.service 文件。

  • Timer 文件qinglong-task.timer
  • 默认寻找qinglong-task.service

因为主名称都是 qinglong-task,Systemd 会自动将它们绑定在一起,无需在文件里做任何特殊声明。


2. 如果文件名不一致,如何手动指定?

如果你希望 Timer 和 Service 使用不同的文件名(例如 Timer 叫 cron-0005.timer,Service 叫 qinglong-runner.service),你需要显式地在 Timer 文件中通过 Unit= 参数进行指定:

修改示例 /etc/systemd/system/cron-0005.timer

[Unit]
Description=Timer to start qinglong at 00:05 daily

[Timer]
OnCalendar=*-*-* 00:05:00
# 显式指定要触发的服务名称
Unit=qinglong-runner.service
Persistent=true

[Install]
WantedBy=timers.target

总结建议

  • 同名(推荐):如果不写 Unit= 参数,Timer 会自动去寻找**同名的 .service** 文件。这种方式最简洁,不容易出错。
  • 不同名:必须在 .timer 文件的 [Timer] 块中明确添加 Unit=你的服务名.service

systemctl status ql.service -l 不是实时持续刷新的日志,它是一个静态的状态快照

下面为你拆解它的含义和内部参数作用:


1. 命令参数拆解

  • systemctl status ql.service
    查看 ql.service 这个服务的当前运行状态(如:是否在运行、PID 进程号、内存占用 CPU 消耗等),并在最下方附带显示最近的 10 行日志
  • -l (或 --full)
    代表 Full(完整显示)。默认情况下,如果日志或进程命令行太长,Systemd 会在右侧用 > 截断。加上 -l 可以强行展开单行内容,防止关键报错信息被截断。

2. 如何区分“静态快照”与“动态实时”?

命令作用特点
systemctl status ql.service -l查看当前状态 + 最近几行日志运行后立即结束(除非页面太长进入分页),内容不会更新
journalctl -u ql.service -f实时追踪最新日志类似 tail -f,终端会卡住,只要服务有新日志产生,就会实时在屏幕上滚屏打印

3. 常用日志排查命令速查

如果你后续想查看日志,推荐以下几个命令:

  • 实时滚动查看当前服务的日志

    journalctl -u ql.service -f
    
  • 查看该服务最近 50 行日志

    journalctl -u ql.service -n 50 --no-pager
    
  • 查看今天产生的该服务日志

    journalctl -u ql.service --since today
    
注意:由于我们在 ql.service 中配置了 StandardOutput=nullStandardError=null,青龙容器内部刷屏的控制台日志已被屏蔽,因此使用上述日志命令只会看到 Systemd 启动、停止、超时终止 等系统级事件,不会看到青龙跑脚本的具体日志(这也是为了保护你的 1G 内存和磁盘空间)。

标签: none

添加新评论