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 データベース クエリ パフォーマンス最適化戦略

推薦する

Windows SSHサーバーを簡単に構築するためのいくつかの手順

ここで言及されている SSH は Security Shell と呼ばれます。Linux をよく使用...

よく使うLinuxコマンドのまとめ

私は2年間運用保守に携わり、多くのコマンドを使用しました。特定のLinuxコマンドを習得すると、どれ...

Prometheus を使用して、MySQL の自動増分主キーの残りの使用可能パーセンテージをカウントします。

最近、本番環境のデータベースがログデータを狂ったように書き込み、主キー値のオーバーフローを引き起こし...

HTML 描画ユーザー登録ページ

この記事では、HTML描画ユーザー登録ページの具体的な実装コードを参考までに共有します。具体的な内容...

MySQLの文字タイプは大文字と小文字を区別します

デフォルトでは、MySQLの文字タイプは大文字と小文字を区別しません。つまり、name='A...

MySQL マスタースレーブ構成の学習ノート

● 新しいプロジェクトのセキュリティを確保するためにクラウド データを購入する予定でした。 Alib...

Nginx ロードバランシング クラスタの実装

(1)実験環境youxi1 192.168.5.101 ロードバランサーyouxi2 192.168...

Dockerは1行のコマンドでFTPサービス構築の実装を完了します

1行のコマンド docker run -d \ -v /share:/home/vsftpd \ -...

MySQL マルチバージョン同時実行制御メカニズム (MVCC) ソースコードの詳細な説明

目次1. はじめに2. MVCC (マルチバージョン同時実行制御メカニズム) 2.1 繰り返し読み取...

CSSを使用して特別なロゴやグラフィックを実装する

1. はじめに画像は多くのスペースを占め、画像の数が増えるほど管理が難しくなるため、シンプルなラベル...

jQuery カスタム虫眼鏡効果

この記事の例では、jQueryのカスタム虫眼鏡効果の具体的なコードを参考までに共有しています。具体的...

Docker 用ビジュアル UI 管理ツール Portainer のインストールと使用方法の分析

Portainer は、ステータス表示パネル、アプリケーション テンプレートの迅速な展開、コンテナ ...

MySQLとPythonの相互作用の例

目次1. データを準備するデータテーブルを作成するデータの挿入2. SQLドリル1. SQL文の強化...

JavaScript offsetParent のケーススタディ

1. offsetParentの定義: offsetParentは子要素に最も近い位置に配置された親...

ログインフォームを実装するためのJavaScript

この記事の例では、ログインフォームを実装するためのJavaScriptの具体的なコードを参考までに共...