如何让 schedule:run 在 docker 容器中使用 systemd?

How do I get schedule:run to work with systemd in a docker container?

下面this guide我设置了两个文件

/etc/systemd/system/lumen-cron.服务

[Unit]
Description=Run lumen cron tasks
After=network.target

[Service]
User=root
ExecStart=/usr/bin/php /var/www/web/artisan schedule:run

/etc/systemd/system/lumen-cron.timer

[Unit]
Description=Run lumen timed tasks

[Timer]
OnBootSec=1min
OnUnitActiveSec=1m

[Install]
WantedBy=timers.target

我得到了我的 docker 图像 FROM ubuntu:xenial 并且我的启动脚本有 systemctl enable lumen-cron

如果我登录到容器,但是调度程序不是 运行。

$ journalctl -f -u lumen-cron.timer
No journal files were found.

$ journalctl -f -u lumen-cron.service
No journal files were found.

$ systemctl list-timers
Failed to connect to bus: No such file or directory

我碰壁了,我觉得我很接近了。有没有其他人在 docker 容器中通过 systemd 成功 运行 laravel/lumen 调度程序?

看起来您可能正在尝试在 Docker 容器内设置 systemd 单元。虽然可以在容器内使用 systemd,但这不是一个很常见的设置。

如果您查看上面 systemctl list-timers 的输出,您会注意到它出错了 Failed to connect to bus: No such file or directory。您可能会收到此错误,因为您试图在 systemd 不是 运行ning.

的容器内使用 systemctl

那么,为什么 systemd 不在容器中 运行ning?默认情况下,容器以多种方式与主机隔离。它们有自己的内核命名空间,包括自己的 PID 1。因此,默认情况下,您的容器将无法使用主机的 systemd 套接字。

为了在容器中使用 systemd,您需要将 运行 systemd 作为容器的 PID 1。这意味着您有两个 systemd,一个在主机上,一个在容器里。 RedHat 有一些内容 blog posts 介绍了如何使用 Fedora 映像实现这一点,但是,正如您会注意到的那样,它需要一些特别的注意,并且它可能会超出您的需要。

相反,这里有一些可能有用的选项:

使用主机的 systemd:

这可能是最简单的解决方案。您可以将这些单元文件放在主机中,并更改 ExecStart= 行,以便它使用相同的命令启动一个新容器:

[Unit]
Description=Run lumen cron tasks
After=network.target

[Service]
Type=oneshot
ExecStart=/bin/docker run --rm -name lumen-cron yourdockerimage /usr/bin/php /var/www/web/artisan schedule:run

使用容器编排平台:

如果您有 time/resources 来管理集群,那么使用 Kubernetes 之类的平台将是理想的选择,特别是如果您想稍后将其扩展到一台以上的服务器。

最新版本的 Kubernetes 添加了对 CronJob 对象的支持,允许您定期指定 运行 的容器:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: lumen-cron
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: lumen-cron
            image: yourimage
            args:
            - /usr/bin/php
            - /var/www/web/artisan
            - schedule:run
          restartPolicy: OnFailure

使用supervisord

如果您只想 运行 将所有内容都放在一个容器中,您可以在容器中使用 supervisord 作为 PID 1,并让 运行 您的 PHP/webserver ] 和 crond.