目的
Dockerコンテナのネットワークを構築して、Webサーバーとアプリケーション・サーバーを接続する。
デフォルトのネットワークとDocker network createで作成したネットワークの違いを確かめる。
###前提
Dockerがインストールされていること
###構成
Webサーバー、APサーバーを別々のコンテナで起動させる。
WebサーバーからhttpアクセスでAPサーバーへフォワーディングする。
Webサーバー
・nginx
APサーバー
・tomcat
ソース(ってほどのものでもないですが。。。)
https://github.com/tky-k/docker/tree/master/docker_network_sample
#####構成図
##Dockerコンテナのネットワークを構築して、Webサーバーとアプリケーション・サーバーを接続する。
###構築
と、言っても行う作業はとても少ないです。
以下5点を行います。
Dockerfileの作成
nginxのconfファイルの作成
コンテナのビルド
Docker networkの作成
コンテナの起動
#####Dockerfileの作成
ベースイメージをnginxとし、confファイルをコピーするようにします。
FROM nginx
COPY docker_sample.conf /etc/nginx/conf.d/
EXPOSE 80
EXPOSE 3000
ENTRYPOINT /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
#####nginxのconfファイルの作成
APサーバーへのフォワーディングを行うため、serverコンテキストを追加します。
nginxはデフォルトで/etc/nginx/conf.d/*.conf内のファイルを読み込むようになっているため、上記のDockerfileでコピーするようにしています。
listenは監視するポート番号、server_nameはブラウザがアクセスしようとするホスト名(HTTPヘッダのHOST)です。
proxy_passはフォワード先です。
server {
listen 3000;
server_name localhost;
location / {
proxy_pass http://docker-network-tomcat:8080;
}
location ~ /\.ht {
deny all;
}
}
#####コンテナのビルド
作成したnginxのconfファイルを取り込むために、コンテナをビルドします。
-tでタグを設定しておいたほうがよいでしょう。
docker build --no-cache=true . -t docker_network_sample:1.0
#####Docker networkの作成
Docker networkはDocker標準で用意されているコマンドを利用します。
-dでネットワークのタイプを選びます。bridgeかoverlayを指定できます。(ここについては省略)
docker network create -d=#NETWORKTYPE #NETWORK_NAME
docker network create -d=bridge docker-sample-network
#####コンテナの起動
コンテナを起動します。
--netで作成したnetworkを指定します。
docker_network_sampleがWebサーバーになるため、ホストのポートとコンテナのポートをDockerエンジンにフォワードさせるため、-pで設定します。
docker run --name docker-network-tomcat --net=docker-sample-network -d tomcat
docker container run --name docker-network-sample --net=docker-sample-network -d -p 8080:80 -p 8081:3000 docker_network_sample:1.0
以上で作業は完了です。
####動作確認
以下のURLにアクセスしてみます。nginxのデフォルトのindexページが表示されます。
http://localhost:8080
次いではこちらにアクセスしてみます。APサーバー(tomcat)にフォワーディングされることが確認できました。
http://localhost:8081
##デフォルトのネットワークとDocker network createで作成したネットワークの違いを確かめる。
Dockerはデフォルトで3種類のネットワークがあります。
bridge,host,noneの3種類です。
$docker network ls
NETWORK ID NAME DRIVER SCOPE
ef01c927c34d bridge bridge local
449369b9a406 docker-sample-network bridge local
a2396438eabe host host local
123e0d0fdf37 none null local
####作成したネットワークの確認
先程作成したネットワークの情報です。
$docker network inspect docker-sample-network
〜中略〜
"Containers": {
"7852061ce4d0624d7048ecf3e0527e8793766bb6884ccab121e8cfbe944fcbd9": {
"Name": "docker-network-sample",
"EndpointID": "afb0318d89f21e033e582a43c4667da79aecdba480705938a805cf2e1f5bc277",
"MacAddress": "02:42:ac:1a:00:03",
"IPv4Address": "172.26.0.3/16",
"IPv6Address": ""
},
"af0af80e57281abacc4624f6dd0b1d93fd8af68d8df7c1b38dcb2292bed9d1cf": {
"Name": "docker-network-tomcat",
"EndpointID": "25d89174f6caa569baca1a411ef9f5b8a1b17bde20654bc49cd4e43e186086c3",
"MacAddress": "02:42:ac:1a:00:02",
"IPv4Address": "172.26.0.2/16",
"IPv6Address": ""
}
},
この状態で相互接続できるのか確認します。
nginxのコンテナにはpingがないため、tomcatのコンテナに接続
$docker container exec -it docker-network-tomcat /bin/bash
#ping docker-network-sample
PING docker-network-sample (172.26.0.3) 56(84) bytes of data.
64 bytes from docker-network-sample.docker-sample-network (172.26.0.3): icmp_seq=1 ttl=64 time=0.063 ms
接続できています。名前によってIPアドレスも解決されています。
####標準のネットワークの確認
標準のネットワークで確認するため、コンテナを立ち上げ直します。
$docker run --name docker-network-tomcat --net=bridge -d -p 8082:8080 tomcat
966b1870debfb1cdf1d6b2e216c936c5f7967475f0dbaba46b12015051203ef3
$docker container run --name docker-network-sample --net=bridge -d -p 8080:80 -p 8081:3000 docker_network_sample:1.0
efeca9569ba7ed37436abeb1e40b1640331a08e67d67368c49e64a7df064945a
$docker network inspect bridge
〜中略〜
"Containers": {
"966b1870debfb1cdf1d6b2e216c936c5f7967475f0dbaba46b12015051203ef3": {
"Name": "docker-network-tomcat",
"EndpointID": "0a5b443e816af8a5709247fc0f15e221b1fe81e7dba139b625941d5e97c16b97",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
Containersにdocker-network-sampleが存在しません。
起動しているコンテナ一覧を確認します。
$docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
966b1870debf tomcat "catalina.sh run" 3 minutes ago Up 3 minutes 0.0.0.0:8082->8080/tcp docker-network-tomcat
docker-network-sampleのコンテナは起動していないようです。
なぜ起動しないか不明なので、-dを除いて実行してみます。
$docker container run --name docker-network-sample --net=bridge -p 8080:80 -p 8081:3000 docker_network_sample:1.0
2019/07/20 05:40:41 [emerg] 7#7: host not found in upstream "docker-network-tomcat" in /etc/nginx/conf.d/docker_sample.conf:6
nginx: [emerg] host not found in upstream "docker-network-tomcat" in /etc/nginx/conf.d/docker_sample.conf:6
docker-network-tomcatが名前解決できないため、nginxの起動でエラーになり、コンテナも起動しなかったようです。
####理由
Dockerの標準で作成されているネットワークはコンテナを起動するときに--netをつけなかった場合、自動で参加するようになっています。
$docker container run -d nginx
$docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0397130c2a99 nginx "nginx -g 'daemon of…" About a minute ago Up About a minute 80/tcp romantic_johnson
$docker network inspect bridge
〜中略〜
"Containers": {
"0397130c2a997fd86593f6fb1f1248c23fa3ba1532623650f3566c891bbf606a": {
"Name": "romantic_johnson",
"EndpointID": "3bf43195b6eff3f906bfc434fbe5e087f06b16cf2a6a45629f43c4753f9fdc5c",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
〜中略〜
この標準のネットワークは内部DNSを使用しないため、名前解決ができません。
一方、作成したネットワークはDockerの内部DNSを使って名前解決ができるようになります。
この動作の違いがあるため、標準ネットワークを使って起動しようとしたnginxは名前解決できずにエラーになってしまったようです。
2019/08/01
Docker-composeを使ってネットワーク作成、ビルド、起動まで一括でできるようにしました。
複数のコンテナの単一サーバー上での連携も設定ファイルひとつでできるので、また1つ便利だなと感じました。
##終わり
コンテナの機能の一部しかまだ把握できていませんが、まだまだ便利だなっていう感想しかでてきません。
ここがイケてないとか言えるほど修めたいですね。