こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。
この記事では、以下の記事で構築したDocker Swarm環境上でデプロイしたservice(nginxとredis)のIPアドレスやネットワーク環境がどうなっているかを確認してみたいと思います。
復習
Docker Swarmクラスタに所属しているnodeは以下となります。
hostnameがdockerとなっているnodeがLeaderで、その他2つのnodeがworker nodeとなっており、計3つのnodeがSwarmクラスタを形成しています。
root@docker:~# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
624so5sshxf30h6bgde3mr9kl * docker Ready Active Leader 23.0.3
ru8v94326h4pdghg0h1vifljy swarm-worker01 Ready Active 23.0.4
pnmvavvon0hfrciinwn7w4pe3 swarm-worker02 Ready Active 23.0.4
networkは以下となります。
root@docker:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
92d578e12a26 bridge bridge local
da8e681f4aa2 docker_gwbridge bridge local
e80bd3a263ec host host local
5d0wz7me1k3q ingress overlay swarm
93abcdf649c5 none null local
このSwarm環境に以下のコマンドを実行してnginx serviceをデプロイ
root@docker:~# docker service create --replicas 3 --name nginx nginx:latest
q3mg1bd2cjq125n8evhu2fsv2
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Service converged
root@docker:~# docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
7cjbdf9htcgw nginx.1 nginx:latest swarm-worker02 Running Running about a minute ago
nwbn4sewf7ug nginx.2 nginx:latest docker Running Running 5 minutes ago
g7t4p8ketaer nginx.3 nginx:latest swarm-worker01 Running Running about a minute ago
またportainerを使ってGUIベースでredis serviceをデプロイしています。
コンテナとネットワークの確認
早速ですがdocker node(Leader)上で以下から取得したシェルスクリプトを実行し、コンテナのIPアドレス一覧を出力してみたいと思います。
django-conやportainerは今回関係ありませんので無視ししてもらって構いません。
nginxコンテナもredisコンテナも172.17.0.0/16のネットワークにいることが分かりますね。
※シェルを用意するのが面倒であればdocker inspect "コンテナ名"でIPアドレスが確認出来ます。
root@docker:~/docker-netns# ls -ltr
total 8
-rw-r--r-- 1 root root 280 Apr 19 06:56 README.md
-rwxr-xr-x 1 root root 3972 Apr 19 06:56 docker-netns.sh
root@docker:~/docker-netns# ./docker-netns.sh visible
container's network namespace to visible, you can show container's nemespace by [ip netns] command.
root@docker:~/docker-netns# ./docker-netns.sh showveth
VETH CONTAINER ID NAMES
vethba234a8 89b3a62cfac9 /django-con
vethabb34ac 788d4fd0762d /redis.3.stm8yqzn2pe9y5sf82uekv3ni
vethbe55e07 a2430aa7323e /nginx.2.nwbn4sewf7ugnnbctw3qukcvk
vethbb9bfd9 8240d0af95a3 /portainer
root@docker:~/docker-netns# ./docker-netns.sh showip
CONTAINER ID IP NAMES
89b3a62cfac9 inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0 /django-con
788d4fd0762d inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0 /redis.3.stm8yqzn2pe9y5sf82uekv3ni
a2430aa7323e inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 /nginx.2.nwbn4sewf7ugnnbctw3qukcvk
8240d0af95a3 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 /portainer
このネットワークはどのbridge,ingressが担当しているのか確認してみます。
Leader上での出力結果の一部を以下に記載しておりますが、結果からも分かるように、Docker Swarmを作成した際に自動生成されるingressやdocker_gwbridgeにserviceが自動的にデプロイされるわけではなく、dockerをインストールした際に自動生成されるbridge(docker0)に紐づいていることが分かります。
serviceはDocker Swarmの話だと思っていたので、デフォルトでingressかdocker_gwbridgeにデプロイされると思ったのですが違うようですね。。。
root@docker:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
92d578e12a26 bridge bridge local
da8e681f4aa2 docker_gwbridge bridge local
e80bd3a263ec host host local
5d0wz7me1k3q ingress overlay swarm
93abcdf649c5 none null local
root@docker:~# docker network inspect docker_gwbridge
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
root@docker:~# docker network inspect ingress
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "10.0.0.0/24",
"Gateway": "10.0.0.1"
}
]
},
root@docker:~# docker network inspect bridge
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
worker01とworker02でも同様にコンテナのIPアドレスとネットワークを確認してみようと思います。
まずはworker01
root@swarm-worker01:~/docker-netns# ./docker-netns.sh showveth
VETH CONTAINER ID NAMES
vetha6d09e8 7ebc11d3fea6 /redis.1.evg1blajwa49alzu6j8kcorqk
veth21699f0 1adc34f9c814 /nginx.3.g7t4p8ketaerk0r3dwmdxsxde
root@swarm-worker01:~/docker-netns# ./docker-netns.sh showip
CONTAINER ID IP NAMES
7ebc11d3fea6 inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 /redis.1.evg1blajwa49alzu6j8kcorqk
1adc34f9c814 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 /nginx.3.g7t4p8ketaerk0r3dwmdxsxde
root@swarm-worker01:~/docker-netns# docker network ls
NETWORK ID NAME DRIVER SCOPE
99685a25d3bd bridge bridge local
2bd0158eceaa docker_gwbridge bridge local
9d0f7be57db6 host host local
5d0wz7me1k3q ingress overlay swarm
a79ea157cf94 none null local
root@swarm-worker01:~/docker-netns# docker network inspect docker_gwbridge
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
root@swarm-worker01:~/docker-netns# docker network inspect ingress
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "10.0.0.0/24",
"Gateway": "10.0.0.1"
}
]
},
root@swarm-worker01:~# docker network inspect bridge
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
続いてworker02
root@swarm-worker02:~/docker-netns# ./docker-netns.sh showveth
VETH CONTAINER ID NAMES
vethf515806 53ff2c1f517a /redis.2.0pymeevizsisahqrlzxcgtx9t
veth28c2242 3d8f68d6a776 /nginx.1.7cjbdf9htcgw74s9x35yuuy1j
root@swarm-worker02:~/docker-netns# ./docker-netns.sh showip
CONTAINER ID IP NAMES
53ff2c1f517a inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 /redis.2.0pymeevizsisahqrlzxcgtx9t
3d8f68d6a776 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 /nginx.1.7cjbdf9htcgw74s9x35yuuy1j
root@swarm-worker02:~/docker-netns# docker network ls
NETWORK ID NAME DRIVER SCOPE
485e81c1074f bridge bridge local
f0dc62496a89 docker_gwbridge bridge local
e8edf1bca875 host host local
5d0wz7me1k3q ingress overlay swarm
ed360f541d18 none null local
root@swarm-worker02:~/docker-netns# docker network inspect docker_gwbridge
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
root@swarm-worker02:~/docker-netns# docker network inspect ingress
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "10.0.0.0/24",
"Gateway": "10.0.0.1"
}
]
},
root@swarm-worker02:~# docker network inspect bridge
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
上記の出力を鑑みるに、たぶんイメージとしては以下の様な状態であると言えると思います。
bridge(docker0)にコンテナがぶら下がっているので、どのホストに接続してもnginxやredisに接続出来ますが、負荷分散が出来ているわけではない状態と言えると思います。
また、ホストを跨いだコンテナ間通信も勿論出来ておりません。
この後、ログは無いのですがdocker_gwbridgeやingressにコンテナをアタッチ出来ないかいろいろ試してみたのですが、不発。
docker公式のドキュメント【Use the default overlay network】を見てみても、デフォルトで作成されるingressではなく、別途overlayを作ってそこにアタッチしている様でした、、、良くわからぬ。。。
デフォルトで作成されるingressにserviceをアタッチする為にはserviceデプロイ時に--publishオプションを指定してあげると良いっぽいです。
以下のその手順なり検証なりを書いています。