手当たり次第に書くんだ

飽きっぽいのは本能

macvlan / ipvlan はコンテナのための技術なのか – Linux ネットワーク仮想化から CNI まで整理する

macvlan や ipvlan は、Docker や Kubernetes のネットワークを調べていると頻繁に登場します。そのため、コンテナ向けに開発されたネットワーク技術のように見えるかもしれません。

しかし、macvlan と ipvlan の本体は Docker や Kubernetes の機能ではありません。どちらも Linux カーネルが提供する仮想ネットワークデバイスであり、コンテナランタイムを使用しなくても、通常の Linux 環境から作成できます。現在、macvlan / ipvlan がコンテナネットワークで広く利用されているのは、これらの技術が Linux の network namespace と非常に相性がよいためです。

本記事では、macvlan / ipvlan が何を仮想化する技術なのか、なぜコンテナで利用されるようになったのか、さらに Kubernetes、Multus、SR-IOV とはどのような関係にあるのかを整理します。

macvlan / ipvlan の本体は Linux のネットワークデバイス

macvlan と ipvlan は、物理 NIC などのネットワークインターフェースを親として、その上に複数の仮想ネットワークインターフェースを作成する Linux カーネルの機能です。親インターフェースに対して複数の接続点を作成し、それぞれを独立した L2 または L3 のエンドポイントとして扱える点が重要です。

親インターフェース作成される仮想インターフェース設計上の意味
物理 NIC などmacvlan インターフェース仮想インターフェースごとに MAC アドレスを持つ L2 エンドポイントを表現する
物理 NIC などipvlan インターフェース親の MAC アドレスを共有し、IP アドレス単位の接続点を表現する

Linux 上では、コンテナを起動しなくても次のように作成できます。これは説明用の最小例であり、実際には IP アドレス、経路、namespace への移動なども合わせて設計します。

ip link add link eth1 name macvlan0 type macvlan mode bridge
ip link add link eth1 name ipvlan0 type ipvlan mode l2

つまり、macvlan / ipvlan はコンテナランタイムによって実装された機能ではありません。Docker や CNI プラグインは、Linux カーネルが提供するこれらの機能を呼び出し、必要に応じてコンテナの network namespace へ配置しています。

一般的なコンテナネットワークは veth と bridge を使う

Linux コンテナのネットワーク分離は、network namespace によって実現されます。各 network namespace は、独立したネットワークインターフェース、IP アドレス、ルーティングテーブル、ARP / NDP テーブルなどを持ちます。一般的なコンテナネットワークでは、veth ペアと Linux bridge を組み合わせます。

構成要素役割
network namespaceコンテナごとに独立したネットワーク空間を提供する
veth ペアホスト側とコンテナ側をつなぐ仮想ケーブルとして動作する
Linux bridgeホスト内で複数の veth を収容する仮想スイッチとして動作する
物理 NICホスト外の物理ネットワークへ接続する

CNI の bridge プラグインも、この構成を使用します。ホストの network namespace 内に仮想スイッチとなる bridge を作成し、各コンテナへ接続する veth ペアのホスト側を bridge へ収容します。外部ネットワークへの通信方法は、実装や設定によりルーティングまたは IP マスカレードなどが使用されます。

この構成は汎用性が高く、コンテナ間通信やネットワーク分離をホスト側で制御しやすい方式です。一方で、コンテナを既存の物理ネットワークへ直接収容したい場合には、Linux bridge や NAT を経由する構造が必ずしも適しているとは限りません。そこで選択肢になるのが macvlan と ipvlan です。

macvlan は MAC アドレス単位で接続点を分ける

macvlan では、親インターフェース上に作成した仮想インターフェースごとに、独立した MAC アドレスを持たせます。外部スイッチから見ると、1 本の物理ポートの先に複数の異なる MAC アドレスを持つ端末が接続されているように見えます。

インターフェースMAC アドレスの見え方IP アドレスの見え方
macvlan0個別の MAC アドレス個別の IP アドレス
macvlan1個別の MAC アドレス個別の IP アドレス
macvlan2個別の MAC アドレス個別の IP アドレス

