コンテナのリンク(連結)と操作
Linking containers together - Docker Documentation
http://docs.docker.com/userguide/dockerlinks/
Using Docker section において、私たちはネットワークを通して Docker コンテナの中で実行されているサービスにつながる事に触れてきました。これは、Docker コンテナの中で、サービスと動作中のアプリケーションを相互に作用することが出来る方法の1つです。このセクションでは、リンクしている(連結している)コンテナに概念を導入するだけでなく、ネットワーク・ポートを通して、Docker コンテナへの接続をリフレッシュさせる方法を扱います。
ネットワークポート割り当てのリフレッシャー
Using Docker section において、私たちは Python Flask アプリケーションのコンテナを作る事ができました。
$ sudo docker run -d -P training/webapp python app.py
注:コンテナに内部ネットワークと IP アドレスが有る場合(Using Docker セクションにおいて、私たちはdocker inspect
コマンドを使って、コンテナの IP アドレスを表示することが出来たのを思い出してください)。Docker は様々なネットワーク設定を持ちます。Docker のネットワークの詳細については、[こちら] (http://docs.docker.com/articles/networking/) を参照してください。
コンテナを -P
フラグを使い起動すると、自動的に Docker ホストのネットワーク側のポートを、コンテナ内部のランダムな high port の範囲 49000 ~ 49900 に割り当てます。そして、私たちが docker ps
を実行すると、ポート 5000 が、ポート 49155 に割り当てられていたのを見てきました。
$ sudo docker ps nostalgic_morse
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse
私たちは、コンテナの特定のポートに割り当てるために -p
フラグを付けるのも見て来ました。
$ sudo docker run -d -p 5000:5000 training/webapp python app.py
それから、特定のポートを指定するのが何故良くない方法なのか(1つのコンテナしか使えないので)についても見て来ました。
-p
フラグを使って設定するほかにも、いくつかの方法があります。デフォルトの -p
フラグは、ホストマシン上で指定されたポートを、すべてのインターフェースに結びつけます。しかし、私たちは特定のインターフェースを指定することも出来ます、たとえば localhost
のように。
$ sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
これは、ホストマシン上のインターフェース localhost
か 127.0.0.1
上のポート 5000 を、コンテナ内部のポート 5000 に結びつけます。
あるいは、コンテナが使うポート 5000 を、localhost
とだけ指定しても、動的にポートを割り当てられることを見て来ました。
$ sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py
また /udp
を末尾に追加することで、UDP ポートに結びつけることができます、たとえば:
$ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
また、docker port
ショートカットによって現在のポート割り当て状況を見るのが便利であり、これはまた特定のポートの設定状態を見るのにも便利です。例えば、コンテナのポートをホストマシンの localhost に結びつけると、docker port
からの出力は次のようになります。
$ docker port nostalgic_morse 5000
127.0.0.1:49155
メモ:-p
フラグは、複数のポートを設定するために、複数回使用することができます。
Docker コンテナのリンク
Docker コンテナは自分自身や他に接続することが出来ず、ネットワークポートマッピングを使うのが唯一の方法です。Docker linking は、親のコンテナが選択した子どもの情報を見ることが出来る、親子関係を作ります。
コンテナのネーミング
Docker の連結(リンク)を行うには、名付けるコンテナ名に依存します。私たちは既に、私たちが作成したコンテナには自動的に名前が付けられますが、実際には、ガイドで見慣れてきた nostalgic_morse
のように、古い友達のようなものです。また、自分自身でコンテナに名付けることが出来ます。名前をつけることは、2つの役立つ機能を提供します。
-
コンテナに名前を付けることは、自分がコンテナの名前を覚えやすくするために多少は便利です。たとえば、ウェブアプリケーションが動作するコンテナを
web
と名付けます。 -
Docker が提供するのは、他のコンテナからの参照ポイントを提供します。例えば、
web
というコンテナをdb
というコンテナにリンクするとします。
自分でコンテナ名を --name
フラグを使って名付けられます。たとえば
$ sudo docker run -d -P --name web training/webapp python app.py
新しく起動するコンテナに対し、--name
フラグを使って 'web' と呼ばれる名前を付けてます。コンテナの名前は docker ps
コマンドを使って見る事が出来ます。
$ sudo docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aed84ee21bde training/webapp:latest python app.py 12 hours ago Up 2 seconds 0.0.0.0:49154->5000/tcp web
また docker inspect
を使う事で、コンテナ名を返すことも出来ます。
$ sudo docker inspect -f "{{ .Name }}" aed84ee21bde
/web
注:コンテナ名はユニークでなくてはいけません。この意味するところは、web
と呼べるコンテナは1つだけということです。もし、コンテナ名を他でも再利用したい場合は、新しいコンテナを同じ名前で作る前に、古いコンテナを docker rm
コマンドで消す必要があります。他の方法としては、docker run
コマンドに --rm
フラグを使う方法があります。これは、それが止まったら、直ぐにコンテナが削除されます。
コンテナの連結
発見したコンテナに対してリンクすることで、お互い安全に通信することができます。リンクを作成するには --link
フラグを使います。新しくコンテナを作りましょう、コンテナはデータベースです。
$ sudo docker run -d --name db training/postgres
ここで training/postgres
イメージ、中には PostgreSQL データベースを含まれるものを使って、db
という新しいコンテナを作成しました。
それでは、新しい web
コンテナを作成し、それを私たちの db
コンテナにリンクしましょう。
$ sudo docker run -d -P --name web --link db:db training/webapp python app.py
これは新しい web
コンテナを既に作成した db
コンテナにリンクします。--link
フラグは次のようになります。
--link name:alias
名前 エイリアス
ここでの name
は、リンク使用としているコンテナ名であり、alias
はリンク名に対する別名です。それでは、エイリアスがどのように使われているかを見ていきましょう。
リンク済みのコンテナは docker ps
によって見る事が出来ます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
349169744e49 training/postgres:latest su postgres -c '/usr About a minute ago Up About a minute 5432/tcp db
aed84ee21bde training/webapp:latest python app.py 16 hours ago Up 2 minutes 0.0.0.0:49154->5000/tcp db/web,web
NAMES
列には、db
と web
という名前のコンテナが見えますが、web
のコンテナには db/web
も見えます。これは web
コンテナは db
コンテナからリンクされ、親子関係があることがわかります。
それでは、コンテナにリンクするというのは、何をしているのでしょうか。これまで2つのコンテナ間でリンクを作成するときに、親子関係が発生する事がわかりました。親コンテナ、ここでは db
が子コンテナである web
に関する情報にアクセスすることができます。このようにすることで、Docker はコンテナ上に外部のポートを露出させることなく、コンテナ間に安全なトンネルをつくることができます。db
コンテナを起動するとき、-P
や -p
フラグを使わなかったことに注意しておいてください。コンテナがリンクされることによって、PostgreSQL データベースをネットワーク上に晒す必要はありません。
Docker では、親コンテナが子コンテナの情報に関する情報に触れるためには、2つの情報があります。
- 環境変数
- /etc/hosts ファイルの更新
まずはじめに、Docker がセットする環境変数を見てみましょう。コンテナの環境変数を見るために、env
コマンドを使ってみましょう。
$ sudo docker run --rm --name web2 --link db:db training/webapp env
. . .
DB_NAME=/web2/db
DB_PORT=tcp://172.17.0.5:5432
DB_PORT_5000_TCP=tcp://172.17.0.5:5432
DB_PORT_5000_TCP_PROTO=tcp
DB_PORT_5000_TCP_PORT=5432
DB_PORT_5000_TCP_ADDR=172.17.0.5
. . .
注:これらの環境変数がセットされるのは、コンテナの起動時だけです。同様に、何らかのデーモン ( sshd
など ) は、生成されたシェル ( spawning shell ) に接続するときには無効にされます。
これまで db
コンテナに関する情報を、Docker が生成したいくつかの環境変数を使って知ることができました。
各々の環境変数は DB_
という接頭辞がついており、これは先ほど設定した alias
から作成されるものです。
もし alias
が db1
であれば、変数による接頭辞は DB1_
となるでしょう。db
コンテナ上のデータベースに対して接続しているアプリケーションの設定を行いたい時、これら環境変数を使用することが出来ます。
ここの接続は安全でプライベートなものになり、リンクされた web
コンテナのみが db
コンテナに接続する事ができます。
加えて、Docker の環境変数のホスト情報から、/etc/hosts
に、親情報のエントリを追加します。それでは web
コンテナ内からファイルをみてみましょう。
root@aed84ee21bde:/opt/webapp# cat /etc/hosts
172.17.0.7 aed84ee21bde
. . .
172.17.0.5 db
私たちはエントリされているホストに関する2つのエントリを見ることが出来ます。1つめは、web
コンテナが、ホスト名にコンテナ ID を使用出来るようにするためです。2つめは、db
コンテナの IP アドレスを、エイリアス(別名)として使えるようにするためです。それでは、このホスト名をつかって ping を試みましょう。
root@aed84ee21bde:/opt/webapp# apt-get install -yqq inetutils-ping
root@aed84ee21bde:/opt/webapp# ping db
PING db (172.17.0.5): 48 data bytes
56 bytes from 172.17.0.5: icmp_seq=0 ttl=64 time=0.267 ms
56 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.250 ms
56 bytes from 172.17.0.5: icmp_seq=2 ttl=64 time=0.256 ms
注:コンテナの中には ping
がないので インストールする必要があります。
ping
コマンドを db
コンテナに対して行うために、127.17.0.5
の名前解決を行うホストエントリを用いています。私たちは、このホストエントリを使って、アプリケーションが db
コンテナに接続させるために使う事ができます。
注:1つの親に複数の子コンテナをリンクすることが出来ます。たとえば、複数の web コンテナ群を db
コンテナに対して接続する事もできるのです。
次のステップ
これでどのように Docker コンテナに対してリンクするかが分かりましたので、次のステップは、どのようにコンテナ内のデータやボリュームやマウントするかを学びます。
Go to Managind Data in Containers.