在启动单元/服务之前,如何等待etcdvariables

我目前正在使用CoreOS集群中的ELK(Elasticsearch,Logstash,Kibana)堆栈进行日志logging。 我发现,您可以使用gelf自动将日志从docker发送到logstash。 我正在使用一个sidekick编写一个logstash容器IP地址的etcdvariables。 由于我必须将logstash的IP传递给docker run命令中的标志,所以我需要等到variables设置完成。

我的问题是如何等待etcdctl get /network/logstash返回IP地址。

这就是我的单元文件现在的样子:

 [Unit] Description=nginx with elk logging After=logstash-discovery.service Requires=docker.service [Service] TimeoutStartSec=0 ExecStartPre=/usr/bin/bash -c "/usr/bin/systemctl set-environment ADDR=$(etcdctl get /network/logstash)" ExecStartPre=-/usr/bin/docker kill nginx1 ExecStartPre=-/usr/bin/docker rm nginx1 ExecStartPre=/usr/bin/docker pull 10.0.2.2:5000/nginx ExecStart=/usr/bin/docker run -p 80:80 --name=nginx1 --net=host --log-driver=gelf --log-opt gelf-address=udp://${ADDR}:12201 --log-opt gelf-tag="fe" 10.0.2.2:5000/nginx ExecStop=/usr/bin/docker stop nginx1 [X-Fleet] Conflicts=logstash.service 

解决的办法是使用etcdctl watch而不是etcdctl get但是如果variables还没有设置,请检查。 所以完整的行看起来像这样:

 ExecStartPre=/usr/bin/bash -c \ "if [ -z $(etcdctl get /network/logstash) ]; \ then /usr/bin/systemctl set-environment ADDR=$(etcdctl watch /network/logstash); \ else /usr/bin/systemctl set-environment ADDR=$(etcdctl get /network/logstash); \ fi" 

你的问题归结为一个关于bash编程的问题:在继续之前,你如何等待variables被设置?

这个问题的一个变种已经回答了如何在bash中创build一个等待web服务器响应的循环? 。

这通常需要多于一行的代码,所以您可能需要将逻辑放在一个文件中并指向ExecStartPre ,而不是使用单行内容。