Docker の macvlan ドライバーも、各コンテナの仮想インターフェースへ MAC アドレスを割り当て、物理ネットワークへ直接接続されたインターフェースのように見せる仕組みとして説明されています。既存の物理ネットワークとの統合や、直接接続を前提とするアプリケーションなどが主な用途です。

一般的な bridge 構成との違いは、ホスト上にコンテナ収容用の Linux bridge を作らなくても、各コンテナを物理ネットワーク上の独立した L2 エンドポイントとして扱えることです。ただし、外部スイッチはコンテナごとの MAC アドレスを学習する必要があります。コンテナ数が増えれば、スイッチの MAC アドレステーブル、ポートセキュリティ、仮想基盤側の MAC アドレス制限などに影響します。

Docker の公式ドキュメントでも、多数の MAC アドレスがネットワークへ展開される問題や、物理インターフェースで複数 MAC アドレスを扱える必要があることが注意点として挙げられています。クラウド環境では複数 MAC アドレスの使用が制限され、macvlan を利用できない場合もあります。

ipvlan は MAC アドレスを増やさず IP アドレスで分ける

ipvlan も、親インターフェース上に複数の仮想インターフェースを作成します。macvlan との大きな違いは、仮想インターフェースごとに独立した MAC アドレスを割り当てないことです。複数の ipvlan インターフェースは、親インターフェースの MAC アドレスを共有します。

インターフェースMAC アドレスの見え方IP アドレスの見え方
親インターフェース共通の MAC アドレスホスト側の IP アドレス
ipvlan0親と同じ MAC アドレス個別の IP アドレス
ipvlan1親と同じ MAC アドレス個別の IP アドレス

外部ネットワークから見ると、同じ MAC アドレスに複数の IP アドレスが対応します。Linux カーネルは宛先 IP アドレスなどを確認し、どの ipvlan インターフェースへパケットを渡すかを判断します。Docker の公式ドキュメントでも、ipvlan の L2 モードは macvlan に似ているものの、コンテナごとの MAC アドレスを割り当てず、親インターフェースの MAC アドレスを共有する点が主な違いとして説明されています。

そのため、スイッチへ大量の MAC アドレスを学習させたくない場合、1 ポートあたりの MAC アドレス数が制限されている場合、仮想基盤やクラウド環境で複数 MAC アドレスを使用できない場合、または L2 よりも IP アドレスやルーティングを中心に設計したい場合には、ipvlan が有力な選択肢になります。

Linux カーネルの ipvlan には、L2、L3、L3S の各モードがあります。L2 モードでは同一 L2 セグメントへの接続に近い動作をし、L3 モードでは親側の network namespace によるルーティングを中心に通信します。L3 モードでは ipvlan 配下へブロードキャストやマルチキャストが配送されないなど、L2 モードとは異なる制約があります。

macvlan と ipvlan は何を仮想化しているのか

macvlan と ipvlan の違いは、単に「MAC アドレスが違うか同じか」という設定差ではありません。どの単位でネットワーク上のエンドポイントを分離するかという、設計思想の違いとして捉える必要があります。

技術仮想化する接続点外部ネットワークからの見え方
macvlanMAC アドレスを持つ L2 エンドポイント複数の独立した端末
ipvlanIP アドレスを持つ L3 寄りのエンドポイント1 つの MAC アドレスに複数 IP
Linux bridge + vethホスト内の仮想スイッチと接続ポートホスト配下の仮想ネットワーク
SR-IOVNIC のハードウェア機能VF 単位のハードウェア接続点

macvlan は、物理ネットワーク上に複数の L2 端末を表現する技術と考えられます。ipvlan は、親インターフェースの L2 識別子を共有しながら、IP アドレス単位で複数の接続点を表現する技術と考えられます。この違いが、スイッチの MAC 学習、ARP / NDP、ルーティング、ポートセキュリティ、監視、障害解析などに影響します。

参考
書籍
参考書籍

Linux ネットワークと CNI 関連資料を探す

