2026年7月13日
2026年7月13日
MACVLAN の設計手順|使える環境の判定・モード選び・ホストとの通信まで
MACVLAN は、1枚の物理NICの上に独自のMACアドレスを持つ仮想インターフェースを作り、コンテナや仮想環境をLAN上の「別の1台」として見せる Linux カーネルの機能です。手軽に見えますが、動くかどうかはスイッチや仮想化基盤の側で決まり、ホスト自身から通信できないという仕様上の制約もあります。この記事では、MACVLAN を入れる前に決めておくこと(使える環境か、どのモードか、アドレスをどう配るか、ホストとどうつなぐか)を順に整理し、最後に構築と確認の手順を示します。
MACVLAN の仕組みと向いている用途
MACVLAN インターフェースは、親インターフェース(例:eth0)と同じL2セグメントに、別のMACアドレスで参加します。上流のスイッチやルーターからは、ホストとは別の機器がつながっているように見えます。
向いているのは次のような用途です。
- LAN内の固定IPやMACアドレスでの識別を前提にした機器・アプリをコンテナ化したい
- DHCPやmDNSなど、ブロードキャスト・マルチキャストを使うサービスをNATなしで動かしたい
- ネットワーク監視ツールなどを、ポート変換を挟まずにLANへ直接出したい
逆に、Webサーバーのように「特定のポートを外に出せればよい」用途なら、Docker の bridge ネットワークとポート公開で足ります。MACVLAN はLAN側の構成に影響を与える仕組みなので、目的がはっきりしているときに選ぶのが無難です。
手順1:使える環境かを判定する
最初に確かめるべきなのは、親インターフェースの先にあるネットワークが「1つのポートから複数のMACアドレスが出てくること」を許すかどうかです。ここで引っかかると、設定が正しくても通信できません。
- 物理サーバー+自前のスイッチ:通常は動きます。ただし、スイッチでポートセキュリティ(ポートごとに学習できるMACアドレス数の制限)を有効にしている場合は、上限を超えた時点でポートが止まることがあります。
- 仮想マシンの中で使う:仮想スイッチ側の設定次第です。VMware vSphere の標準仮想スイッチでは、セキュリティポリシーの無差別モード(Promiscuous mode)や偽装転送(Forged transmits)を許可しないと、ゲストが作ったMACアドレスのフレームが落とされます。Hyper-V では仮想NICの「MACアドレスのスプーフィング」を有効にする必要があります。KVM/Proxmox の Linux ブリッジは通常そのまま動きます。項目名は製品の版によって異なるため、手元のマニュアルで確認してください。
- パブリッククラウドのVM・多くのVPS:基本的に使えないと考えてください。事業者が割り当てたMACアドレス以外のフレームは配送されないのが一般的です。追加のIPアドレスが必要なら、事業者のセカンダリIPやプライベートネットワークの機能を使います。提供の有無や仕様はサービスごとに異なります(2026年10月現在)。
- Wi-Fi:一般的な無線クライアントは、1つの接続につき1つのMACアドレスしか扱えないため、MACVLAN は動かないことがほとんどです。
MACアドレスを増やせない環境では、MACアドレスを親と共有してIPアドレスだけで区別する IPVLAN が代わりの選択肢になります。
手順2:モードを選ぶ
MACVLAN には動作モードがあり、同じ親を持つ MACVLAN 同士がどう通信するかが変わります。
- bridge:同じ親を持つ MACVLAN 同士が、ホスト内で直接通信できます。もっともよく使われるモードで、Docker の macvlan ドライバーも既定はこのモードです。
- vepa:MACVLAN 同士の通信もいったん外部スイッチへ出し、折り返してもらいます。スイッチ側にヘアピン(同じポートへの折り返し転送)の機能が必要です。
ip linkで mode を指定しないとこのモードになる点に注意してください。 - private:MACVLAN 同士の通信を遮断します。同じホスト上のコンテナ同士を互いに見えなくしたい場合に使います。
- passthru:親インターフェースを1つの MACVLAN に引き渡します。仮想マシンにNICを直接渡すような特殊な用途向けです。
特別な理由がなければ bridge を選び、ip link で作る場合も mode bridge を明示しておくと、意図しない vepa で「コンテナ同士だけ通じない」という事態を避けられます。
手順3:IPアドレスとMACアドレスを計画する
MACVLAN のインターフェースはLANの住人になるので、既存の機器とアドレスが重ならないように計画します。
- DHCPの範囲と分ける:ルーターなどのDHCPサーバーが配る範囲と、MACVLAN 用の範囲を分けます。Docker では
--ip-rangeで、コンテナに割り当てる範囲を絞れます。DHCPサーバー側でもその範囲を除外しておくと安全です。 - 固定IPを台帳に残す:どのコンテナがどのIPを使っているかを記録します。重複すると、ARPの取り合いで通信が不安定になり、原因の特定に時間がかかります。
- MACアドレスの扱い:インターフェースを作り直すとMACアドレスが変わることがあります。DHCPの予約やスイッチ側の設定でMACアドレスを使っている場合は、
ip linkのaddressやdocker run --mac-addressで固定します。 - VLANと組み合わせる:業務用LANと分けたい場合は、親をVLANのサブインターフェース(例:
eth0.20)にします。スイッチ側はそのポートをトランクにして、VLAN 20 を通しておく必要があります。
手順4:ホストとの通信経路を設計する
MACVLAN でもっともつまずくのがこの点です。カーネルの設計上、親インターフェース(ホスト)と、その上の MACVLAN インターフェースは直接通信できません。モードを bridge にしても同じです。LAN上の他の機器からはコンテナに届くのに、ホストからだけ ping が通らない、という症状になります。
ホストからコンテナへ通信する必要がある場合は、ホスト側にも MACVLAN インターフェース(いわゆる shim)を1つ作り、コンテナの範囲への経路をそちらに向けます。
# ホスト用の MACVLAN(bridge モード)を作る
sudo ip link add mvl-shim link eth0 type macvlan mode bridge
sudo ip addr add 192.168.1.250/32 dev mvl-shim
sudo ip link set mvl-shim up
# コンテナに割り当てる範囲(例: 192.168.1.192/27)への経路を shim 経由にする
sudo ip route add 192.168.1.192/27 dev mvl-shim
ホストのアドレス(例:192.168.1.10)とは別のIPを shim に割り当て、そのIPもDHCPの範囲外から選びます。ホストからコンテナに触る必要がないなら、この設定は不要です。必要かどうかを設計段階で決めておくと、後から慌てずに済みます。
手順5:構築して確認する
ip コマンドで試す
まずは一時的な設定で動作を確かめます。再起動で消えるので、検証に向いています。リモートで作業する場合は、親インターフェースの設定を触らないことと、別経路のコンソールを用意しておくことを心がけてください。
sudo ip link add mvl0 link eth0 type macvlan mode bridge
sudo ip addr add 192.168.1.200/24 dev mvl0
sudo ip link set mvl0 up
# モードとMACアドレスを確認
ip -d link show mvl0
# 別のPCから到達できるか(ホスト以外の機器で実行)
ping -c 3 192.168.1.200
Docker で使う
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
--ip-range=192.168.1.192/27 \
-o parent=eth0 \
lan-macvlan
docker run -d --name app --network lan-macvlan --ip 192.168.1.200 nginx:stable
-o parent=eth0.20 のようにVLANのサブインターフェースを指定すると、存在しない場合は Docker が作成します。確認は docker network inspect lan-macvlan で、割り当てられたIPとMACアドレスを見ます。
恒久的な設定にする
ホスト側の shim などを再起動後も残すには、使っているネットワーク管理の仕組みで設定します。systemd-networkd の場合は、.netdev ファイルでインターフェースを定義し、親の .network ファイルに MACVLAN= で紐づけます。
# /etc/systemd/network/25-mvl-shim.netdev
[NetDev]
Name=mvl-shim
Kind=macvlan
[MACVLAN]
Mode=bridge
# 親インターフェースの .network ファイル(例: /etc/systemd/network/10-eth0.network)の [Network] に追記
MACVLAN=mvl-shim
shim 用のアドレスと経路は、mvl-shim 用の .network ファイルに書きます。NetworkManager を使う環境では nmcli connection add type macvlan で同様の設定ができます。設定ファイルを変更する前に、元のファイルを控えておいてください。
つまずきやすい症状と確認方法
- LAN上のどこからも届かない:手順1の環境の制約を疑います。親インターフェースで
sudo tcpdump -e -n -i eth0 host 192.168.1.200を実行し、ARPの要求と応答が出ているかを見ます。要求は出ているのに応答が返らない場合は、仮想スイッチやスイッチのポートセキュリティでフレームが落とされている可能性があります。 - ホストからだけ届かない:仕様どおりの動作です。手順4の shim を設定します。
- コンテナ同士だけ届かない:モードが vepa や private になっていないかを
ip -d link showで確認します。 - ときどき通信が途切れる:IPアドレスの重複を疑います。別の機器から
arpingで同じIPに複数のMACアドレスが応答していないかを確かめます。
まとめ
- MACVLAN は仮想インターフェースに独自のMACアドレスを持たせ、LANに直接参加させる仕組み。動くかどうかは上流のスイッチや仮想化基盤が複数のMACアドレスを許すかで決まる
- クラウドのVM、多くのVPS、Wi-Fi では基本的に使えない。MACアドレスを増やせない環境では IPVLAN を検討する
- モードは特に理由がなければ bridge を明示する
- DHCPの範囲と分け、固定IPとMACアドレスを台帳で管理する
- ホストと MACVLAN は直接通信できないため、必要なら shim インターフェースと経路を用意する