オープニング
\\\ インターネッツ!!大海原! ///♪♪

皆さんこんばんは。ディスカバリーチャンネル「インターネッツ!大海原!!」
MCを務めるのは毎度おなじみジャッカルと、

ジェシーよ~♪
インターネットという大海に生息する高度な精度を誇るOSSにクローズアップし、どんなものなのかを触れ合うことで理解するシリーズ。
本シリーズは鯨さんがトレードマークのDockerにクローズアップしその生態系に迫ります。第3回目は❝複数❞のDockerコンテナです。
第1回目と第2回目では単体のコンテナに関してしか考えませんでした。
しかしDockerのコンテナは様々なアプリケーションを使う事やたくさんのコンテナを使う事にこそその真価があります。
そして実際に複数のコンテナを使用するということは各コンテナ間の接続などを考えていく必要があります。
そう、今回のテーマはコンテナのネットワークです。コンテナ間のネットワークの仕組みを紐解きます。
前回の記事は以下のリンクから行けます。
それでは今回もDockerの生態に迫っていきましょう!
今回は少しボリューミーですが一つ一つ確認していきましょう。
コンテナを用意
まず、複数のコンテナという事なので、とりあえず2つのコンテナを用意してあげます。
$ sudo docker run -dit --name httpd01 -p 8080:80 httpd:2.4
$ sudo docker run -dit --name httpd02 -p 8081:80 httpd:2.4
Dockerのコンテナはimageをdocker hubからpullしてきてrunすると起動する。
この時pullとrunの二つのコマンドを使わなくても上記のようにimageの名前(httpd)とタグ(2.4)を指定してあげてrunするとpull + runが実行されコンテナが立ち上がる。
コンテナができているかの確認
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
80221a5494af httpd:2.4 "httpd-foreground" 10 hours ago Up 10 hours 0.0.0.0:8081->80/tcp httpd02
889654dc6d98 httpd:2.4 "httpd-foreground" 11 hours ago Up 11 hours 0.0.0.0:8080->80/tcp httpd01
ここまでは以下のような状態です。ラズベリーパイの中にhttpd01とhttpd02という名前のapacheを積んだコンテナが2台できました。docker runするときにポートを指定していますね。(-p 8080:80というところと-p 8081:80というところです。)ここについてはネットワークに絡むところなので後述する図に示していきます。

コンテナ間のネットワークを考える上で必要なのはコンテナのipですがコンテナのipを調べるには「コンテナに入って(docker execを使って入ります。)確認する方法」と「docker container inspectコマンドを使う方法」の2つがあります。
今回はせっかくなのでdocker container inspectコマンドで確認してみます。以下のコマンドでhttpd01のコンテナのネットワークについての情報を確認できますが、
$ sudo docker container inspect httpd01
今回確認したいのはip addressなので、特定の値を知りたいときは–formatオプションを使います。(–formatオプションの使い方は別の記事でまとめることにします。)
$ sudo docker container inspect --format="{{.NetworkSettings.IPAddress}}" httpd01
172.17.0.2
grepを使って出力する部分を絞ることもできます。以下のコマンドを実行します。
$ sudo docker container inspect httpd01 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
対象は”IPAddress”のところでhttpd01のip addressは172.17.0.2だとわかります。
httpd02コンテナのip addressも同様に確認します。
$ sudo docker container inspect --format="{{.NetworkSettings.IPAddress}}" httpd02
172.17.0.3
DockerのIP Addressについて (docker0)
突然ですがdocker0ってご存じですか?
docker0はインターフェースです。
Dockerを始めようとした人が初めにDocker Engineをインストールしますが、このDocker Engineをインストールしたときにdocker0というインターフェースが作られます。
ifconfigコマンドで確認できます。確認するとdocker0のipは172.17.0.1であることが分かります。
$ ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:8cff:fe85:c7bb prefixlen 64 scopeid 0x20<link>
ether 02:42:8c:85:c7:bb txqueuelen 0 (イーサネット)
RX packets 348499 bytes 20681276 (19.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 665996 bytes 935750142 (892.4 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
上記のIPを元にDockerコンテナの現在のネットワーク環境は以下の図のようになっています。

まず、最初にポートのところですが、この記事の始めのコマンドでポートを指定してコンテナを作成しましたね。その時の設定が上記のポートのところの接続関係になります。

bridge ネットワーク

what’s up !? またいきなり訳のわからないワードがでてきたわ !!
さてここで突然登場したbridgeネットワークという名というネットワーク。
docker のネットワークはデフォルトではこのbridgeネットワークというネットワークが使われます。
今回の場合は以下の部分がbridgeネットワークになります。

コンテナ同士はこのbridgeネットワークを通じてお互い通信しあうことができます。
試しにhttpd02からhttpd01にアクセスして確認してみます。
まずhttpd02コンテナに入ります
$ sudo docker container exec -it httpd02 /bin/bash
root@80221a5494af:/usr/local/apache2# 👈コンテナの中に入った
疎通確認のために使うコマンドであるpingとcurlをインストールします。
root@80221a5494af:/usr/local/apache2# apt update
root@80221a5494af:/usr/local/apache2# apt -y upgrade
root@80221a5494af:/usr/local/apache2# apt install -y iputils-ping curl
まずはpingで疎通確認。httpd01コンテナに向けてpingを打ちます。
root@80221a5494af:/usr/local/apache2# ping -c 3 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.575 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.239 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.242 ms
--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 120ms
rtt min/avg/max/mdev = 0.239/0.352/0.575/0.157 ms
「0% packet loss」となっていてpingの疎通が成功しています。
次にコンテンツをcurlで確認してみます。httpd01コンテナ内ではapacheが動いています。これを確認します。
root@80221a5494af:/usr/local/apache2# curl http://172.17.0.2/
<html><body><h1>It works!</h1></body></html>
はい、以上で疎通確認完了です。疎通はできていてます。オールOK!

Docker コンテナ間の疎通はまるでクジラがコミュニケーションをとる「クジラの歌」の様だな

ジャック相変わらずロマンチストね!

HAHAHA, これだったらbridge ネットワークじゃなくてsing ネットワークの方がいいかもしれないな!

そうね!こんな素敵な歌の疎通、ブロードウェイだったらきっとスターなれるわ
※雑談部分です。読み飛ばしてもらって大丈夫な部分です。
皆さんは「クジラの歌」ってご存じですか?これは鯨がコミュニケーションを目的として発する音の事です。反復的かつパターン予測のある音で、その聞こえ様から歌唱を想起させ歌と言われるようになったらしいです。
今回、これをタイトルに使わせてもらいました。
参考:wikipedia↓

bridgeネットワーク以外にもDocker ネットワークがありますので、次の記事でDocker ネットワークについてまとめるつもりです。
まとめ
いかがだったでしょうか。今回はDocker networkの初歩としてbridge ネットワークを手を動かして、図で視覚化してまとめてみました。
実際のサービスなどは当然コンテナ2つとかではなく、もっとたくさんのコンテナを使いますので他にもネットワークを知って、Dockerを使用できる可動域を広げていく必要があります。
次回以降の記事ではそんなbridge ネットワーク以外のネットワークであるDocker ネットワークに触れたいと思います。
今回もジャッカルとジェーシーを上手く話しに挟みこめなかったな。。。キャラの性質の問題かな。。。
【参考】:さわって学ぶクラウドインフラ docker基礎からのコンテナ構築