Dockerコンテナのホスト間マルチネットワークセグメント通信ソリューションの詳細説明

Dockerコンテナのホスト間マルチネットワークセグメント通信ソリューションの詳細説明

1. マックヴラン

前回のブログ投稿で紹介した Docker コンテナのホスト間通信を実現するための Consul サービスの導入など、Docker のホスト間ネットワーク通信を実現するためのソリューションは多数あります。

Macvlanの動作原理:

Macvlan は、Linux カーネルでサポートされているネットワーク インターフェイスです。必要な Linux ビルドは v3.9~3.19 および 4.0+ です。
物理ネットワーク カードに Macvlan サブインターフェイスを作成すると、物理ネットワーク カードは複数の独立した MAC アドレスと IP アドレスを持つことができます。仮想化されたサブインターフェースは、隣接する物理ネットワークに直接公開されます。外から見ると、ネットワーク ケーブルが複数のストランドに分割され、それぞれ異なるホストに接続されているように見えます。
物理ネットワーク カードはパケットを受信すると、受信したパケットの宛先 MAC アドレスに基づいて、パケットを仮想ネットワーク カードに渡す必要があるかどうかを判断します。

コンテナを物理ネットワークに直接接続する必要がある場合は、Macvlan を使用できます。 Macvlan 自体はネットワークを作成しません。本質的には、まずホストの物理ネットワーク カードを「プロミスキャス モード」で動作させ、物理ネットワーク カードの MAC アドレスを無効にして、物理ネットワーク カードがレイヤー 2 ネットワーク内のすべてのトラフィックを受信できるようにします。次のステップは、この物理ネットワーク カード上に仮想ネットワーク カードを作成し、仮想ネットワーク カードに MAC アドレスを割り当てて、1 枚のカードを複数回使用できるようにすることです。物理ネットワークの観点から見ると、各仮想ネットワーク カードは個別のインターフェイスです。

Macvlan を使用する際の注意:

  • コンテナは、IP アドレスの割り当てを担当する物理ネットワークに直接接続されます。これにより、物理ネットワークの IP アドレスが枯渇する可能性があります。もう 1 つの結果は、ネットワーク パフォーマンスの問題です。物理ネットワークに接続されるホストが増えると、ブロードキャスト パケットの割合が急速に増加し、ネットワーク パフォーマンスが低下します。
  • ホスト上のネットワークは「プロミスキャス モード」で動作する必要があります。
  • 前述の通り、プロミスキャスモードで動作する物理ネットワークカードの MAC アドレスは無効になります。そのため、このモードで動作するコンテナは外部ネットワークと通信できませんが、ホストと外部ネットワーク間の通信には影響しません。
  • 長期的には、仮想ネットワークは物理ネットワークから共有されるのではなく分離される必要があるため、ブリッジ ネットワークとオーバーレイ ネットワークの方が適しています。

動作図:


2. 設定例

例 1 (macvlan ベースのコンテナで単一セグメントのホスト間通信を実装する)

結果:

それぞれ Docker サービスを実行している 2 台の CentOS 7.3 マシン。
2 つの Docker サーバーは同じ MacVlan ネットワークを作成するため、Docker サーバー上のコンテナーはホスト間で通信できます。

構成を開始する

1. 最初のDockerサーバーは次のように構成されます

[root@docker01 ~]# ip link set ens33 promisc on # ens33 ネットワーク カードの無差別モードを有効にします [root@docker01 ~]# ip link show ens33 # 表示された情報に red2 で次の単語が含まれていることを確認します: ens33: <BROADCAST,MULTICAST,'PROMISC',UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
  リンク/イーサ 00:0c:29:9f:33:9f brd ff:ff:ff:ff:ff:ff
[root@docker01 ~]# docker network create -d macvlan --subnet 172.22.16.0/24 --gateway 172.22.16.1 -o pa
レンタル=ens33 mac_net1
#macvlan ネットワークを作成し、ゲートウェイ、ネットワーク セグメント、その他の情報を指定します。"-o" は、バインドするネットワーク カードを指定します [root@docker01 ~]# docker run -itd --name test1 --ip 172.22.16.10 --network mac_net1 busybox # 新しく作成した macvlan ネットワークに基づいてコンテナーを実行し、その IP を指定します

実行中のコンテナのIPアドレスを確認する

[root@docker01 ~]# docker exec test1 ip a # IP をチェックし、次の赤い部分が設定どおりであることを確認します: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
  リンク/ループバック 00:00:00:00:00:00 brd 00:00:00:00:00:00
  inet 127.0.0.1/8 スコープ ホスト lo
    valid_lft 永久 preferred_lft 永久
6: eth0@if2: <BROADCAST、MULTICAST、UP、LOWER_UP、M-DOWN> mtu 1500 qdisc noqueue 
  リンク/イーサ 02:42:ac:16:10:0a brd ff:ff:ff:ff:ff:ff
  inet '172.22.16.10/24' brd 172.22.16.255 スコープ グローバル eth0
    valid_lft 永久 preferred_lft 永久

2. 2 番目の Docker サーバーは次のように構成されます (基本的には最初の Docker サーバーと同様です)

[root@docker02 ~]# ip link set ens33 promisc on # プロミスキャスモードを有効にする [root@docker02 ~]# ip link show ens33 
2: ens33: <BROADCAST,MULTICAST,'PROMISC',UP,LOWER_UP> mtu 1500 qdisc pfifo_fast 状態 UP モード DEFAULT グループ デフォルト qlen 1000
  リンク/イーサ 00:0c:29:b5:bc:ed brd ff:ff:ff:ff:ff:ff
[root@docker02 ~]# docker network create -d macvlan --subnet 172.22.16.0/24 --gateway=172.22.16.1 -o parent=ens33 mac_net1
#最初の Docker サーバーと同じネットワーク セグメントとゲートウェイを持つ macvlan を作成します。そしてそれを物理ネットワーク カードにバインドします。
#他の Docker サーバー上の macvlan がこのサーバーと同じネットワーク セグメント内にあることを視覚的に確認するため。そのため、ネットワーク名を同じに設定することをお勧めします。
[root@docker02 ~]# docker run -itd --name test2 --ip 172.22.16.11 --network mac_net1 busybox
#コンテナを実行し、macvlanネットワークに基づいていることを指定します。#IPアドレスが他のdockerサーバーのコンテナIPアドレスと競合しないように注意してください。

実行中のコンテナのIPアドレスを確認する

[root@docker02 ~]# docker exec test2 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
  リンク/ループバック 00:00:00:00:00:00 brd 00:00:00:00:00:00
  inet 127.0.0.1/8 スコープ ホスト lo
    valid_lft 永久 preferred_lft 永久
6: eth0@if2: <BROADCAST、MULTICAST、UP、LOWER_UP、M-DOWN> mtu 1500 qdisc noqueue 
  リンク/イーサ 02:42:ac:16:10:0b brd ff:ff:ff:ff:ff:ff
  inet '172.22.16.11/24' brd 172.22.16.255 スコープ グローバル eth0
    valid_lft 永久 preferred_lft 永久

2番目のDockerサーバーのコンテナtest2を使用して、最初のDockerサーバーのコンテナtest1にpingを実行します。


OK、ホスト間のコンテナ通信は macvlan を通じて実現されます。プロミスキャス モードを使用すると物理ネットワーク カードの MAC アドレスが無効になるため、コンテナーはこのモードを介して外部ネットワークと通信できません。

例 2 (macvlan に基づくマルチセグメント クロスホスト ネットワークのソリューション)

達成された効果は次のとおりです。

  • それぞれ Docker サービスを実行している 2 台の CentOS 7.3 マシン。
  • 各ホストは、コンテナが使用するための 2 つの MacVlan セグメント (172.10.16.0/24 と 172.20.16.0/24) を作成します。
  • 最初の Docker サーバーはコンテナ test1 と test2 を実行し、2 番目の Docker サーバーはコンテナ test3 と test4 を実行します。
  • 最後に、ホスト間で同じネットワーク セグメント内のコンテナーは相互に通信できます。

構成を開始します:

1. 最初のDockerサーバーは次のように構成されます

[root@docker01 ~]# ip link set ens33 promisc on # ens33 ネットワーク カードの無差別モードを有効にする #つまり、ネットワーク カードの複数の仮想インターフェイスを有効にする 
[root@docker01 ~]# ip link show ens33 # 表示される情報に red2 で次の単語が含まれていることを確認します: ens33: <BROADCAST,MULTICAST,'PROMISC',UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
  リンク/イーサ 00:0c:29:9f:33:9f brd ff:ff:ff:ff:ff:ff
[root@docker01 ~]# modinfo 8021q
 # 8021qモジュールがロードされているかどうかを確認します。情報が返された場合は、モジュールがロードされていることを意味します

modinfo 8021qコマンドによって返される情報は次のとおりです。

[root@docker01 ~]# modprobe 8021q #8021qモジュールがロードされていない場合は、このコマンドを実行します [root@docker01 ~]# cd /etc/sysconfig/network-scripts/
[root@docker01 ネットワークスクリプト]# vim ifcfg-ens33 
           ................
