Dockerのネットワーク構成

◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【4/18開催】VSCode Dev Containersで楽々開発環境構築祭り〜Python/Reactなどなど〜
Visual Studio Codeの拡張機能であるDev Containersを使ってReactとかPythonとかSpring Bootとかの開発環境をラクチンで構築する方法を紹介するイベントです。
https://tech-lab.connpass.com/event/311864/

こんにちは、サイオステクノロジー技術部 武井です。Dockerのネットワークが気になったのでちょっと調べてみました。

以下のコマンドで簡単なコンテナを起動して、内部のネットワークを調べてみました。PHPが動作するWebサーバーを立ち上げて、-pオプションで80番をポートフォワードします。

# docker run -d -p 80:80  --name php70-apache  php:7.0-apache

こんな構成になっているようです。

Screen Shot 2018-09-13 at 11.51.45

仮想ブリッジが内部にあり、veth(Virtual Ethernet Pair)が仮想ブリッジにつながっていて、そのペアにコンテナ側のインターフェースがいます。 vethは仮想的なネットワークインターフェースで、異なるnamespaceにあるインターフェース同士をつなぐことが出来ます。

つまり、仮想ブリッジを介して、コンテナ同士がL2のレイヤーでつながっています。

試しに見てみました。

 

# ip addr show
...
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:68:de:b6:2a 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
    inet6 fe80::42:68ff:fede:b62a/64 scope link 
       valid_lft forever preferred_lft forever
6: vethca38e86@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP 
    link/ether 22:35:bb:aa:3d:15 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::2035:bbff:feaa:3d15/64 scope link 
       valid_lft forever preferred_lft forever
...

docker0という仮想ブリッジがあるのが見えました。仮想ブリッジは172.17.0.1というIPアドレスを持っていました。

また、vethca38e86というのが、vethのインターフェースで、コンテナ側のネットワークインターフェースとケーブルで繋がっているようなイメージです。

こちらも以下のコマンドで見てみました。

# brctl show
bridge name bridge id       STP enabled interfaces
docker0     8000.024268deb62a   no      vethca38e86

仮想ブリッジに先程のvethca38e86のインターフェースが接続されているのがわかります。

物理NICと仮想ブリッジは通信は、OSの機能でルーティングされます。以下のコマンドで見てみましたが、172.17.0.0/16宛の通信がdocker0(仮想ブリッジのインターフェース)にルーティングされているのがわかります。

# ip route
default via 10.0.2.2 dev enp0s3  proto static  metric 100 
10.0.2.0/24 dev enp0s3  proto kernel  scope link  src 10.0.2.15  metric 100 
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.0.1 
192.168.56.0/24 dev enp0s8  proto kernel  scope link  src 192.168.56.38  metric 100 

iptablesの設定も見てみました。

# Generated by iptables-save v1.4.21 on Mon Sep 10 22:38:05 2018
*nat
:PREROUTING ACCEPT [11:1858]
:INPUT ACCEPT [9:706]
:OUTPUT ACCEPT [115:8648]
:POSTROUTING ACCEPT [115:8648]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80
COMMIT
# Completed on Mon Sep 10 22:38:05 2018
# Generated by iptables-save v1.4.21 on Mon Sep 10 22:38:05 2018
*filter
:INPUT ACCEPT [1127:114395]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [701:70242]
:DOCKER - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:DOCKER-USER - [0:0]
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
COMMIT
# Completed on Mon Sep 10 22:38:05 2018

以下のPREROUTINGチェインで、物理NICの80番ポート宛への通信の宛先を、コンテナのIPアドレスの80番あてへとDNATしているようです。

-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80

ローカルのインターフェース宛に届いたパケットは、独自定義のチェインDOCKERに飛んで、2番めのチェインでは、送信元のインターフェースがdoker0(仮想ブリッジのインターフェース)ではないので、そのまま3番目のチェインに飛んで、そこで宛先が80/tcpの通信は、コンテナのIPアドレスの80番にDNATしているという感じだと思います、多分。

こんな感じで、コンテナまでパケットが届くんだということがわかりました。

物理的に以下のようなネットワークを、仮想ブリッジやiptablesなどの機能でエミュレートしているのだと思います、多分。

Screen Shot 2018-09-13 at 11.51.31

以上です。今回は備忘録というかメモ的な感じですみません(´・ω・`)

アバター画像
About 武井 宜行 269 Articles
Microsoft MVP for Azure🌟「最新の技術を楽しくわかりやすく」をモットーにブログtech-lab.sios.jp)で情報を発信🎤得意分野はAzureによるクラウドネイティブな開発(Javaなど)💻「世界一わかりみの深いクラウドネイティブ on Azure」の動画を配信中📹 https://t.co/OMaJYb3pRN
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる