如何让 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
.
下面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
.