我有一个cloud-config.yaml
在 CoreOS 上运行四个容器的基本方法(直接运行,无需集群)。其中两个容器(nginx-gen
和nginx-letsencrypt
)从名为的容器中挂载卷nginx
。每个容器启动都定义为一个 systemd 单元。
我已经添加了After=
和Requires=
依赖项,但是第一次登录时我看到的是:
CoreOS stable (1185.5.0)
Failed Units: 2
letsencrypt.service
nginx-gen.service
nginx
(提供音量的一方)正在运行。
如果此后我执行:
sudo systemctl start nginx-gen.service
sudo systemctl start letsencrypt.service
它们启动并运行正确,所以我猜测问题出在系统启动时的依赖关系上。
我对 CoreOS 和 systemd 没有经验,所以原因可能非常简单(比如在 Docker 容器实际运行之前单元就获得了“完成”状态)。
查看journalctl
日志,确实,nginx-gen
服务在有机会挂载卷之前就失败了nginx
:
...
Jan 02 14:35:47 core-01 systemd[1]: nginx-gen.service: Failed with result 'start-limit-hit'.
...
Jan 02 14:36:03 core-01 docker[1401]: Status: Downloaded newer image for nginx:latest
...
我该如何修复该问题?
我的cloud-config.yaml
:
#cloud-config
write_files:
# omitted for ServerFault: ensure template file
# https://raw.githubusercontent.com/jwilder/nginx-proxy/master/nginx.tmpl)
# and directories (/path/to/templates, /path/to/certs) are in-place
coreos:
units:
- name: nginx.service
command: start
content: |
[Unit]
Description=Generic Nginx container
[Service]
Restart=always
ExecStart=/usr/bin/docker run --name nginx -p 80:80 -p 443:443 -v /etc/nginx/conf.d -v /etc/nginx/vhost.d -v /usr/share/nginx/html -v /path/to/certs:/etc/nginx/certs:ro nginx
ExecStop=/usr/bin/docker rm -f nginx
- name: nginx-gen.service
command: start
content: |
[Unit]
Description=Docker-gen service for Nginx
After=nginx.service
Requires=nginx.service
[Service]
Restart=always
ExecStart=/usr/bin/docker run --name nginx-gen --volumes-from nginx -v /path/to/templates:/etc/docker-gen/templates -v /path/to/certs:/etc/nginx/certs:ro -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/docker-gen -notify-sighup nginx -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
ExecStop=/usr/bin/docker rm -f nginx-gen
- name: letsencrypt.service
command: start
content: |
[Unit]
Description=Ngnix reverse proxy Letsencrypt companion
After=nginx.service
Requires=nginx.service
[Service]
Restart=always
ExecStart=/usr/bin/docker run --name nginx-letsencrypt -e "NGINX_DOCKER_GEN_CONTAINER=nginx-gen" --volumes-from nginx -v /path/to/certs:/etc/nginx/certs:rw -v /var/run/docker.sock:/var/run/docker.sock:ro jrcs/letsencrypt-nginx-proxy-companion
ExecStop=/usr/bin/docker rm -f nginx-letsencrypt
答案1
每http://container-solutions.com/running-docker-containers-with-systemd/,您需要强制这些容器在docker服务之后启动。
样本:
[Unit]
Description=Redis Container
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
Restart=always
ExecStartPre=-/usr/bin/docker stop %n
ExecStartPre=-/usr/bin/docker rm %n
ExecStartPre=/usr/bin/docker pull redis
ExecStart=/usr/bin/docker run --rm --name %n redis
[Install]
WantedBy=multi-user.target
因此,在您的情况下,将 Requires=docker.service 添加到 nginx 单元的 Unit 部分就可以了,并且可能还会将 WantedBy 添加到每个单元,以便 SystemD 知道运行它们。