ipvlan macvlan 场景
面试题
Docker 中的 ipvlan 和 macvlan 网络驱动是什么?什么场景下需要使用它们?
标准答案
ipvlan 和 macvlan 是 Docker 的高级网络驱动,它们让容器直接使用物理网络的 IP 地址,绕过 Docker 的 NAT 和网桥机制,适用于对网络性能和直接接入有特殊要求的场景。
macvlan 网络
macvlan 是什么
# macvlan 允许一个物理网卡拥有多个 MAC 地址
# 每个容器获得一个独立的 MAC 地址
# 容器"看起来"像直接连接在物理网络上
# +------------------+ +------------------+
# | 容器 A: eth0 | | 容器 B: eth0 |
# | MAC: 02:42:... | | MAC: 02:42:... |
# | IP: 192.168.1.10| | IP: 192.168.1.11|
# +--------+---------+ +--------+---------+
# | |
# +------------------------+
# |
# 宿主机 eth0(多 MAC)
# |
# 物理交换机
创建和使用 macvlan
# 创建 macvlan 网络
# 需要指定父接口(物理网卡)和子网
docker network create \
--driver macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 \
my-macvlan-net
# 启动容器使用 macvlan
docker run -d \
--network my-macvlan-net \
--ip=192.168.1.100 \
--name web \
nginx
# 容器直接获得了局域网 IP
# 像一台独立的物理机一样被访问
# 不需要 -p 端口映射!
macvlan 的局限
# 1. 宿主机与容器不能直接通信!
# macvlan 模式下,宿主机无法直接访问本机上的 macvlan 容器
# 需要用 macvlan 的子接口或额外的配置
# 2. MAC 地址耗尽
# 每个容器需要一个 MAC 地址
# 某些交换机端口限制 MAC 学习数量
# 3. 需要交换机支持
# 如果物理交换机限制每个端口只能学一个 MAC,走不通
# 验证宿主机无法访问 macvlan 容器
ping 192.168.1.100
# ❌ 不通!这是 macvlan 的已知限制
macvlan 的三种模式
# 1. bridge 模式(默认)
# - 同一宿主机上的容器可以通过 MAC 地址直接通信
# - 最常用
# 2. private 模式
# - 同一宿主机上的容器不能直接通信
# - 即使在同一网络也不行
# 3. passthru 模式
# - 将物理网卡直接交给单个容器
# - 该容器独占物理网卡
docker network create \
--driver macvlan \
-o parent=eth0 \
-o macvlan_mode=private \
my-macvlan-net
ipvlan 网络
ipvlan 是什么
# ipvlan 和 macvlan 类似
# 但所有容器共享物理网卡的 MAC 地址
# 通过不同的 IP 地址来区分
# +------------------+ +------------------+
# | 容器 A: eth0 | | 容器 B: eth0 |
# | IP: 192.168.1.10| | IP: 192.168.1.11|
# | MAC: 相同 | | MAC: 相同 |
# +--------+---------+ +--------+---------+
# | |
# +------------------------+
# |
# 宿主机 eth0(单一 MAC)
# |
# 物理交换机
# 创建 ipvlan 网络
docker network create \
--driver ipvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 \
my-ipvlan-net
# 启动容器
docker run -d \
--network my-ipvlan-net \
--ip=192.168.1.100 \
--name web \
nginx
ipvlan 的模式
# 1. L2 模式(默认)
# - 工作在数据链路层
# - 容器通过父接口的 MAC 通信
# - 与 macvlan bridge 模式类似
docker network create \
--driver ipvlan \
-o ipvlan_mode=l2 \
-o parent=eth0 \
my-ipvlan-l2
# 2. L3 模式
# - 工作在网络层
# - 容器之间的流量经过路由
# - 不依赖 ARP,减少广播
# - 性能更好,但配置更复杂
docker network create \
--driver ipvlan \
-o ipvlan_mode=l3 \
--subnet=192.168.1.0/24 \
--subnet=10.0.0.0/24 \
-o parent=eth0.100 \
my-ipvlan-l3
适用场景对比
| 场景 | macvlan | ipvlan | bridge |
|---|---|---|---|
| 需要独立 MAC 地址 | ✅ 最佳 | ❌ 共享 MAC | ❌ |
| 需要访问宿主机 | ❌ | ✅ | ✅ |
| 大量容器(MAC 数限制) | ❌ | ✅ | ✅ |
| 性能要求极高 | ✅ | ✅ | ❌(有 NAT) |
| 容器直接暴露到物理网络 | ✅ | ✅ | ❌ |
| 一致性哈希负载均衡 | ❌ | ✅(L3) | ❌ |
场景 1:遗留应用直接网络接入
# 场景:旧版应用期望拥有独立 IP
# 使用 ipvlan 让容器获得一个"真"IP 地址
docker network create \
--driver ipvlan \
--subnet=10.0.0.0/24 \
--gateway=10.0.0.1 \
-o parent=eth0 \
direct-net
docker run -d \
--network direct-net \
--ip=10.0.0.100 \
--name legacy-app \
my-legacy-app
# 现在 legacy-app 直接被网络管理员管理
# 像一台物理机一样,其他设备可以直接访问
场景 2:高性能代理
# Nginx 作为高性能反向代理,需要尽量高的网络性能
# 避免 NAT 转换的损耗
docker network create \
--driver macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 \
proxy-net
docker run -d \
--network proxy-net \
--ip=192.168.1.200 \
--name nginx-proxy \
nginx
# 客户端直接通过 192.168.1.200:80 访问
# 没有端口映射的开销
场景 3:多租户网络安全隔离
# 使用 802.1q VLAN 子接口
# 为不同租户创建不同的 ipvlan 网络
# 创建 VLAN 子接口(假设交换机允许 VLAN 100 和 200)
ip link add link eth0 name eth0.100 type vlan id 100
ip link add link eth0 name eth0.200 type vlan id 200
ip link set eth0.100 up
ip link set eth0.200 up
# 为租户 A 创建网络
docker network create \
--driver ipvlan \
--subnet=10.100.0.0/24 \
--gateway=10.100.0.1 \
-o parent=eth0.100 \
tenant-a-net
# 为租户 B 创建网络
docker network create \
--driver ipvlan \
--subnet=10.200.0.0/24 \
--gateway=10.200.0.1 \
-o parent=eth0.200 \
tenant-b-net
# 租户 A 的容器
docker run -d --network tenant-a-net --name app-a my-app
# 租户 B 的容器
docker run -d --network tenant-b-net --name app-b my-app
# 物理隔离:VLAN 在交换机层面隔离
注意事项
# 1. 宿主机不能访问 macvlan 容器
# - 解决方案:创建 macvlan 子接口给宿主机用
sudo ip link add macvlan-host link eth0 type macvlan mode bridge
sudo ip addr add 192.168.1.50/24 dev macvlan-host
sudo ip link set macvlan-host up
# 2. 交换机端口 MAC 学习限制
# - 某些交换机每个端口最多学几个 MAC
# - 如果容器很多,可能触发 MAC 泛洪保护
# 3. 云环境通常不支持
# - 大多数云服务商禁止 MAC 欺骗
# - macvlan/ipvlan 在云 VPC 中无法使用
面试官追问
问:macvlan 和 ipvlan 怎么选?
答:
– 需要独立 MAC 地址?选 macvlan(对兼容性要求极高时)
– 需要大量容器?选 ipvlan(不消耗 MAC 地址)
– 宿主机需要访问容器?选 ipvlan
– 性能敏感且不需要跨 VLAN?选 ipvlan L3 模式
– 在云环境中?都不可用,只能 bridge + NAT
问:macvlan 模式下为什么宿主机不能访问容器?
答:这是 macvlan 的工作机制决定的。宿主机物理网卡有了多个 MAC,收到目标是容器 MAC 的包时,物理网卡不会把它交给宿主机的协议栈(因为 MAC 不匹配)。数据包直接被转到对应的 macvlan 接口。这是设计使然,用 macvlan sub-interface 可以绕过这个限制。
问:生产环境应该优先用哪种网络?
答:绝大多数生产环境仍然使用 bridge 模式(包括自定义 bridge)。macvlan/ipvlan 是特殊场景的补充方案,用于:
1. 遗留系统迁移(原系统绑定 IP 地址)
2. 需要绕过 NAT 的高性能场景
3. 和物理网络深度集成的场景(如 VLAN)
一般容器场景,bridge 网络足够好,而且可移植性强。
总结
macvlan 和 ipvlan 让容器直接暴露在物理网络中,像独立的物理机一样管理和访问。macvlan 每个容器一个 MAC,ipvlan 共享 MAC。它们适用于高性能、直接网络接入或遗留系统迁移等特殊场景。大多数常规场景仍推荐使用 bridge 网络。


暂无评论内容