dockerのネットワークを確認、作成する方法について
コンテナのIPアドレスを確認して疎通を確認する
コンテナを立ち上げるとIPAdressが付与される。
$ docker container inspect golang-container |jq -r .[].NetworkSettings.IPAddress
172.17.0.3
$ docker container inspect debian-base |jq -r .[].NetworkSettings.IPAddress
172.17.0.2
コンテナのIP172.17.0.3に対してホストからpingをうっても疎通はできません。
コンテナとホストは別のネットワークにいるからです
$ ping 172.17.0.3
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
ホストのIPは192.168.0.11
ただし、コンテナのIPを見ると172.17.0.0/16の同じネットワークに属しています。
従ってコンテナ間のpingは疎通します
## debian-baseコンテナ(172.17.0.2)に入って、0.3のコンテナにpingする
$ docker exec -it debian-base /busybox/sh
/ # ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=4.812 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.341 ms
64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.275 ms
docker networkコマンドでdockerネットワークを管理
dockerネットワークはdocker networkコマンドで作成できます。
Dockerをインストールすると自動的にbridgeネットワークが作成され、作成したコンテナはbridgeネットワークに接続します。
dockerネットワークにはbridgeネットワークとoverlayネットワークの2種類あります。
https://docs.docker.jp/engine/userguide/networking/work-with-networks.html
docker network コマンド一覧
- connect コンテナをネットワークに接続
- create ネットワークを作成
- disconnect コンテナをネットワークから外す
- inspect ネットワークの詳細を表示
- ls ネットワークの一覧を表示
- prune 未使用のネットワークを削除
- rm 指定したネットワークを削除
docker network lsとdocker network inspectで一覧表示と詳細確認
lsはネットワークの一覧を表示、inspectは指定したネットワークの詳細を表示します。
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
abb4ea29056f bridge bridge local
## brideネットワークに属しているコンテナの名前を表示
$ docker network inspect bridge | jq '.[].Containers | .[].Name'
"debian-baae"
"golang-container"
docker network createでネットワークを作成
create {ネットワーク名}
で新規のネットワークを作成できます。
作成時にはサブネットやゲートウェイは指定しなくても自動で重複しないネットワークを割り当てますが、指定したい場合は下記のようにオプションで指定します。
$ docker network create newnetwork --subnet 172.16.0.0/16 --gateway 172.16.0.1
$ docker network ls | grep -E 'NET|new'
NETWORK ID NAME DRIVER SCOPE
ae76a1daea94 newnetwork bridge local
作成したネットワークを接続してコンテナを作成する
–netでネットワークを指定してコンテナを作成する。
$ docker run -it --name debian-static-test --net newnetwork gcr.io/distroless/static-debian11:debug
## 起動したコンテナを確認
$ docker ps | grep debian-static-test
1008639dcf41 gcr.io/distroless/static-debian11:debug "/busybox/sh" 13 minutes ago Up 12 minutes debian-static-test
##起動したコンテナのネットワークを確認する
$ docker container inspect debian-static-test |jq -r '.[].HostConfig.NetworkMode'
newnetwork
コンテナを別のネットワークに付け替える
## debian-static-testコンテナのネットワークをbridgeからnewnetworkに付け替える
## disconnectでbridgeネットワークから切断
$ docker network disconnect bridge debian-static-test
## connectでnewnetworkに接続
$ docker network connect newnetwork debian-static-test
##コンテナのアドレスがnewnetworkのサブネット内であることを確認
$ docker exec -it debian-static-test /busybox/ip a | egrep "l eth1"
inet 172.11.0.2/16 brd 172.11.255.255 scope global eth1
$ docker network inspect newnetwork | jq . | grep -i subnet
"Subnet": "172.11.0.0/16"
名前解決 Service Discoveryでコンテナ名を指定してping
新しく作成したネットワーク内にあるコンテナ同士はIPアドレスでなく、名前でもpingを飛ばすことができる。デフォルトのbridgeネットワークではできない。
docker内蔵のDNSが名前解決をしてくれる
$ docker exec -it debian-static-test /busybox/sh
/ # ping debian-static
PING debian-static (172.11.0.3): 56 data bytes
64 bytes from 172.11.0.3: seq=0 ttl=64 time=0.875 ms
64 bytes from 172.11.0.3: seq=1 ttl=64 time=0.375 ms
https://docs.docker.jp/engine/userguide/networking/dockernetworks.html
https://dev.classmethod.jp/articles/docker-service-discovery/
$ docker exec -it debian-static-test cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0
## 127.0.0.11というnameserverが設定されている
コンテナから名前解決のリクエストがあれば、内部 DNS サーバ(127.0.0.11)を最初に参照する。これは/etc/resolv.confに設定されている。
https://docs.docker.jp/engine/userguide/networking/dockernetworks.html#docker-dns
docker networkの削除
docker netwrok rmで作成したネットワークを削除できます。
$ docker network rm newnetwork
dockerネットワークの種類
dockerネットワークには3つの種類があります。
docker network lsで表示するとDRIVERの部分にbridge, host, nullが登場します(例)。
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
abb4ea29056f bridge bridge local
763de16ea37b host host local
82071b8789b8 none null local
- host dockerホストのIPアドレスを共有する
- bridge ブリッジのネットワーク、NATする
- null ネットワークに接続しない
bridgeは最初に作られているデフォルトのネットワークです。
docker network createで新しいユーザ定義のネットワークを作成できます。
デフォルトのbridgeではなく環境ごとにユーザ定義のネットワークを作成した方が管理しやすいです。
hostネットワークを利用する
hostネットワークを利用する場合は、コンテナにIPアドレスが割り振られません。
この場合コンテナはホスト上のアプリケーションな形になります。
apacheコンテナを立ち上げて80/tcpでListenすると、ホスト上でnginxを80で立ち上げるといったことはできません。
$ docker network connect host debian-container