docker1.12 から導入された
IngressOverlayNetwork使って、コンテナ間通信をしたかったのですが、
嵌ったので、メモ。
Version
使用したVersionは以下。
docker version
Client:
Version: 1.12.1
API version: 1.24
Go version: go1.6.3
Git commit: 23cf638
Built:
OS/Arch: linux/amd64
Server:
Version: 1.12.1
API version: 1.24
Go version: go1.6.3
Git commit: 23cf638
Built:
OS/Arch: linux/amd64
やりたい構成
1ホスト内に以下のような構成でServiceを作成。
apache(nginx) -- tomcat(spring) -- mysql
Serviceを作成したコマンドは以下
docker service create -p 80:80 --replicas 1 --name apache apache_image
docker service create -p 8009:8009 -p 8080:8080 --replicas 1 --name tomcat tomcat_image
docker service create -p 3306:3306 --replicas 1 --name mysql mysql_image
コンテナ間通信できない問題
apacheコンテナ→tomcatコンテナ
tomcatコンテナ→mysqlコンテナへの通信ができない。
以下、色々確認したコマンド
ホスト側
1.ss -natp | grep 8080
→ LISTEN 0 128 :::8080 # 各portは待ち受けされている
2.curl 192.169.56.100:8080 -w '%{http_code}\n' -o /dev/null -s
→ 200 # ホストからは通信できてる
コンテナ側
docker exec -ti apache.1.8vfwjrtun0gbthomghmzt4e67 # コンテナに入る
3. curl 192.169.56.100:8080 -w '%{http_code}\n' -o /dev/null -s
→ curl: (7) Failed connect to 192.169.56.100:8080; Connection timed out # コンテナからは通信できない
コンテナ間通信できない原因:icc
ホスト側で
tcpdump -i docker_gwbridge
を実行してpacketを確認したところ、コンテナからの通信パケットも届いてることを確認
じゃあ、設定かな?というとこで、
docker network inspect docker_gwbridge
→
[
{
"Name": "docker_gwbridge",
...
"Options": {
"com.docker.network.bridge.enable_icc": "false", # ★こいつか!
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.name": "docker_gwbridge"
},
docker_gwbridge作り直して解決
docker_gwbridgeを作り直して、
その際に"com.docker.network.bridge.enable_icc"="true"を追加。
そうすると、apacheコンテナからtomcatコンテナに通信ができた。
が、作り直すのも多少手間取った。
docker_gwbridgeにはgateway_ingress-sboxというコンテナが割り当てられており、削除できない。
別のbridge作って、別のingress作って、リンクさせて。。。
っていう方法が良くわからなかったので、dockerを入れ直した。
(ingressはswarm initしたら作成される)
swarm initする前に、docker_gwbridgeを削除し、以下のコマンドで作成。
docker network create -o "com.docker.network.bridge.enable_icc"="true" -o "com.docker.network.bridge.enable_ip_masquerade"="true" -o "com.docker.network.bridge.name"="docker_gwbridge" docker_gwbridge
その後、swarm initすると無事、再作成したdocker_gwbridgeがingressとリンクして、
コンテナ間通信できるようになった。
きっともっと良いやり方があるな。。。
ひとまず、やりたいことはできるようになった。