Slide 1

Slide 1 text

怖くない コンテナ・ネットワーク ~ 難しいことはDockerにおまかせ~ 1 2020.06.29 @zaki_hmkc

Slide 2

Slide 2 text

● 話すこと ○ ホストOSとDockerのネットワークの初期状態 ○ ホストOSからDockerコンテナへの通信 ○ Dockerのコンテナ同士の通信 ● 話さないこと ○ コンテナネットワークの詳しい挙動 ○ bridge以外のネットワーク ○ proxy関連 本日のメニュー 2 コンテナ若葉マーク #wakabamark

Slide 3

Slide 3 text

要素技術を含む解説はSIOSさんのブログへ! https://tech-lab.sios.jp/archives/20179 3 コンテナ若葉マーク #wakabamark

Slide 4

Slide 4 text

自己紹介 { "twitter": "@zaki_hmkc" "github": "zaki-lknr" "work": [ "hybrid-cloud", "kubernetes", "container" ] "like": [ "ansible", "openshift", "on-premise" ] } { "twitter": "@zaki_hmkc" "github": "zaki-lknr" "work": [ "hybrid-cloud", "kubernetes", "container" ] "like": [ "ansible", "openshift", "sbhawks", "baystars" ] } 自己紹介 4

Slide 5

Slide 5 text

検証環境 $ ip addr 1: lo: ... 2: ens192: ... link/ether ... inet 192.168.0.18/24 brd 192.168.0.255 scope global noprefixroute ens192 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe22:862f/64 scope link valid_lft forever preferred_lft forever ネットワークに接続された LinuxのVMを用意 192.168.0.18 5 コンテナ若葉マーク #wakabamark

Slide 6

Slide 6 text

Install Docker $ ip addr 1: lo: ... 2: ens192: ... link/ether ... inet 192.168.0.18/24 brd 192.168.0.255 scope global noprefixroute ens192 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe22:862f/64 scope link valid_lft forever preferred_lft forever : 3: docker0: .. link/ether ... inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:faff:fe6d:af0e/64 scope link valid_lft forever preferred_lft forever Dockerインストールすると 6 コンテナ若葉マーク #wakabamark Docker Version: 19.03.11

Slide 7

Slide 7 text

インストール時点のDockerネットワーク [zaki@cloud-dev ~]$ sudo docker network ls NETWORK ID NAME DRIVER SCOPE 99511840b916 bridge bridge local 4a5b091ec94b host host local 86ed4375e66a none null local 7 コンテナ若葉マーク #wakabamark デフォルトで3種類のネットワークが用意される デフォルトでbridgeネットワークが使用される

Slide 8

Slide 8 text

inspectで詳細を確認 (network) $ sudo docker network inspect bridge "Config": [ { "Subnet": "172.17.0.0/16" } ] "Containers": {}, 8 コンテナ若葉マーク #wakabamark

Slide 9

Slide 9 text

Host OS 図にすると…(コンテナ起動前) ens192 Docker 172.17.0.0/16 docker0 172.17.0.1 192.168.0.18 9 コンテナ若葉マーク #wakabamark

Slide 10

Slide 10 text

コンテナを起動 $ sudo docker container run \ -d \ --name sample-http \ httpd 01cee855b930a3f178851da09c23fe3c47712220ab3a1c7220cb42d7634513db $ sudo docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 01cee855b930 httpd "httpd-foreground" 7 seconds ago Up 6 seconds 80/tcp sample-http 10 コンテナ若葉マーク #wakabamark

Slide 11

Slide 11 text

