怖くないコンテナ・ネットワーク / docker-networking-introduction

怖くないコンテナ・ネットワーク / docker-networking-introduction

- 世界一わかりみが深いコンテナ & Docker入門 〜 その5:Dockerのネットワークってどうなってるの? 〜
https://tech-lab.sios.jp/archives/20179

- Docker コンテナ・ネットワークの理解 — Docker-docs-ja 17.06 ドキュメント
http://docs.docker.jp/engine/userguide/networking/dockernetworks.html

- ユーザ定義ネットワーク用の内部 DNS サーバ — Docker-docs-ja 17.06 ドキュメント
http://docs.docker.jp/engine/userguide/networking/configure-dns.html

4924e08c88a442edbffd87b91cb45131?s=128

zaki-lknr

June 29, 2020
Tweet

Transcript

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

  2. • 話すこと ◦ ホストOSとDockerのネットワークの初期状態 ◦ ホストOSからDockerコンテナへの通信 ◦ Dockerのコンテナ同士の通信 • 話さないこと

    ◦ コンテナネットワークの詳しい挙動 ◦ bridge以外のネットワーク ◦ proxy関連 本日のメニュー 2 コンテナ若葉マーク #wakabamark
  3. 要素技術を含む解説はSIOSさんのブログへ! https://tech-lab.sios.jp/archives/20179 3 コンテナ若葉マーク #wakabamark

  4. 自己紹介 { "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
  5. 検証環境 $ ip addr 1: lo: ... 2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP>

    ... 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
  6. Install Docker $ ip addr 1: lo: ... 2: ens192:

    <BROADCAST,MULTICAST,UP,LOWER_UP> ... 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: <BROADCAST,MULTICAST,UP,LOWER_UP>.. 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
  7. インストール時点の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ネットワークが使用される
  8. inspectで詳細を確認 (network) $ sudo docker network inspect bridge "Config": [

    { "Subnet": "172.17.0.0/16" } ] "Containers": {}, 8 コンテナ若葉マーク #wakabamark
  9. Host OS 図にすると…(コンテナ起動前) ens192 Docker 172.17.0.0/16 docker0 172.17.0.1 192.168.0.18 9

    コンテナ若葉マーク #wakabamark
  10. コンテナを起動 $ 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
  11. 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
  12. 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
  13. ホストOSでipコマンド $ ip addr 23: veth9c217a5@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> 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
  14. 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
  15. • Dockerをインストールするとネットワーク(docker0)が作成される • コンテナ起動するとIPアドレスが自動で割り当てられる • コンテナと通信するためのネットワークインタフェース(veth)がホストOSに 作成される Dockerのネットワーク関連の初期状態 15 コンテナ若葉マーク

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

  17. 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
  18. IPアドレスが分かったのでホストOSからアクセス $ curl 172.17.0.2 <html><body><h1>It works!</h1></body></html> 18 コンテナ若葉マーク #wakabamark

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

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

  21. リモートからのアクセス Host OS Docker docker0 ens192 sample-http eth veth Remote

    192.168.0.18 172.17.0.2 「172.17.0.2」がど こにあるかわから ない 21 コンテナ若葉マーク #wakabamark
  22. コンテナを外部からアクセスできるようにする $ sudo docker container run -d -p 9999:80 --name

    sample-http-pub httpd cf009ecea1cf18380a0e5d72cbea7433b603000be063df73fbf5e6d2de416722 -p <Host OSで替わりにListenするポート番号:転送先のコンテナのポート番号> 22 コンテナ若葉マーク #wakabamark
  23. リモートからのアクセス 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
  24. • -p オプションを使用することで ◦ コンテナへアクセスをホストOSが代わりに行う ◦ コンテナのIPアドレスを知る必要がなくなる ◦ pはportでなくpublishのp コンテナの通信機能

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

  26. Host OS 複数コンテナを動かして相互に通信… ens192 Docker docker0 veth webサーバー eth veth

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

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

  29. ユーザー定義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
  30. 作成したネットワークをinspectで詳細確認 $ sudo docker network inspect my-network 30 コンテナ若葉マーク #wakabamark

    "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ]
  31. ホストOSにネットワークインタフェースが追加される $ ip addr 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> 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: <NO-CARRIER,BROADCAST,MULTICAST,UP> 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
  32. ネットワークを指定してコンテナを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
  33. Host OS 新規ネットワーク追加前の状態 ens192 Docker 172.17.0.0/16 docker0 veth sample-http-pub eth

    33 コンテナ若葉マーク #wakabamark
  34. 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
  35. コンテナ内から別コンテナ名に対してcurl [root@01a6118461b7 /]# curl http://my-http-pub <html><body><h1>It works!</h1></body></html> [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
  36. • IPアドレスでの通信は事前に設定ができない • ユーザー定義bridgeネットワークであればコンテナ名で名前解決できる • (--linkオプションは廃止予定なので使わないこと) コンテナ間の通信 36 コンテナ若葉マーク #wakabamark

  37. 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
  38. • Dockerはコンテナが通信するための設定を面倒見てくれる • ホストOSからの通信は-p(--publish)を使う • コンテナ間通信が必要な場合はbridgeネットワークを作成する ◦ またはdocker-composeを使用する まとめ 38

    コンテナ若葉マーク #wakabamark