network namespace、仮想ネットワークデバイス、CNI、Kubernetes ネットワークを確認したい場合の検索リンクです。価格、在庫、内容はリンク先で確認してください。

Amazon で見る

このリンクは Amazon アソシエイトリンクです。

なぜコンテナで広く使われるようになったのか

macvlan / ipvlan はコンテナ専用ではありません。しかし、コンテナのネットワーク分離に使用される network namespace との組み合わせが非常に自然です。macvlan または ipvlan で作成したインターフェースを、個別の network namespace へ移動すると、それぞれの namespace は自分専用のネットワークインターフェースを持つように見えます。

コンテナランタイムから見れば、必要な処理は明確です。macvlan または ipvlan インターフェースを作成し、対象コンテナの network namespace へ移動し、IP アドレスとルーティングを設定し、コンテナ終了時にインターフェースを削除します。

  1. 親インターフェースを指定して macvlan または ipvlan インターフェースを作成する。
  2. 作成したインターフェースを対象コンテナの network namespace へ移動する。
  3. コンテナ側で IP アドレス、デフォルトゲートウェイ、ルーティングを設定する。
  4. コンテナ終了時にインターフェースを削除する。

つまり、macvlan / ipvlan がコンテナで使われるようになった理由は、コンテナのためだけに作られたからではありません。Linux の network namespace へ独立したネットワーク接続点を効率よく渡すという要求に、既存の macvlan / ipvlan が適合したためです。

Docker と Kubernetes ではどのように使われるのか

Docker では、macvlan と ipvlan がネットワークドライバーとして提供されています。Docker の通常の bridge ネットワークでは、コンテナはホスト内の仮想 bridge へ接続され、外部からの通信にはポート公開やルーティングなどを使用します。一方、macvlan では、コンテナを物理ネットワーク上の独立した端末のように見せられます。

Kubernetes では、macvlan / ipvlan は CNI プラグインとして使用されます。CNI の macvlan プラグインは、指定された親インターフェースから macvlan インターフェースを作成し、コンテナ側の network namespace へ配置します。ipvlan プラグインも同様に、L2、L3、L3S モードの ipvlan インターフェースを作成します。

ただし、通常の Kubernetes クラスタでは、Pod にはクラスタネットワーク用のインターフェースが 1 つ割り当てられます。CNF などで管理通信用とデータ通信用のネットワークを分離したい場合には、Multus を使用して Pod へ複数のインターフェースを持たせます。

Pod 内のインターフェース主な役割
eth0通常の Kubernetes クラスタネットワーク
net1 などMultus 経由で追加される macvlan / ipvlan / SR-IOV などのネットワーク

ここで重要なのは、Multus 自体が macvlan や ipvlan のデータプレーンを実装しているわけではないことです。Multus は複数の CNI プラグインを呼び分けるメタプラグインであり、実際のインターフェース作成は macvlan CNI、ipvlan CNI、SR-IOV CNI などが担当します。

macvlan のホスト間通信制約

macvlan で特に注意が必要なのが、親インターフェースを持つホストと、その親インターフェース上に作成された macvlan インターフェースとの直接通信です。標準的な構成では、ホストの親インターフェースと macvlan 配下のコンテナは直接通信できません。これは単なるルーティング設定の不足ではなく、Linux カーネル側の macvlan の動作に基づく制約です。Docker の公式ドキュメントでも、この制約が明記されています。

この制約を理解せずに導入すると、外部ノードからは通信できるのに、同じホストからだけ通信できないという分かりにくい状態になります。ホストから macvlan 配下へ通信する必要がある場合は、ホスト側にも同じ親インターフェースを使用する macvlan インターフェースを作成し、そのインターフェースを経由させる方法があります。別の bridge ネットワークをコンテナへ追加し、ホストとの管理通信にはそちらを使用する設計も考えられます。

macvlan / ipvlan は SR-IOV や DPDK の代替ではない

macvlan / ipvlan と SR-IOV は、どちらもコンテナや Pod へ追加インターフェースを与える用途で登場します。しかし、両者が操作しているレイヤーは異なります。macvlan / ipvlan は、Linux カーネル上に仮想ネットワークデバイスを作成します。パケットは原則として Linux カーネルのネットワークスタックを通過します。