BOOTPROTO=manual # この設定項目を「manual」に変更します。これは手動を意味します [root@docker01 network-scripts]# cp -p ifcfg-ens33 ifcfg-ens33.10 # ネットワーク カード設定ファイルをコピーします。-p は元のファイルのプロパティを保持します [root@docker01 network-scripts]# vim ifcfg-ens33.10 
BOOTPROTO=なし 
NAME=ens33.10 #名前の変更に注意してください DEVICE=ens33.10 #名前の変更に注意してください ONBOOT=yes
IPADDR=192.168.10.11 # 仮想ネットワークカードのIPを設定する
プレフィックス=24
ゲートウェイ=192.168.10.2
VLAN=はい
[root@docker01 ネットワークスクリプト]# cp ifcfg-ens33.10 ifcfg-ens33.20 
[root@docker01 ネットワークスクリプト]# vim ifcfg-ens33.20 
BOOTPROTO=なし
名前=ens33.20
デバイス=ens33.20
ONBOOT=はい
IPADDR=192.168.20.10 # ここでのIPはens33.10と同じネットワークセグメントではないことに注意してください PREFIX=24
ゲートウェイ=192.168.20.2
VLAN=はい
[root@docker01 network-scripts]# ifdown ens33;ifup ens33 # 変更を有効にするには、ネットワーク カードを再起動します[root@docker01 network-scripts]# ifup ens33.10 # ネットワーク カードを起動します[root@docker01 network-scripts]# ifup ens33.20 # 起動します[root@docker01 ~]# docker network create -d macvlan --subnet 172.10.16.0/24 --gateway 172.10.16.1 -o parent=ens33.10 mac_net10
#macvlan ネットワークを作成し、ネットワーク セグメントとゲートウェイを定義して、ens33.10 にバインドします。
[root@docker01 ~]# docker network create -d macvlan --subnet 172.20.16.0/24 --gateway 172.20.16.1 -o parent=ens33.20 mac_net20
#macvlan ネットワークを作成し、ネットワーク セグメントとゲートウェイを定義して、ens33.20 にバインドします。
#次に、作成したmacvlanネットワークに基づいてコンテナを実行します

2. 2 番目の Docker サーバーは次のように構成されます (基本的には最初の操作と同様ですが、IP が競合しないように注意してください)

[root@docker02 ~]# ip link set ens33 promisc on # プロミスキャスモードを有効にする [root@docker02 ~]# ip link show ens33 
2: ens33: <BROADCAST,MULTICAST,'PROMISC',UP,LOWER_UP> mtu 1500 qdisc pfifo_fast 状態 UP モード DEFAULT グループ デフォルト qlen 1000
  リンク/イーサ 00:0c:29:b5:bc:ed brd ff:ff:ff:ff:ff:ff
[root@docker02 ~]# modinfo 8021q
返される情報については図1を参照してください。
[root@docker02 ~]# modprobe 8021q #8021qモジュールがロードされていない場合は、このコマンドを実行します [root@docker02 ~]# cd /etc/sysconfig/network-scripts/
[root@docker02 ネットワークスクリプト]# vim ifcfg-ens33 
      ...............#一部のコンテンツを省略 BOOTPROTO=manual    
[root@docker02 network-scripts]# scp [email protected]:/etc/sysconfig/network-scripts/ifcfg-ens33.* . # 末尾の「.」に注意してください。
ifcfg-ens33.10 100% 128 83.4KB/秒 00:00  
ifcfg-ens33.20 100% 124 75.0KB/秒 00:00 
[root@docker02 ネットワークスクリプト]# vim ifcfg-ens33.10 
BOOTPROTO=なし
名前=ens33.10
デバイス=ens33.10
ONBOOT=はい
IPADDR=192.168.10.11 # 最初のIPとの競合を避けるためにIPを変更します PREFIX=24
ゲートウェイ=192.168.10.2
VLAN=はい
[root@docker02 ネットワークスクリプト]# vim ifcfg-ens33.20 

BOOTPROTO=なし
名前=ens33.20
デバイス=ens33.20
ONBOOT=はい
IPアドレス=192.168.20.11
プレフィックス=24
ゲートウェイ=192.168.20.2
VLAN=はい
[root@docker02 network-scripts]# ifdown ens33;ifup ens33 # 設定を有効にするためにネットワーク カードを再起動します [root@docker02 network-scripts]# ifup ens33.10 # ネットワーク カードを起動します [root@docker02 network-scripts]# ifup ens33.20
#次に、最初の docker サーバーによって作成されたネットワークと同じ macvlan ネットワークを作成します [root@docker02 ~]# docker network create -d macvlan --subnet 172.10.16.0/24 --gateway 172.10.16.1 -o parent=ens33.10 mac_net10
[root@docker02 ~]# docker network create -d macvlan --subnet 172.20.16.0/24 --gateway 172.20.16.1 -o parent=ens33.20 mac_net20 
[root@docker02 ~]# docker run -itd --name test3 --network mac_net10 --ip 172.10.16.11 busybox
[root@docker02 ~]# docker run -itd --name test4 --network mac_net20 --ip 172.20.16.21 busybox

