異なるサーバーで実行できるdocker-composeファイルを作成したい。
そのためには、docker-compose.ymlのいくつかの場所で、サーバーのHost-ipまたはホスト名(すべてのコンテナーが実行されている)を指定できる必要があります。
例えば。領事コンテナの場合、仲間の領事コンテナがサーバーを見つける方法を定義します。
consul:
image: progrium/consul
command: -server -advertise 192.168.1.125 -bootstrap
明らかに192.168.1.125をハードコーディングしたくありません。
env_file :を使用してホスト名またはipを指定し、すべてのサーバーでそれを採用することができます。 -compose.yml。ただし、これは環境変数を指定するためにのみ使用でき、advertiseパラメーターには使用できません。
より良い解決策はありますか?
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
より良い解決策はありますか?
絶対に!コンテナ間の通信にホストIPはまったく必要ありません。 docker-compose.yaml
ファイルにlink
コンテナがある場合、サービスのIPアドレスを検出するために使用できる多くの環境変数にアクセスできます。
たとえば、2つのコンテナを持つdocker-compose構成を考えてみましょう。1つはconsul
を使用し、もう1つは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の変数のセットがあります。たとえば、2番目の画像では、次の場所に接続することにより、consul REST APIと対話できます。
http://${CONSUL_PORT_8500_TCP_ADDR}:8500/
Docker Composeの新しいバージョン( 1.4. )を使用すると、次のようなことができるはずです。
docker-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
静的と思われるDocker内部ネットワークIP 172.17.0.1を使用しました
環境変数は、以前のソリューションで提案されたように、コンテナーがリンクされるときにDockerによって作成されます。ただし、コンテナが再起動された場合、env変数は自動的に更新されません。そのため、本番環境で環境変数を使用することは推奨されません。
Dockerは、環境変数の作成に加えて、/ etc/hostsファイルのホストエントリも更新します。実際、Dockerのドキュメントでは、環境変数の代わりにetc/hostsのHostエントリを使用することを推奨しています。
リファレンス: https://docs.docker.com/userguide/dockerlinks/
/ etc/hostsファイルのホストエントリとは異なり、環境変数に保存されているIPアドレスは、ソースコンテナが再起動されても自動的に更新されません。/etc/hostsのホストエントリを使用して、リンクされたコンテナのIPアドレスを解決することをお勧めします。