Docker は、ブリッジ、ホスト、オーバーレイなどの複数のネットワークを提供します。同じ Docker ホスト上に複数の異なるタイプのネットワークが同時に存在し、異なるネットワーク内のコンテナは相互に通信できません。 Docker コンテナのネットワーク間の分離と通信は、iptables メカニズムの助けを借りて実現されます。 iptables のフィルター テーブルは、デフォルトで INPUT、FORWARD、OUTPUT の 3 つのチェーンに分かれています。 Docker は、ブリッジ ネットワーク間の分離と通信を実現するために、FORWARD チェーン (カスタム チェーンへの転送) 内に独自のチェーンも提供します。 基本的なDockerネットワーク構成 Docker を起動すると、ホスト上に docker0 仮想ブリッジが自動的に作成されます。これは実際には Linux ブリッジであり、ソフトウェア スイッチとして理解できます。マウントされたネットワーク ポート間でトラフィックを転送します。 同時に、Docker は、ローカルの未使用のプライベート ネットワーク セグメント内のアドレスを docker0 インターフェイスにランダムに割り当てます。たとえば、一般的な IP アドレスは 172.17.0.1 で、マスクは 255.255.0.0 です。その後起動したコンテナ内のネットワーク ポートにも、同じネットワーク セグメント (172.17.0.0/16) 内のアドレスが自動的に割り当てられます。 Docker コンテナが作成されると、veth ペア インターフェースのペアが同時に作成されます (データ パケットが 1 つのインターフェースに送信されると、他のインターフェースでも同じデータ パケットを受信できます)。 このインターフェースのペアの一方の端はコンテナ内にあり、eth0 です。もう一方の端はローカルにあり、docker0 ブリッジにマウントされ、名前は veth で始まります (たとえば、veth1)。このようにして、ホストはコンテナと通信でき、コンテナは互いに通信できるようになります。 Docker は、ホストとすべてのコンテナの間に仮想共有ネットワークを作成します。 1. iptablesのフィルターテーブル内のDockerチェーン Docker 18.05.0 (2018.5) 以降のバージョンでは、次の 4 つのチェーンが提供されます。
現在、ホストの Docker のデフォルトの iptables 設定は、/etc/sysconfig/iptables ファイルにリストされています。 ##アドレス転送テーブル NAT ルールチェーンとデフォルト *NAT #PREROUTINGルールチェーンのデフォルトポリシーはACCEPTです :事前ルーティング受け入れ [0:0] #INPUTルールチェーンのデフォルトポリシーはACCEPTです :入力受け入れ[0:0] #OUTPUTルールチェーンのデフォルトポリシーはACCEPTです :出力受け入れ [4:272] #POSTROUTINGルールチェーンのデフォルトポリシーはACCEPTです :ポストルーティング受け入れ [4:272] #DOCKER ルールチェーンのデフォルトポリシーは ACCEPT です :ドッカー - [0:0] ##########################PREROUTING ルール チェーンに追加されたルール############################# ##-m は、パケットを一致させるために拡張モジュールを使用することを意味します。ローカルマシンに到着したパケットの宛先アドレスタイプがローカルエリアネットワークの場合、DOCKER チェーン -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER に割り当てられます。 ##########################OUTPUT ルール チェーンに追加されたルール############################ -A 出力! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER ##########################POSTROUTING ルール チェーンに追加されたルール############################# ##このルールは、コンテナが外部ネットワークと通信できるように設計されています。#送信元アドレスが 192.168.0.0/20 のパケット (つまり、Docker コンテナによって生成されたパケット) で、docker0 ネットワーク カードから送信されていないパケットは、ホスト ネットワーク カードのアドレスに変換されます。 -A POSTROUTING -s 192.168.0.0/20 ! -o docker0 -j MASQUERADE ################################DOCKER ルール チェーンに追加されたルール############################## #docker0インターフェースから入力されたデータパケットは呼び出しチェーンに返されます。-iはデータパケットがどのインターフェースから処理されるかを指定します -A DOCKER -i docker0 -j RETURN ############################################################################### ##ルールテーブル*フィルター内のチェーンとデフォルトポリシー :入力ドロップ [4:160] :転送承認[0:0] :出力受け入れ [59:48132] :ドッカー - [0:0] :DOCKER-ISOLATION-ステージ-1 - [0:0] :DOCKER-アイソレーション-ステージ-2 - [0:0] :DOCKER-ユーザー - [0:0] ###############################FORWARD ルール チェーンに追加されたルール############################## ##すべてのデータパケットはDOCKER-USERチェーンに割り当てられます -A FORWARD -j DOCKER-USER ##すべてのデータパケットはDOCKER-ISOLATION-STAGE-1チェーンに割り当てられます -A FORWARD -j DOCKER-ISOLATION-STAGE-1 -A FORWARD -o docker0 -m conntrack --ctstate RELATED、ESTABLISHED -j ACCEPT ##docker0インターフェースから出力されるデータパケットはDOCKERチェーンに割り当てられます -A FORWARD -o docker0 -j DOCKER ##docker0 インターフェースによって入力され、docker0 インターフェースによって出力されないデータ パケットは通過を許可されます -A FORWARD -i docker0 ! -o docker0 -j ACCEPT ##docker0インターフェースから入力されたデータパケットとdocker0インターフェースから出力されたデータパケットは通過を許可されます -A FORWARD -i docker0 -o docker0 -j ACCEPT ######################DOCKER-ISOLATION-STAGE-1 ルール チェーンにルールが追加されました################## ##docker0 インターフェースによって入力されるが、docker0 インターフェースによって出力されないデータ パケットは、DOCKER-ISOLATION-STAGE-2 チェーンに割り当てられます。##つまり、docker0 からのデータ パケットを処理するが、docker0 によって出力されない場合 -A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2 ##データパケットは直接呼び出しチェーンに戻ります -A DOCKER-ISOLATION-STAGE-1 -j RETURN ######################DOCKER-ISOLATION-STAGE-2 ルール チェーンにルールが追加されました################## ##docker0インターフェースから出力されたデータパケットは破棄されます -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP ##データパケットは直接呼び出しチェーンに戻ります -A DOCKER-ISOLATION-STAGE-2 -j RETURN ################################DOCKER-USER ルール チェーンに追加されたルール############################### ## 呼び出しチェーンに直接戻る -A DOCKER-USER -j RETURN 2. DockerのDOCKERチェーン ホストから docker0 への IP パケットのみが処理されます。 3. DockerのDOCKER-ISOLATIONチェーン(異なるブリッジネットワーク間の通信を分離する) ご覧のとおり、異なるブリッジ ネットワーク間の通信を分離するために、Docker は 2 つの DOCKER-ISOLATION ステージ実装を提供します。 DOCKER-ISOLATION-STAGE-1 チェーンは、送信元アドレスがブリッジ ネットワーク (デフォルトでは docker0) であるパケットをフィルタリングします。一致するパケットは、DOCKER-ISOLATION-STAGE-2 チェーンによって処理されます。 一致するものがない場合、親チェーンに FORWARD で戻ります。 DOCKER-ISOLATION-STAGE-2 チェーンでは、宛先アドレスがブリッジ ネットワーク (デフォルトでは docker0) であるパケットがさらに処理されます。一致するパケットは、パケットがブリッジ ネットワークから別のブリッジ ネットワークに送信されたことを示します。他のブリッジ ネットワークからのこのようなパケットは直接ドロップされます。 一致しないデータ パケットは、後続の処理のために親チェーンに FORWARD で返されます。 4. DockerのDOCKER-USERチェーン Docker が起動すると、DOCKER チェーンと DOCKER-ISOLATION (現在は DOCKER-ISOLATION-STAGE-1) チェーン内のフィルタリング ルールが読み込まれ、有効になります。ここでフィルタリングルールを変更することは絶対に禁止されています。 ユーザーが Docker のフィルタリング ルールを補足したい場合は、それらを DOCKER-USER チェーンに追加することを強くお勧めします。 DOCKER-USER チェーンのフィルタリング ルールは、Docker によって作成されたデフォルトのルールの前にロードされます (上記のルール リストでは、DOCKER_USER チェーンが最初にルール チェーンに追加されます)。これにより、DOCKER チェーンと DOCKER-ISOLATION チェーン内の Docker のデフォルトのフィルタリング ルールが上書きされます。 たとえば、Docker を起動すると、デフォルトで外部ソース IP の転送が許可されるため、ホスト上の任意の Docker コンテナ インスタンスにソース IP から接続できるようになります。特定の IP のみがコンテナ インスタンスにアクセスできるようにする場合は、DOCKER チェーンの前にロードできるように、DOCKER-USER チェーンにルーティング ルールを挿入できます。 次に例を示します。 # 192.168.1.1 のみがコンテナにアクセスできるようにする iptables -A DOCKER-USER -i docker0 ! -s 192.168.1.1 -j DROP # 192.168.1.0/24 ネットワークセグメントの IP のみがコンテナにアクセスできるようにする iptables -A DOCKER-USER -i docker0 ! -s 192.168.1.0/24 -j DROP # 192.168.1.1-192.168.1.3 ネットワークセグメント内の IP のみがコンテナにアクセスできるようにします (iprange モジュールが必要です) iptables -A DOCKER-USER -m iprange -i docker0 ! --src-range 192.168.1.1-192.168.1.3 -j DROP 5. iptables の nat テーブル内の Docker ルール コンテナから他の Docker ホストにアクセスするには、Docker は iptables の nat テーブルの POSTROUTING チェーンに転送ルールを挿入する必要があります。例は次のとおりです。 iptables -t nat -A POSTROUTING -s 172.18.0.0/16 -j マスカレード 上記の構成では、コンテナ インスタンスの IP 範囲をさらに制限して、Docker ホスト上に複数のブリッジ ネットワークがある状況を区別します。 6. Dockerではiptablesフィルタテーブルの変更は禁止されています dockerd を起動すると、パラメータ --iptables はデフォルトで true に設定され、iptables ルーティング テーブルを変更できるようになります。 この機能を無効にするには、次の 2 つのオプションがあります。 起動パラメータ --iptables=false を設定する 設定ファイル/etc/docker/daemon.jsonを変更し、"iptables": "false"; に設定し、systemctl reload dockerを実行してリロードします。 追加知識: Docker ネットワーク モードのデフォルト ブリッジ モード 前述の通り、Docker には birdge、host、overlay、nacvlan、none、Network plugin の 5 つのネットワーク モードがあります。ここでは主に bridge のデフォルトのブリッジ モードを紹介します。 1. はじめに ネットワークの概念では、ブリッジはネットワーク セグメント間でトラフィックを転送するリンク層デバイスです。ネットワーク ブリッジは、ホスト カーネル上で実行されるハードウェア デバイスまたはソフトウェア デバイスです。 Docker では、ブリッジ ネットワークはソフトウェア ブリッジングを使用します。同じブリッジ ネットワークに接続されたコンテナーは、直接かつ完全なポートで相互に通信でき、ブリッジ ネットワークに接続されていないコンテナーとは直接分離されます。このように、ブリッジ ネットワークは、同じホスト上のすべてのコンテナーの接続と分離を管理します。 Docker のブリッジ ドライバーは、同じブリッジ上のネットワークが相互に通信できるように、また異なるブリッジ ネットワーク上のコンテナーが相互に分離されるように、ホストにルールを自動的にインストールします。 ブリッジ ネットワークは、同じホスト上の Docker デーモンによって生成されたコンテナーに適用できます。異なるホスト上のコンテナー間のやり取りには、オペレーティング システム レベルのルーティング操作を使用するか、オーバーレイ ネットワーク ドライバーを使用します。 Docker を起動すると (systemctl start docker)、Docker デーモンをホスト マシンに接続するためのデフォルトのブリッジ ネットワーク (birbr0) が自動的に作成され、ネットワーク docker0 が作成されます。以降のコンテナーは、ブリッジ ネットワーク (docker0) に自動的に接続されます。ローカル ブリッジを表示できます。コンテナーが作成されるたびに、コンテナーをデフォルトのブリッジ ネットワークに接続するための新しいブリッジが作成されます。 [root@localhost hadoop]# brctl show ブリッジ名 ブリッジID STP対応インターフェース docker0 8000.0242b47b550d いいえ virbr0 8000.52540092a4f4 はい virbr0-nic [ルート@localhost hadoop]# ブリッジ virbr0 は docker0 とホスト マシンを接続します。ブリッジ上にインターフェース virbr0-nic が作成され、docker0 ネットワークからデータを受信します。コンテナが生成されるたびに、docker0 上に新しいインターフェースが作成され、docker0 のアドレスがコンテナのゲートウェイとして設定されます。 [root@localhost hadoop]# docker run --rm -tdi nvidia/cuda:9.0-base [root@localhost hadoop]# docker ps コンテナID イメージ コマンド 作成ステータス ポート名 9f9c2b80062f nvidia/cuda:9.0-base "/bin/bash" 15秒前 14秒前 quizzical_mcnulty [root@localhost hadoop]# brctl show ブリッジ名 ブリッジID STP対応インターフェース docker0 8000.0242b47b550d いいえ vethabef17b virbr0 8000.52540092a4f4 はい virbr0-nic [ルート@localhost hadoop]# ローカルネットワーク情報を表示する ifconfig -a [root@localhost hadoop]# ifconfig -a docker0: flags=4163<UP、ブロードキャスト、実行中、マルチキャスト> mtu 1500 inet 192.168.0.1 ネットマスク 255.255.240.0 ブロードキャスト 192.168.15.255 inet6 fe80::42:b4ff:fe7b:550d プレフィックス長 64 スコープID 0x20<リンク> ether 02:42:b4:7b:55:0d txqueuelen 0 (イーサネット) RXパケット 37018 バイト 2626776 (2.5 MiB) RXエラー 0 ドロップ 0 オーバーラン 0 フレーム 0 TXパケット 46634 バイト 89269512 (85.1 MiB) TXエラー 0 ドロップ 0 オーバーラン 0 キャリア 0 衝突 0 eno1: flags=4163<UP、BROADCAST、RUNNING、MULTICAST> mtu 1500 inet 192.168.252.130 ネットマスク 255.255.255.0 ブロードキャスト 192.168.252.255 ether 00:25:90:e5:7f:20 txqueuelen 1000 (イーサネット) RXパケット 14326014 バイト 17040043512 (15.8 GiB) RXエラー 0 ドロップ 34 オーバーラン 0 フレーム 0 TXパケット 10096394 バイト 3038002364 (2.8 GiB) TXエラー 0 ドロップ 0 オーバーラン 0 キャリア 0 衝突 0 デバイスメモリ 0xfb120000-fb13ffff eth1: flags=4099<UP、ブロードキャスト、マルチキャスト> mtu 1500 ether 00:25:90:e5:7f:21 txqueuelen 1000 (イーサネット) RXパケット 0 バイト 0 (0.0 B) RXエラー 0 ドロップ 0 オーバーラン 0 フレーム 0 TXパケット 0 バイト 0 (0.0 B) TXエラー 0 ドロップ 0 オーバーラン 0 キャリア 0 衝突 0 デバイスメモリ 0xfb100000-fb11ffff lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 ネットマスク 255.0.0.0 inet6 ::1 プレフィックス長 128 スコープID 0x10<ホスト> ループ txqueuelen 0 (ローカル ループバック) RXパケット 3304 バイト 6908445 (6.5 MiB) RXエラー 0 ドロップ 0 オーバーラン 0 フレーム 0 TXパケット 3304 バイト 6908445 (6.5 MiB) TXエラー 0 ドロップ 0 オーバーラン 0 キャリア 0 衝突 0 oray_vnc: flags=4163<UP、BROADCAST、RUNNING、MULTICAST> mtu 1200 inet 172.1.225.211 ネットマスク 255.0.0.0 ブロードキャスト 172.255.255.255 ether 00:25:d2:e1:01:00 txqueuelen 500 (イーサネット) RXパケット 1944668 バイト 227190815 (216.6 MiB) RXエラー 0 ドロップ 0 オーバーラン 0 フレーム 0 TXパケット 2092320 バイト 2232228527 (2.0 GiB) TXエラー 0 ドロップ 0 オーバーラン 0 キャリア 0 衝突 0 vethabef17b: flags=4163<UP、ブロードキャスト、実行中、マルチキャスト> mtu 1500 inet6 fe80::e47d:4eff:fe87:39d3 プレフィックス長 64 スコープID 0x20<リンク> ether e6:7d:4e:87:39:d3 txqueuelen 0 (イーサネット) RXパケット 0 バイト 0 (0.0 B) RXエラー 0 ドロップ 0 オーバーラン 0 フレーム 0 TXパケット 8バイト 648 (648.0 B) TXエラー 0 ドロップ 0 オーバーラン 0 キャリア 0 衝突 0 virbr0: flags=4099<UP、ブロードキャスト、マルチキャスト> mtu 1500 inet 192.168.122.1 ネットマスク 255.255.255.0 ブロードキャスト 192.168.122.255 ether 52:54:00:92:a4:f4 txqueuelen 0 (イーサネット) RXパケット 0 バイト 0 (0.0 B) RXエラー 0 ドロップ 0 オーバーラン 0 フレーム 0 TXパケット 0 バイト 0 (0.0 B) TXエラー 0 ドロップ 0 オーバーラン 0 キャリア 0 衝突 0 virbr0-nic: flags=4098<ブロードキャスト、マルチキャスト> mtu 1500 ether 52:54:00:92:a4:f4 txqueuelen 500 (イーサネット) RXパケット 0 バイト 0 (0.0 B) RXエラー 0 ドロップ 0 オーバーラン 0 フレーム 0 TXパケット 0 バイト 0 (0.0 B) TXエラー 0 ドロップ 0 オーバーラン 0 キャリア 0 衝突 0 Docker は、ブリッジとルーティング ルールを組み合わせて、同じホスト マシン内のコンテナー間の相互作用を設定します。Docker コンテナー ブリッジ ネットワーク ドライバーでは、ネットワーク アクセス メソッドは次の図に示されています。 コンテナの起動時にポートマッピングが指定されている場合は、内部ポート80をホストポート8080にマッピングします。次のように、0.0.0.0:8080にネットワークカードを指定することもできます。
次に、ルーティング テーブルを確認します。
ルーティング転送ルールが追加されたことがわかります。 [root@localhost hadoop]# iptables -t nat -vnL チェーン PREROUTING (ポリシー ACCEPT 55 パケット、2470 バイト) pkts バイト ターゲット prot オプトイン アウト ソース 宛先 161K 8056K PREROUTING_direct すべて -- * * 0.0.0.0/0 0.0.0.0/0 161K 8056K PREROUTING_ZONES_SOURCE すべて -- * * 0.0.0.0/0 0.0.0.0/0 161K 8056K PREROUTING_ZONES すべて -- * * 0.0.0.0/0 0.0.0.0/0 0 0 DOCKER すべて -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE dst-type LOCAL と一致 チェーン INPUT (ポリシー ACCEPT 0 パケット、0 バイト) pkts バイト ターゲット prot オプトイン アウト ソース 宛先 チェーン出力 (ポリシー ACCEPT 0 パケット、0 バイト) pkts バイト ターゲット prot オプトイン アウト ソース 宛先 3442 258K OUTPUT_direct すべて -- * * 0.0.0.0/0 0.0.0.0/0 0 0 DOCKER すべて -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE は dst-type LOCAL と一致する チェーン POSTROUTING (ポリシー ACCEPT 0 パケット、0 バイト) pkts バイト ターゲット prot オプトイン アウト ソース 宛先 0 0 すべてをマスカレード -- * !docker0 192.168.0.0/20 0.0.0.0/0 0 0 すべてを返す -- * * 192.168.122.0/24 224.0.0.0/24 0 0 すべてを返す -- * * 192.168.122.0/24 255.255.255.255 0 0 マスカレード tcp -- * * 192.168.122.0/24 !192.168.122.0/24 マスカレードポート: 1024-65535 0 0 マスカレード udp -- * * 192.168.122.0/24 !192.168.122.0/24 マスカレードポート: 1024-65535 0 0 すべてをマスカレード -- * * 192.168.122.0/24 !192.168.122.0/24 3442 258K POSTROUTING_direct すべて -- * * 0.0.0.0/0 0.0.0.0/0 3442 258K POSTROUTING_ZONES_SOURCE すべて -- * * 0.0.0.0/0 0.0.0.0/0 3442 258K POSTROUTING_ZONES すべて -- * * 0.0.0.0/0 0.0.0.0/0 0 0 マスカレード tcp -- * * 192.168.0.3 192.168.0.3 tcp dpt:80 チェーン DOCKER (2 件の参照) pkts バイト ターゲット prot オプトイン アウト ソース 宛先 0 0 すべてを返す --docker0 * 0.0.0.0/0 0.0.0.0/0 0 0 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 から:192.168.0.3:80 デフォルトのポート タイプは TCP です。 2. コンテナ間アクセス構成 まず 2 つのコンテナを起動し、コンテナに入り、各コンテナの IP 情報を確認します。 [root@localhost hadoop]# docker ps コンテナID イメージ コマンド 作成ステータス ポート名 462751a70444 nvidia/cuda:9.0-base "/bin/bash" 17 分前 17 分前にアップ 0.0.0.0:8080->80/tcp sad_heyrovsky 9f9c2b80062f nvidia/cuda:9.0-base "/bin/bash" 41 分前 41 分前 quizzical_mcnulty [ルート@localhost hadoop]# ここで2つのコンテナを起動し、docker examine container IDを呼び出してコンテナのIPを表示します。
2つのコンテナは192.168.0.2 192.168.0.3です コンテナーの 1 つに入り、別のマシンに ping を実行します。ping を実行する唯一の方法は、アドレス モード (ping 192.168.0.3) を使用することだということがわかります。
/etc/hosts にエイリアスを追加し、その名前を ping すると、ping できないことがわかります。
その理由については、次の記事で引き続き、この問題を解決するためのユーザー定義ブリッジ ネットワークについて説明します。 上記のDockerとiptables、ブリッジモードネットワーク分離と通信操作の実装に関する記事は、編集者が皆さんと共有する内容のすべてです。参考になれば幸いです。また、123WORDPRESS.COMを応援していただければ幸いです。 以下もご興味があるかもしれません:
|
導入MySQL スロー クエリ ログは、問題のある SQL ステートメントのトラブルシューティングや...
1. 以前のバージョン yum 削除 docker docker-client docker-cli...
私は熟練した DBA になるつもりはありませんが、MySQL を最適化するときは、いくつかの構成を調...
仮想化とコンテナ化は、クラウドベースのプロジェクトでは避けられない 2 つの問題です。仮想化は純粋な...
Web テーブルの構造マークアップについて説明する前に、いくつかの画像を見てみましょう。 HTML ...
問題の原因:スレーブサーバーがクローンマスターサーバーである場合、server-uuidの値は同じで...
<br />作業を簡単に完了できる Web ページ作成ツールは数多くありますが、HTML...
しばらく前にシステムを再インストールしましたが、バックアップを取っていなかったので、コンピューター上...
目次序文プロミスチェーンMDN エラー連鎖デフォルト処理略語非同期待機序文この記事を書いた理由は、ユ...
序文パブリック IP を持つ本番 VPS の場合、必要なポートのみが開かれ、IP とポートを制御する...
システム環境: Ubuntu 16.04LTSこの記事では、6 つの Docker コンテナを使用し...
背景CVE-2021-21972 VMware vCenter における認証されていないコマンド実行...
フロントエンドがインターフェースを要求すると、バックエンドでインターフェースが定義されます。ステータ...
弊社の Web プロジェクトの 1 つでは、新しい都市の増加によりトラフィックと DB 負荷が増加し...
元記事:究極の IE6 チートシート: 25 以上の Internet Explorer 6 のバグ...