docker
docker-swarm

Docker Ingress Overlay Networkでコンテナ間通信を行う

More than 1 year has passed since last update.

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とリンクして、

コンテナ間通信できるようになった。

きっともっと良いやり方があるな。。。

ひとまず、やりたいことはできるようになった。