我用了这答案作为指南,帮助我编写一个启动脚本,用于 systemd 在我的机器启动时启动我的 Jenkins 容器。但是,该脚本不起作用。以下是脚本:
[Unit]
Description=Docker container that houses the Jenkins build service.
After=network-online.target
[Service]
Group=docker
ExecStart=/usr/bin/docker start jenkins
ExecStop=/usr/bin/docker stop jenkins
[Install]
WantedBy=multi-user.target
我把它放在了/etc/systemd/system/jenkins.service
。
当我运行 时sudo systemctl start jenkins
,什么都没有发生。没有错误或任何打印输出,并且容器没有启动(如果我运行docker ps
,则没有列出正在运行的容器)。
我可以/usr/bin/docker start jenkins
从命令行手动运行,并且启动非常顺利,所以问题似乎出在我编写脚本的方式上,但我不明白为什么它没有按预期工作。任何帮助都非常感谢。
更新:
ExecStart
我已通过将和ExecStop
值分别更改为/bin/sh -c '/usr/bin/docker start jenkins'
和来更新脚本/bin/sh -c '/usr/bin/docker stop jenkins'
,但仍然不起作用。
更新 2:
我通过删除并将命令括在双引号中来更新ExecStart
和,但现在我得到了一个有趣的输出:ExecStop
/bin/sh -c "..."
sudo systemctl status jenkins
$ sudo systemctl status jenkins
● jenkins.service - Docker container that houses the Jenkins build service.
Loaded: loaded (/etc/systemd/system/jenkins.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sun 2017-12-03 12:20:39 EST; 10s ago
Process: 1513 ExecStop=/usr/bin/docker stop jenkins (code=exited, status=203/EXEC)
Process: 1511 ExecStart=/usr/bin/docker start jenkins (code=exited, status=203/EXEC)
Main PID: 1511 (code=exited, status=203/EXEC)
Dec 03 12:20:39 evt-jenkins systemd[1]: Started Docker container that houses the Jenkins build service..
Dec 03 12:20:39 evt-jenkins systemd[1]: jenkins.service: Main process exited, code=exited, status=203/EXEC
Dec 03 12:20:39 evt-jenkins systemd[1]: jenkins.service: Control process exited, code=exited status=203
Dec 03 12:20:39 evt-jenkins systemd[1]: jenkins.service: Unit entered failed state.
Dec 03 12:20:39 evt-jenkins systemd[1]: jenkins.service: Failed with result 'exit-code'.
有什么办法可以让我看见确切地什么地方出了问题?这些错误代码实际上不代表任何信息。
更新 3:
好的,所以我又从头开始,删除了引号。文件jenkins.service
现在读起来和问题顶部完全一样。当我重新加载 systemd 并启动服务时,这是输出sudo systemctl status jenkins
:
$ sudo systemctl status jenkins
● jenkins.service - Docker container that houses the Jenkins build service.
Loaded: loaded (/etc/systemd/system/jenkins.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Sun 2017-12-03 12:31:59 EST; 2s ago
Process: 1683 ExecStop=/usr/bin/docker stop jenkins (code=exited, status=0/SUCCESS)
Process: 1594 ExecStart=/usr/bin/docker start jenkins (code=exited, status=0/SUCCESS)
Main PID: 1594 (code=exited, status=0/SUCCESS)
Dec 03 12:31:59 evt-jenkins systemd[1]: Started Docker container that houses the Jenkins build service..
Dec 03 12:31:59 evt-jenkins docker[1594]: jenkins
Dec 03 12:31:59 evt-jenkins docker[1683]: jenkins
因此,systemd 不仅报告脚本成功运行,而且还通过容器名称(而不是其 SHA)显示启动容器的正确输出。但是当我运行 时docker ps
,没有列出任何内容!我想提醒您,当我手动运行 docker 命令时,容器运行正常。
有什么想法吗?Systemd 被证明很难使用。
更新 4:
好的,我刚刚注意到这里发生了一些非常奇怪的事情。如果你注意到上面的代码片段(的输出sudo systemctl status jenkins
),你会注意到的 PID 是ExecStart
1594,的 PIDExecStop
是 1683。现在在输出中进一步向下,你会看到的输出排在ExecStart
第一位,前。ExecStop
我不确定这是否是因为输出缓冲,或者 systemd 是否ExecStart
在 之前运行ExecStop
。
答案1
您尝试使用 systemd 启动脚本而不是使用类似的 docker 机制来执行此操作,有什么原因吗restart: always
?
我们正在使用 docker-compose.yml,它看起来像这样:
docker-compose.yml
版本:'2' 服务: 詹金斯: 图片:###OWN_JENKINS_IMAGE### 重启:总是 内存限制:2100米 网络: - 网络 -dockerhub 环境: -“反向代理端口=8080” - “REVERSE_PROXY_HOSTNAME=####INTERNAL_HOSTNAME####” “X_PROXY_PORT=443” -“X_PROXY_SCHEME=https” -“X_PROXY_NAME=####INTERNAL_HOSTNAME####” 卷: - ./数据/詹金斯:/var/jenkins_home - ./数据/ssh/:/var/ssh/ - /var/run/docker.sock:/var/run/docker.sock - /usr/bin/docker:/usr/bin/docker - ./data/volumes/lib64/libdevmapper.so.1.02:/usr/lib/libdevmapper.so.1.02 - ./data/volumes/lib64/libdw.so.1:/usr/lib/libdw.so.1 - ./data/volumes/lib64/libgcrypt.so.11:/usr/lib/libgcrypt.so.11 - ./data/volumes/lib64/libsystemd-id128.so.0:/usr/lib/libsystemd-id128.so.0 - ./data/volumes/lib64/libsystemd-journal.so.0:/usr/lib/libsystemd-journal.so.0 网络: 网站: 外部的: 名称:网络 DockerHub: 外部的: 名称:####INTERNAL_HOSTNAME####
启动图像后,docker-compose up -d
当出现问题时它将重新启动,并且下面的整个服务器也会重新启动。
答案2
我同意使用Docker启动容器,并使用restart:always选项。
至于脚本和日志:
您是否要覆盖 docker 守护程序的任何默认值?您可能需要考虑使用仅包含非默认值的覆盖文件,而不是编辑 systemd 配置文件本身。
来自 systemctl 的输出:您是否尝试过设置 StandardOutput=tty 来查看正在发生的情况?
其他日志:您是否在系统上的其他日志(例如 /var/log/syslog 或 /var/log/messages)中看到任何错误?对于 systemd,stderr 的默认输出是 syslog。
我之所以问这个问题,是因为根据我的 Unix/Linux 经验,当系统操作不合时,您需要查看日志。
有关使用 Docker 和 systemd 的更多信息,你可以查看维基百科。