我想创建一个能够在不同服务器上运行的 docker-compose 文件。
为此,我必须能够在 docker-compose.yml 的几个地方指定服务器的host-ip或主机名(所有容器都在运行)。
E.g。对于一个consul容器,我想定义如何通过其他领事容器找到服务器。
consul:
image: progrium/consul
command: -server -advertise 192.168.1.125 -bootstrap
我不想显然硬编码192.168.1.125。
我可以使用 env_file:指定主机名或IP并在每台服务器上采用它,因此我将这些信息放在一个地方并在docker-compose.yml中使用它。但这只能用于指定环境变量而不能用于广告参数。
有更好的解决方案吗?
答案 0 :(得分:17)
docker-compose允许使用运行compose命令的环境中的环境变量。
请参阅https://docs.docker.com/compose/compose-file/#variable-substitution
上的文档假设您可以创建一个包装器脚本,如@balver建议的那样,您可以设置一个名为EXTERNAL_IP
的环境变量,其中包含$(docker-machine ip)
的值。
示例:
#!/bin/sh
export EXTERNAL_IP=$(docker-machine ip)
exec docker-compose $@
和
# docker-compose.yml
version: "2"
services:
consul:
image: consul
environment:
- "EXTERNAL_IP=${EXTERNAL_IP}"
command: agent -server -advertise ${EXTERNAL_IP} -bootstrap
不幸的是,如果您使用随机端口分配,则无法添加EXTERNAL_PORT
,因此必须静态链接端口。
PS:HashiCorp Nomad默认启用非常相似的功能,还包括映射端口。 Doc:https://www.nomadproject.io/docs/jobspec/interpreted.html#interpreted_env_vars
答案 1 :(得分:15)
有更好的解决方案吗?
绝对!您根本不需要主机ip来进行容器之间的通信。如果您link
文件中有docker-compose.yaml
个容器,则可以访问许多环境变量,以便发现服务的IP地址。
例如,考虑一个包含两个容器的docker-compose配置:一个使用consul
,另一个运行一些需要与领事交谈的服务。
consul:
image: progrium/consul
command: -server -bootstrap
webserver:
image: larsks/mini-httpd
links:
- consul
首先,只需consul
启动-server -bootstrap
,consul
就会找出自己的广告地址,例如:
consul_1 | ==> Consul agent running!
consul_1 | Node name: 'f39ba7ef38ef'
consul_1 | Datacenter: 'dc1'
consul_1 | Server: true (bootstrap: true)
consul_1 | Client Addr: 0.0.0.0 (HTTP: 8500, HTTPS: -1, DNS: 53, RPC: 8400)
consul_1 | Cluster Addr: 172.17.0.4 (LAN: 8301, WAN: 8302)
consul_1 | Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false
consul_1 | Atlas: <disabled>
在webserver
容器中,我们发现pid 1可以使用以下环境变量:
CONSUL_PORT=udp://172.17.0.4:53
CONSUL_PORT_8300_TCP_START=tcp://172.17.0.4:8300
CONSUL_PORT_8300_TCP_ADDR=172.17.0.4
CONSUL_PORT_8300_TCP_PROTO=tcp
CONSUL_PORT_8300_TCP_PORT_START=8300
CONSUL_PORT_8300_UDP_END=udp://172.17.0.4:8302
CONSUL_PORT_8300_UDP_PORT_END=8302
CONSUL_PORT_53_UDP=udp://172.17.0.4:53
CONSUL_PORT_53_UDP_ADDR=172.17.0.4
CONSUL_PORT_53_UDP_PORT=53
CONSUL_PORT_53_UDP_PROTO=udp
CONSUL_PORT_8300_TCP=tcp://172.17.0.4:8300
CONSUL_PORT_8300_TCP_PORT=8300
CONSUL_PORT_8301_TCP=tcp://172.17.0.4:8301
CONSUL_PORT_8301_TCP_ADDR=172.17.0.4
CONSUL_PORT_8301_TCP_PORT=8301
CONSUL_PORT_8301_TCP_PROTO=tcp
CONSUL_PORT_8301_UDP=udp://172.17.0.4:8301
CONSUL_PORT_8301_UDP_ADDR=172.17.0.4
CONSUL_PORT_8301_UDP_PORT=8301
CONSUL_PORT_8301_UDP_PROTO=udp
CONSUL_PORT_8302_TCP=tcp://172.17.0.4:8302
CONSUL_PORT_8302_TCP_ADDR=172.17.0.4
CONSUL_PORT_8302_TCP_PORT=8302
CONSUL_PORT_8302_TCP_PROTO=tcp
CONSUL_PORT_8302_UDP=udp://172.17.0.4:8302
CONSUL_PORT_8302_UDP_ADDR=172.17.0.4
CONSUL_PORT_8302_UDP_PORT=8302
CONSUL_PORT_8302_UDP_PROTO=udp
CONSUL_PORT_8400_TCP=tcp://172.17.0.4:8400
CONSUL_PORT_8400_TCP_ADDR=172.17.0.4
CONSUL_PORT_8400_TCP_PORT=8400
CONSUL_PORT_8400_TCP_PROTO=tcp
CONSUL_PORT_8500_TCP=tcp://172.17.0.4:8500
CONSUL_PORT_8500_TCP_ADDR=172.17.0.4
CONSUL_PORT_8500_TCP_PORT=8500
CONSUL_PORT_8500_TCP_PROTO=tcp
EXPOSE
每个端口consul
d都有一组变量
图片。例如,在第二个图像中,我们可以通过连接到:
http://${CONSUL_PORT_8500_TCP_ADDR}:8500/
答案 2 :(得分:13)
使用新版本的Docker Compose(1.4.0)你应该能够做到这样的事情:
<强>搬运工-compose.yml 强>
consul:
image: progrium/consul
command: -server -advertise HOSTIP -bootstrap
<强>的bash 强>
$ sed -e "s/HOSTIP/${HOSTIP}/g" docker-compose.yml | docker-compose --file - up
这要归功于新功能:
Compose现在可以通过指定 - 作为文件名,从标准输入而不是从文件读取YAML配置。这样可以更轻松地动态生成配置:
$ echo 'redis: {"image": "redis"}' | docker-compose --file - up
答案 3 :(得分:11)
我使用了似乎是静态的docker内部网络IP:172.17.0.1
答案 4 :(得分:6)
在早期解决方案中建议的环境变量是由Docker在链接容器时创建的。但是,如果重新启动容器,则不会自动更新env变量。因此,不建议在生产中使用环境变量。
Docker除了创建环境变量外,还会更新/ etc / hosts文件中的主机条目。实际上,Docker文档建议使用etc / hosts中的主机条目而不是环境变量。
参考:https://docs.docker.com/userguide/dockerlinks/
与/ etc / hosts文件中的主机条目不同,如果重新启动源容器,则不会自动更新存储在环境变量中的IP地址。我们建议使用/ etc / hosts中的主机条目来解析链接容器的IP地址。
答案 5 :(得分:1)
创建一个脚本来在每次启动时在环境变量中设置您的主机 IP。
sudo vi /etc/profile.d/docker-external-ip.sh
然后将这段代码复制进去:
export EXTERNAL_IP=$(hostname -I | awk '{print $1}')
现在你可以在你的 docker-compose.yml 文件中使用它:
version: '3'
services:
my_service:
container_name: my-service
image: my-service:latest
environment:
- EXTERNAL_IP=${EXTERNAL_IP}
extra_hosts:
- my.external-server.net:${EXTERNAL_IP}
...
答案 6 :(得分:0)
C:/Users/User/eclipse-workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/auth-java-example/
可以工作,但是很难将其编码到extra_hosts
中,但是对于我当前的静态设置,这时我就需要这一切。
docker-compose.yml