SR-IOV では、NIC が持つ Virtual Function を Pod へ割り当てます。VF は NIC のハードウェア資源として提供されるため、macvlan / ipvlan とはインターフェースの生成方法も性能特性も異なります。DPDK はさらに別の技術です。DPDK 対応アプリケーションは、HugePage や専用 CPU、ユーザー空間ドライバーなどを使用し、Linux カーネルの通常のネットワークスタックを迂回してパケットを処理します。

方式主な実装場所カーネルネットワークスタック主な用途
bridge + vethLinux カーネル使用する一般的な Pod 通信
macvlanLinux カーネル使用する既存 L2 ネットワークへの直接収容
ipvlanLinux カーネル使用するMAC 数を抑えた L2 / L3 接続
SR-IOVNIC ハードウェア + ドライバー構成により異なる高性能データプレーン
SR-IOV + DPDKNIC ハードウェア + ユーザー空間原則として迂回高 pps、低遅延処理

したがって、macvlan / ipvlan は SR-IOV の簡易版ではありません。管理系、制御系、一般的なデータ通信には macvlan / ipvlan が適する可能性があります。一方、高い pps 性能や低遅延、CPU 利用効率が要件になるデータプレーンでは、SR-IOV や DPDK を別途検討する必要があります。

macvlan と ipvlan の選択基準

macvlan と ipvlan の選択は、機能の優劣ではなく、物理ネットワークから Pod をどのように見せたいかで決まります。

判断項目macvlanipvlan
Pod ごとに MAC アドレスが必要適する適さない
上位スイッチの MAC 学習を抑えたい適さない適する
既存 L2 ネットワークへ端末として収容したい適するL2 モードで対応可能
ポートあたりの MAC 数制限がある注意が必要適する可能性が高い
L3 ルーティング中心に設計したい主用途ではないL3 / L3S モードを検討
DHCP との親和性個別 MAC を使いやすいDHCP 方式に注意が必要
ホストとの直接通信標準状態では制約ありモードと構成の確認が必要

「macvlan と ipvlan のどちらが高性能か」から選ぶのではなく、Pod 単位の MAC アドレスを上位ネットワークへ見せるのか、Pod の IP アドレスを誰が払い出すのか、上位ネットワークは L2 で収容するのか L3 で経路広告するのか、ホストと Pod の直接通信が必要か、ブロードキャストやマルチキャストが必要か、スイッチや仮想基盤に MAC アドレス数の制約があるかを先に定義する必要があります。

macvlan / ipvlan の選択は、CNI 設定ファイルの書き方ではなく、上位ネットワークとの責任分界を決める設計問題です。

まとめ

macvlan / ipvlan は、現在ではコンテナネットワークで頻繁に利用されています。しかし、コンテナ専用に閉じた技術ではありません。どちらも Linux カーネルが提供する仮想ネットワークデバイスであり、物理 NIC などの親インターフェース上に複数のネットワーク接続点を作成します。

macvlan は、仮想インターフェースごとに異なる MAC アドレスを持たせ、複数の L2 エンドポイントを表現します。ipvlan は、親インターフェースの MAC アドレスを共有し、IP アドレス単位で接続点を分離します。これらのインターフェースを network namespace へ配置できるため、コンテナは独立したネットワークインターフェースを持ち、物理ネットワークへ直接参加できます。この構造がコンテナのネットワーク要件と一致した結果、Docker、CNI、Multus などから広く利用されるようになりました。

したがって、macvlan / ipvlan の本質は「コンテナ用ネットワーク」ではありません。Linux 上で L2 または L3 のネットワークエンドポイントを仮想化し、それを分離された network namespace へ割り当てる技術です。コンテナでの利用は、その仕組みが最も分かりやすく活用されている代表例と位置づけるのが適切です。

参考資料

コンテナとネットワーク設計の関連記事
macvlan / ipvlan はコンテナのための技術なのか – Linux ネットワーク仮想化から CNI まで整理する

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る