私はモノリスサーバーを多数の小さなドッカーコンテナーに分割する予定ですが、「コンテナー間通信」に適したソリューションはまだ見つかりません。これが私のターゲットシナリオです。
コンテナをリンクする方法とポートを公開する方法は知っていますが、これらのソリューションはどれも私を満足させるものではありません。
従来のサーバーネットワークのように、コンテナ間でホスト名(コンテナ名)を介して通信するソリューションはありますか?
編集:Docker 1.9の後、docker network
コマンド(以下を参照してください https://stackoverflow.com/a/35184695/977939 )これを達成するための推奨方法です。
私の解決策は、DNSレコードが自動的に更新されるようにホストでdnsmasqを設定することです。「A」レコードはコンテナの名前を持ち、コンテナのIPアドレスを自動的にポイントします(10秒ごと)。 自動更新スクリプト はここに貼り付けられます:
#!/bin/bash
# 10 seconds interval time by default
INTERVAL=${INTERVAL:-10}
# dnsmasq config directory
DNSMASQ_CONFIG=${DNSMASQ_CONFIG:-.}
# commands used in this script
DOCKER=${DOCKER:-docker}
SLEEP=${SLEEP:-sleep}
TAIL=${TAIL:-tail}
declare -A service_map
while true
do
changed=false
while read line
do
name=${line##* }
ip=$(${DOCKER} inspect --format '{{.NetworkSettings.IPAddress}}' $name)
if [ -z ${service_map[$name]} ] || [ ${service_map[$name]} != $ip ] # IP addr changed
then
service_map[$name]=$ip
# write to file
echo $name has a new IP Address $ip >&2
echo "Host-record=$name,$ip" > "${DNSMASQ_CONFIG}/docker-$name"
changed=true
fi
done < <(${DOCKER} ps | ${TAIL} -n +2)
# a change of IP address occured, restart dnsmasq
if [ $changed = true ]
then
systemctl restart dnsmasq
fi
${SLEEP} $INTERVAL
done
Dnsmasqサービスがdocker0
で利用可能であることを確認してください。次に、このミニDNSサービスを使用するには、--dns Host_ADDRESS
でコンテナーを起動します。
新しいネットワーク機能を使用すると、名前でコンテナに接続できるため、新しいネットワークを作成すると、そのネットワークに接続されているコンテナは名前で他のコンテナに到達できます。例:
1)新しいネットワークを作成します
$ docker network create <network-name>
2)コンテナをネットワークに接続します
$ docker run --net=<network-name> ...
または
$ docker network connect <network-name> <container-name>
3)名前によるコンテナのping
docker exec -ti <container-name-A> ping <container-name-B>
64 bytes from c1 (172.18.0.4): icmp_seq=1 ttl=64 time=0.137 ms
64 bytes from c1 (172.18.0.4): icmp_seq=2 ttl=64 time=0.073 ms
64 bytes from c1 (172.18.0.4): icmp_seq=3 ttl=64 time=0.074 ms
64 bytes from c1 (172.18.0.4): icmp_seq=4 ttl=64 time=0.074 ms
ドキュメントの this セクションを参照してください。
注:従来のlinks
とは異なり、新しいネットワークは環境変数を作成しません、環境変数を他のコンテナと共有することもできません。
現在、この機能はエイリアスをサポートしていません
少なくともホスト名の部分については、 --link
の目的は であるべきです。
docker 1.10およびPR 19242 の場合、次のようになります。
docker network create --net-alias=[]: Add network-scoped alias for the container
(以下の最後のセクションを参照)
環境変数に加えて、Dockerはソースコンテナーのホストエントリを
/etc/hosts
ファイルに追加します。
たとえば、LDAPサーバーを起動します。
docker run -t --name openldap -d -p 389:389 larrycai/openldap
そして、LDAPサーバーをテストするためのイメージを定義します。
FROM ubuntu
RUN apt-get -y install ldap-utils
RUN touch /root/.bash_aliases
RUN echo "alias lds='ldapsearch -H ldap://internalopenldap -LL -b
ou=Users,dc=openstack,dc=org -D cn=admin,dc=openstack,dc=org -w
password'" > /root/.bash_aliases
ENTRYPOINT bash
--linkを使用すると、テストイメージ内で「openldap
」コンテナを「internalopenldap
」として公開できます。
docker run -it --rm --name ldp --link openldap:internalopenldap ldaptest
次に、「lds」と入力すると、そのエイリアスが機能します。
ldapsearch -H ldap://internalopenldap ...
それは人々を返すでしょう。意味internalopenldap
は、ldaptest
イメージから正しく到達します。
もちろん、docker 1.7は libnetwork
を追加します。これは、コンテナを接続するためのネイティブGo実装を提供します。 ブログ投稿 を参照してください。
Container Network Model(CNM)により、より完全なアーキテクチャを導入しました
これにより、新しい「ネットワーク」コマンドでDocker CLIが更新され、「-net
」フラグを使用してコンテナーをネットワークに割り当てる方法が文書化されます。
docker 1.10には、新しいセクション Network-scoped alias があり、現在 に正式に文書化されていますnetwork connect
:
リンクはコンテナ内でローカライズされるプライベートな名前解決を提供しますが、ネットワークスコープのエイリアスは、特定のネットワークのスコープ内の他のコンテナが代替名によってコンテナを発見する方法を提供します。
サービスのコンシューマーによって定義されるリンクエイリアスとは異なり、ネットワークスコープのエイリアスは、ネットワークにサービスを提供するコンテナーによって定義されます。上記の例を続けて、ネットワークエイリアスを使用して
isolated_nw
に別のコンテナを作成します。
$ docker run --net=isolated_nw -itd --name=container6 -alias app busybox
8ebe6767c1e0361f27433090060b33200aac054a68476c3be87ef4005eb1df17
--alias=[]
コンテナのネットワークスコープエイリアスを追加する
--link
オプションを使用して、別のコンテナを優先エイリアスにリンクできますネットワークに接続されているコンテナを一時停止、再起動、および停止できます。一時停止されたコンテナは接続されたままであり、ネットワーク検査で明らかにすることができます。コンテナが停止すると、再起動するまでネットワークに表示されません。
指定した場合、停止したコンテナが再起動されると、コンテナのIPアドレスが再適用されます。 IPアドレスが使用できなくなった場合、コンテナは起動に失敗します。
IPアドレスが使用可能であることを保証する1つの方法は、ネットワークの作成時に
--ip-range
を指定し、その範囲外から静的IPアドレスを選択することです。これにより、このコンテナがネットワーク上にない間、IPアドレスが別のコンテナに与えられないことが保証されます。
$ docker network create --subnet 172.20.0.0/16 --ip-range 172.20.240.0/20 multi-Host-network
$ docker network connect --ip 172.20.128.2 multi-Host-network container2
$ docker network connect --link container1:c1 multi-Host-network container2
EDIT:もうEdgeから出血していません: http://blog.docker.com/2016/02/docker-1 -10 /
元の回答
一晩中戦いました。 Edgeのブリーディングを恐れないのであれば、最新バージョンの Docker engine と Docker compose は両方ともlibnetworkを実装しています。
適切な構成ファイル(バージョン2に配置する必要があります)を使用して、すべて相互に認識できるサービスを作成します。また、ボーナスとして、docker-composeを使用してそれらをスケーリングできます(ホスト上のポートをバインドしない任意のサービスをスケーリングできます)
以下に例を示します file
version: "2"
services:
router:
build: services/router/
ports:
- "8080:8080"
auth:
build: services/auth/
todo:
build: services/todo/
data:
build: services/data/
そして、この新しいバージョンの構成ファイルのリファレンス: https://github.com/docker/compose/blob/1.6.0-rc1/docs/networking.md
私の知る限り、Dockerのみを使用することでは不可能です。コンテナのip:sをホスト名にマップするには、DNSが必要です。
すぐに使用できるソリューションが必要な場合。 1つの解決策は、たとえば Kontena を使用することです。これには、Weaveのネットワークオーバーレイテクノロジーが付属しており、このテクノロジーを使用して各サービスの仮想プライベートLANネットワークを作成し、すべてのサービスにservice_name.kontena.local-address
でアクセスできます。
Wordpressサービスのwordpress-mysql.kontena.localアドレスを使用してMySQLサーバーに接続するWordpressアプリケーションのYAMLファイルの簡単な例を次に示します。
wordpress:
image: wordpress:4.1
stateful: true
ports:
- 80:80
links:
- mysql:wordpress-mysql
environment:
- WORDPRESS_DB_Host=wordpress-mysql.kontena.local
- WORDPRESS_DB_PASSWORD=secret
mysql:
image: mariadb:5.5
stateful: true
environment:
- MYSQL_ROOT_PASSWORD=secret
Tumtum Blog を見つけて、つまずいたのは 公式Dockerドキュメントのこの段落 です。この段落をずっと見逃していたのか、それとも新しく追加されたのかはわかりませんが、それがまさに必要なものです:)