Systemd 服务从 Docker 的动态端口值开始

gus*_*t1n 5 systemd docker

使用 CoreOS、Docker 和 systemd 来管理我的服务,我想正确执行服务发现。由于 CoreOS 使用 etcd(分布式键值),因此有一种非常方便的方法可以做到这一点。在 systemd 的 ExecStartPost 上,我可以毫无问题地将启动的服务插入到 etcd 中。我的用例需要这样的东西:

ExecStartPost=/usr/bin/etcdctl set /services/myServiceName '{ \"host\": \"%H\", \"port\": 5555 }'
Run Code Online (Sandbox Code Playgroud)

这就像一个魅力。

但这就是我的想法出现的地方。如果我只是运行docker run -p 5555,Docker 有能力随机分配一个端口,这很棒,因为我不必在 *.service 文件中静态设置它,而且我可以在同一主机上运行多个实例。如果我可以获得随机分配的端口并插入而不是静态的5555怎么办?

原来我可以使用该docker port命令来获取端口,并通过一些格式我们可以只获取端口

$(echo $(/usr/bin/docker port my-container-name 5555) | cut -d':' -f2)
Run Code Online (Sandbox Code Playgroud)

如果我这样设置(使用 bash),它会起作用:

/usr/bin/etcdctl set /services/myServiceName '{ \"host\": \"%H\", \"port\": '$(echo $(/usr/bin/docker port my-container-name 5555) | cut -d':' -f2)' }'
Run Code Online (Sandbox Code Playgroud)

但是使用 systemd 我就是无法让它工作。这是我正在使用的代码:

ExecStartPost=/usr/bin/etcdctl set /services/myServiceName '{ \"host\": \"%H\", \"port\": '$(echo $(/usr/bin/docker port my-container-name 5555) | cut -d':' -f2)'}'
Run Code Online (Sandbox Code Playgroud)

不知何故,我出了点问题,但很难调试,因为在终端中输入时它可以工作。

And*_*inn 2

systemdExecStart选项不执行任何 shell 插值,因此不理解诸如$(echo 'Hello'). 但是,您可以启动一个执行命令的 shell 来获得这样的行为。尝试类似的方法:

ExecStartPost=/bin/sh -c "/usr/bin/etcdctl set /services/myServiceName '{ \"host\": \"%H\", \"port\": '$(echo $(/usr/bin/docker port my-container-name 5555) | cut -d':' -f2)'}'"
Run Code Online (Sandbox Code Playgroud)