この設定を行った後、ping テストを実行できます。設定が正しければ、test3 は test1 と通信できるはずです (両方とも mac_net10 ネットワークに基づいているため)。また、test4 は test2 と通信できるはずです (同様に)。

しかし、test3 と test1 は test4 および test2 と通信できません (同じ仮想 LAN に基づいていないため)。

コンテナ test3 がコンテナ test1 に ping を送信します (注: テストに VMware 仮想マシンを使用する場合、VMware の特性上、ネットワーク アダプタを NAT モードではなく「ブリッジ モード」などに変更する必要があります。そうしないと、通信ができなくなります)


コンテナ test4 がコンテナ test2 テストに ping を送信します。


この時点で、ホスト間ネットワークのマルチセグメントが実装されています。同様に、各コンテナは外部ネットワークと通信できません。忍耐力があれば、公式のDockerドキュメントを読むことをお勧めします。

Dockerコンテナのホスト間マルチセグメント通信ソリューションに関するこの記事はこれで終わりです。Dockerコンテナのホスト間マルチセグメント通信に関するより関連性の高いコンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。皆様、今後とも123WORDPRESS.COMをよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Dockerコンテナ間の通信と外部ネットワーク通信の操作
  • Dockerコンテナの接続と通信の実装
  • Dockerコンテナのホスト間通信におけるダイレクトルーティングの詳細な説明
  • Dockerコンテナがホスト間で通信する方法の詳細な説明
  • Dockerコンテナ間の通信方法の詳細な説明
  • Dockerコンテナ間の通信を実装する方法

<<:  ナビゲーションバーコンポーネントをVueでカプセル化する

>>:  MySQL データベース クエリ パフォーマンス最適化戦略

推薦する

TypeScript インターフェースの紹介

目次1. インターフェース定義2. 属性2.1 オプション属性2.2 読み取り専用プロパティ3. ク...

超詳細なMySQL使用仕様の共有

最近、データベース関連の操作が多くなり、会社の既存の仕様はあまり包括的ではありません。インターネット...

数ステップでサイバーパンク2077風の視覚効果を実現するCSS

背景記事を始める前に、賽博朋克とは何か、賽博朋克2077とは何かを簡単に理解しましょう。サイバーパン...

Nginx の負荷分散構成、ダウンタイム発生時の自動切り替えモード

厳密に言えば、nginx には負荷分散バックエンド ノードのヘルス チェック機能はありませんが、デフ...

MySQL の乗算と除算の精度の不一致の問題 (除算後の小数点以下 4 桁)

質問今日、プロジェクト関数を書いていたとき、金額の統計計算を行い、単位を変換する必要がありました。そ...

CSSは親要素の下の最初の子要素を選択します(:first-child)

序文最近、プロジェクトで :first-child を使用したのですが、すぐに思いつきました。これは...

MySQL ストアド プロシージャの使用例の分析

この記事では、MySQL ストアド プロシージャの使用方法について説明します。ご参考までに、詳細は以...

MySQL 8.0.12 の詳細なインストールおよびアンインストール チュートリアル

1. MySQL 8.0.12 バージョンのインストール手順。 1. ダウンロードhttps://d...

CSS を使用して 3 列レイアウトを実装するサンプル コード。中央の列は適応型で、テキスト サイズに応じて幅が変わります。

Baiduのインタビューで遭遇する質問は、次のレイアウト効果を達成する必要がある。 中央の紫色の列...

Vueは適切なスライドアウトレイヤーアニメーションを実装します

この記事では、適切なスライドアウトレイヤーアニメーションを実装するためのVueの具体的なコードを例と...

DockerがMySQL構成実装プロセスを開始

目次実際の戦闘プロセスまずは主なコマンドと詳細を一つずつ説明しましょう起動が成功したかどうかを確認す...

Docker を使用した SQL Server の実行の実装

現在、.net Core はクロスプラットフォームであり、誰もが Linux と Docker を使...

クラウドサーバーはBaotaを使用してPython環境を構築し、Djangoプログラムを実行します。

目次PagodaをインストールするPythonランタイム環境を構成するPythonをインストールする...

Linux に MySQL 8.0.19 をインストールするための詳細な手順と問題解決方法

最近Tencent Cloudサーバーを購入し、環境を構築しました。このメモは、これまで MySQL...

jsはテーブルドラッグオプションを実装します

この記事の例では、テーブルドラッグオプションを実装するためのjsの具体的なコードを参考までに共有して...