Docker container間の連携について

docker初心者なので、Docker container同士の連携について、設定方法やらを半年後の自分用にチラシの裏しておきます。

この内容を踏まえた上で、[docker-compose (旧Fig)](http://qiita.com/taka4sato/items/f03004e449538b325b5e)に進む事をお奨めします。

# 初めに
Container同士の連携と言っても、大きく2つのケースがあります。

1. 同じHost内にあるContainer間の連携 (シングルホスト)
1. 別のHostにあるContainerとの連携 (マルチホスト)

マルチホストでの連携は、Best practiceについてまだ試行錯誤の段階にあるみたいですが、[ここら辺](http://deeeet.com/writing/2014/12/01/docker-link-pattern/)とか[ここら辺](http://k2nr.me/blog/2014/08/21/docker-container-management.html)を参照して見て下さい。

ここでは、シングルホストでの連携についてチラシの裏しておきます。
結論から言うと、同じHost上のContainer-A→Container-Bにアクセスさせる場合、

* Container-Aの起動時に、`docker run` に`--link` OptionでContainer-Bを指定して上げる事でアクセスできる様になります
* Container-A上で`curl localhost:xxx` (xxxはContainer-BがHostにexposeしてるPort)ではアクセス出来ないです

###参考URL

* [公式PageのLinkについてのページ](http://docs.docker.com/userguide/dockerlinks/) 
* [公式Pageを日本語訳してくれたページ](http://qiita.com/zembutsu/items/f361cad9be500950939f) 



# 素のContainerからnginx Containerにアクセス

Container-A (素のubuntu) から、Container-B (nginx, Port 25525をhostにexpose)にアクセスしたい、というCase studyで、Container間の連携の設定方法やアクセス方法を見てみたいと思います。

### Container-Bを立ち上げる
まず、アクセスを受ける側のContainer-Bを立ち上げます。中身の`dockerfile/nginx`は[このDockerfile](https://registry.hub.docker.com/u/dockerfile/nginx/)です。単にnginxをinstallして、port 80で待ち受けしているだけです。このcontainerに`nginx_test`という名前を付けて、Host側からPort 25525でアクセスできるようにしています。

```
#docker run -d -p 25525:80 --name nginx_test dockerfile/nginx
```

Container-Bの起動後、host上で、`curl localhost:25525`すると、Container-Bのnginxから応答(Welcome to nginxのHTML code)がある事を確認して下さい。

### Container-Aを立ち上げる
続いて、アクセスする側のContainer-Aを立ち上げます。中身は素のubuntu 14.04です。
`--link nginx_test:nginx`で、`nginx_test`というcontainerに`nginx`というAliasを付与しています。

```
#docker run -it --link nginx_test:nginx ubuntu:14.04
```


すると、Container-Aのshellに遷移すると思います。

### Container-AからContainer-Bがどう見えるか確認する
Container-AのShell上で以下の操作をして、Container-BがContainer-Aからどう見えて居るのか、Container-Bのnginxにどうすればアクセスできるのか見てみます。

``` 
環境変数の確認
#env | grep NGINX
NGINX_PORT_443_TCP_ADDR=172.17.0.2
NGINX_NAME=/cranky_kowalevski/nginx
NGINX_PORT_80_TCP_PROTO=tcp
NGINX_PORT_80_TCP=tcp://172.17.0.2:80
NGINX_PORT_443_TCP_PORT=443
NGINX_PORT_80_TCP_PORT=80
NGINX_PORT_443_TCP=tcp://172.17.0.2:443
NGINX_PORT_443_TCP_PROTO=tcp
NGINX_PORT_80_TCP_ADDR=172.17.0.2
NGINX_PORT=tcp://172.17.0.2:80

/ect/hostsの確認
#cat /ect/hosts | grep nginx
172.17.0.2      nginx

Container-Bにping
#ping nginx
PING nginx (172.17.0.2) 56(84) bytes of data.
64 bytes from nginx (172.17.0.2): icmp_seq=1 ttl=64 time=0.114 ms
...

Container-Bのnginxに接続してみる
#apt-get update && apt-get install -y curl
#curl nginx
で、Welcome to nginxのHTML codeが戻って来たら成功です。

```
### まとめ
* Container-AからはContainer-Bは`nginx`というaliasで見える。`curl nginx`もしくは`curl nginx:80`でアクセスできる
* Container-Aの環境変数に、Container-Bの情報が色々登録されている
* Container-Aから、`curl localhost:25525`や`curl localhost:80`してもContainer-Bにはアクセスできない
* Container-Bは、`docker run -p 25525:80`として起動させたが、Container-Aからは`nginx:80`として見える  
`25525`はあくまでhost側に見せるport。つまりContainer-BにはContainer-Aしかアクセスせず、HostからContainer-Bへのアクセスは存在しない場合には、Container-BのPortはHostにExposeする必要は無い



# 素のContainerからMongo Containerにアクセス

続いて、Container-A (素のubuntu) から、Container-B (MongoDB, Port 27017をhostにexpose)にアクセスしたい、というCase studyで、Container間の連携の設定方法やアクセス方法を見てみたいと思います。

### Container-Bを立ち上げる
まず、アクセスされる側のContainer-Bを立ち上げます。中身の`dockerfile/mongodb`は[このDockerfile](https://registry.hub.docker.com/u/dockerfile/mongodb/)です。単にMongo DBをinstallして、port 27017で待ち受けしているだけです。このcontainerに`mongo_test`という名前を付けて、Host側からPort 27017でアクセスできるようにします。

```
#docker run -d -p 27017:27017 --name mongo_test dockerfile/mongodb
```

### Container-Aを立ち上げる
続いて、アクセスする側のContainer-Aを立ち上げます。中身は素のubuntu 14.04です。
`--link mongo_test:mongo_test1`で、`mongo_test`というcontainerに`mongo_test1`というAliasを付与しています。

```
#docker run -it --link mongo_test:mongo_test1 ubuntu:14.04
```

すると、Container-Aのshellに遷移すると思います。

### Container-AからContainer-Bがどう見えるか確認する
Container-AのShell上で以下の操作をして、Container-BがContainer-Aからどう見えて居るのか、Container-BのMongoにどうすればアクセスできるのか見てみます。

``` 
環境変数の確認
#env | grep MONGO
MONGO_TEST1_PORT_27017_TCP_ADDR=172.17.0.57
MONGO_TEST1_PORT_27017_TCP=tcp://172.17.0.57:27017
MONGO_TEST1_PORT=tcp://172.17.0.57:27017
MONGO_TEST1_PORT_27017_TCP_PROTO=tcp
MONGO_TEST1_PORT_28017_TCP=tcp://172.17.0.57:28017
MONGO_TEST1_PORT_27017_TCP_PORT=27017
MONGO_TEST1_PORT_28017_TCP_ADDR=172.17.0.57
MONGO_TEST1_PORT_28017_TCP_PORT=28017
MONGO_TEST1_NAME=/sharp_pike/mongo_test1
MONGO_TEST1_PORT_28017_TCP_PROTO=tcp


/ect/hostsの確認
#cat /ect/hosts | grep mongo
172.17.0.57     mongo_test1


Container-Bにping
#ping mongo_test1
PING mongo_test1 (172.17.0.57) 56(84) bytes of data.
64 bytes from mongo_test1 (172.17.0.57): icmp_seq=1 ttl=64 time=0.058 ms
...


Container-BのMongoに接続してみる
#apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
#echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' > /etc/apt/sources.list.d/mongodb.list
#apt-get update && apt-get install -y mongodb-org-shell
#mongo $MONGO_TEST1_PORT_27017_TCP_ADDR:$MONGO_TEST1_PORT_27017_TCP_PORT
MongoDB shell version: 2.6.7
connecting to: 172.17.0.57:27017/test
...
mongo cliに入れて、mongoの操作が出来る事を確認して下さい


最後のmongoコマンドは、単純に以下でもOKです
#mongo --host mongo_test1
```
### まとめ
* Container-Aからは、Container-Bは、`mongo_test1`というaliasで見えている。`curl mongo_test1`でアクセスできる
* Container-Aの環境変数に、Container-Bの情報が色々登録されている
* Container-Aから、`curl localhost:27017`してもContainer-Bにはアクセスできない