inspectで詳細を確認 (network) $ sudo docker network inspect bridge "Containers": { "01cee8...": { "Name": "sample-http", "EndpointID": "....", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, 11 コンテナ若葉マーク #wakabamark

Slide 12

Slide 12 text

inspectで詳細を確認 (container) $ sudo docker container inspect sample-http "Networks": { "bridge": { ... "NetworkID": "995118...", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "MacAddress": "02:42:ac:11:00:02", ... } } 12 コンテナ若葉マーク #wakabamark

Slide 13

Slide 13 text

ホストOSでipコマンド $ ip addr 23: veth9c217a5@if22: mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 26:2b:a2:d2:c1:e9 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::242b:a2ff:fed2:c1e9/64 scope link valid_lft forever preferred_lft forever 13 コンテナ若葉マーク #wakabamark

Slide 14

Slide 14 text

Host OS 図にすると…(コンテナ起動中) ens192 Docker 172.17.0.0/16 docker0 veth sample-http eth 172.17.0.2 172.17.0.1 192.168.0.18 14 コンテナ若葉マーク #wakabamark

Slide 15

Slide 15 text

● Dockerをインストールするとネットワーク(docker0)が作成される ● コンテナ起動するとIPアドレスが自動で割り当てられる ● コンテナと通信するためのネットワークインタフェース(veth)がホストOSに 作成される Dockerのネットワーク関連の初期状態 15 コンテナ若葉マーク #wakabamark

Slide 16

Slide 16 text

ホストOSからの通信 16 コンテナ若葉マーク #wakabamark

Slide 17

Slide 17 text

Host OS ネットワーク図(再掲) ens192 Docker 172.17.0.0/16 docker0 veth sample-http eth 172.17.0.2 172.17.0.1 192.168.0.18 17 コンテナ若葉マーク #wakabamark

Slide 18

Slide 18 text

IPアドレスが分かったのでホストOSからアクセス $ curl 172.17.0.2

It works!

18 コンテナ若葉マーク #wakabamark

Slide 19

Slide 19 text

ホストOS上からcurl 172.17.0.2 19 コンテナ若葉マーク #wakabamark 192.168.0.18

Slide 20

Slide 20 text

リモートからcurl? 172.17.0.2 192.168.0.18 192.168.0.* 20 コンテナ若葉マーク #wakabamark

Slide 21

Slide 21 text

リモートからのアクセス Host OS Docker docker0 ens192 sample-http eth veth Remote 192.168.0.18 172.17.0.2 「172.17.0.2」がど こにあるかわから ない 21 コンテナ若葉マーク #wakabamark

Slide 22

Slide 22 text

コンテナを外部からアクセスできるようにする $ sudo docker container run -d -p 9999:80 --name sample-http-pub httpd cf009ecea1cf18380a0e5d72cbea7433b603000be063df73fbf5e6d2de416722 -p 22 コンテナ若葉マーク #wakabamark

Slide 23

Slide 23 text

リモートからのアクセス Host OS Docker docker0 ens192 sample-http-pub Remote ホストは9999で Listen コンテナは80で Listen ホストの9999へ のアクセスをコン テナの80へ転送 -p 9999:80 で実行した場合 192.168.0.18 23 コンテナ若葉マーク #wakabamark eth veth

Slide 24

Slide 24 text

● -p オプションを使用することで ○ コンテナへアクセスをホストOSが代わりに行う ○ コンテナのIPアドレスを知る必要がなくなる ○ pはportでなくpublishのp コンテナの通信機能 24 コンテナ若葉マーク #wakabamark

Slide 25

Slide 25 text

コンテナ間の通信 25 コンテナ若葉マーク #wakabamark

Slide 26

Slide 26 text

Host OS 複数コンテナを動かして相互に通信… ens192 Docker docker0 veth webサーバー eth veth DBサーバー eth 26 コンテナ若葉マーク #wakabamark

Slide 27

Slide 27 text

コンテナのIPアドレス使えばいいのでは? ● コンテナをrunしないとアドレスがわからない ● コンテナ間通信で接続先となるコンテナから順番に起動して、次のコンテ ナにその情報を設定していかなければならない IPアドレス指定は不可能ではないが、 難しい(手順が煩雑) 27 コンテナ若葉マーク #wakabamark

Slide 28

Slide 28 text

コンテナ名でアクセスすればいいのでは? ● Dockerの「内部DNS」機能で実現可能 ● ただしデフォルトのbridgeネットワークでは機能がオフ 28 コンテナ若葉マーク #wakabamark

Slide 29

Slide 29 text

ユーザー定義bridgeネットワークを作成 $ sudo docker network create my-network --driver bridge 7a62608ea9c3e7d4051e056cdf04e91c66d2fdf2635bdba9fc52925126f204c1 $ sudo docker network ls NETWORK ID NAME DRIVER SCOPE 99511840b916 bridge bridge local 4a5b091ec94b host host local 7a62608ea9c3 my-network bridge local 86ed4375e66a none null local ユーザー定義bridgeネットワークは Dockerの「内部DNSが有効」 29 コンテナ若葉マーク #wakabamark

Slide 30

Slide 30 text

作成したネットワークをinspectで詳細確認 $ sudo docker network inspect my-network 30 コンテナ若葉マーク #wakabamark "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ]

Slide 31

Slide 31 text

ホストOSにネットワークインタフェースが追加される $ ip addr 3: docker0: mtu 1500 qdisc noqueue state UP group default link/ether 02:42:fa:6d:af:0e brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever [...] 34: br-7a62608ea9c3: mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:a5:82:b6:3e brd ff:ff:ff:ff:ff:ff inet 172.18.0.1/16 brd 172.18.255.255 scope global br-7a62608ea9c3 valid_lft forever preferred_lft forever 31 コンテナ若葉マーク #wakabamark

Slide 32

Slide 32 text

ネットワークを指定してコンテナをrun $ sudo docker container run -d -p 9998:80 --name my-http-pub --network my-network httpd c59e2277723604cd25b1c7b2d8f15ce072cf4328f92191bbcf512962d8078120 $ sudo docker container run -d --name centos-client --network my-network centos:7 tail -f /dev/null 01a6118461b70e7a6129273be9f3753b4d96aaa4edcc11309992b038a170eb04 32 コンテナ若葉マーク #wakabamark

Slide 33

Slide 33 text

Host OS 新規ネットワーク追加前の状態 ens192 Docker 172.17.0.0/16 docker0 veth sample-http-pub eth 33 コンテナ若葉マーク #wakabamark

Slide 34

Slide 34 text

Host OS 複数のDockerネットワークの様子 ens192 Docker 172.17.0.0/16 docker0 veth sample-http-pub eth 172.18.0.0/16 (my-network) br-****** veth my-http-pub eth veth centos-client eth 34 コンテナ若葉マーク #wakabamark

Slide 35

Slide 35 text

コンテナ内から別コンテナ名に対してcurl [root@01a6118461b7 /]# curl http://my-http-pub

It works!

[root@01a6118461b7 /]# curl http://my-http-pub -v * About to connect() to my-http-pub port 80 (#0) * Trying 172.18.0.2... * Connected to my-http-pub (172.18.0.2) port 80 (#0) > GET / HTTP/1.1 : : 35 コンテナ若葉マーク #wakabamark

Slide 36

Slide 36 text

● IPアドレスでの通信は事前に設定ができない ● ユーザー定義bridgeネットワークであればコンテナ名で名前解決できる ● (--linkオプションは廃止予定なので使わないこと) コンテナ間の通信 36 コンテナ若葉マーク #wakabamark

Slide 37

Slide 37 text

docker-composeのDockerネットワーク version: '3' services: my-httpd: image: httpd ports: - 9997:80 client: image: centos:7 command: ["tail", "-f", "/dev/null"] compose使用時は、ネットワークの定義が なくても、自動で専用のbridgeネットワークが 作成される 37 コンテナ若葉マーク #wakabamark

Slide 38

Slide 38 text

● Dockerはコンテナが通信するための設定を面倒見てくれる ● ホストOSからの通信は-p(--publish)を使う ● コンテナ間通信が必要な場合はbridgeネットワークを作成する ○ またはdocker-composeを使用する まとめ 38 コンテナ若葉マーク #wakabamark