Macvlan 网络

Macvlan 是一种网络驱动,允许容器直接连接到物理网络接口,并为每个容器分配独立的 MAC 地址。这使得容器在网络上表现为独立的物理设备,能够直接与外部网络通信。

Macvlan 网络允许 Docker 容器直接连接到物理网络,每个容器都有自己的 MAC 地址,从而在网络上表现为独立的物理设备。与传统的桥接网络相比,Macvlan 提供了更高的网络性能和更低的延迟,因为它避免了额外的网络层开销。此外,Macvlan 网络支持多种模式,包括桥接模式、私有模式和 VEPA 模式,每种模式适用于不同的网络环境和需求。

Macvlan 网络的优势

  1. 高性能:避免了传统桥接网络的额外开销,提供更低的延迟和更高的吞吐量。
  2. 隔离性:每个容器拥有独立的 MAC 地址,网络流量完全隔离。
  3. 灵活性:支持多种模式(桥接模式、私有模式、VEPA 模式),适用于不同的网络场景。

Macvlan 网络的工作模式

  1. 桥接模式(Bridge Mode)

    • 容器与物理网络接口处于同一子网。
    • 容器可以直接与外部网络通信。
    • 适用于单主机环境。
  2. 私有模式(Private Mode)

    • 容器之间可以通信,但不能与外部网络通信。
    • 适用于需要容器间隔离的场景。
  3. VEPA 模式(Virtual Ethernet Port Aggregator Mode)

    • 容器之间的通信需要通过外部交换机。
    • 适用于多主机环境。

创建 Macvlan 网络的步骤

1. 确认物理网络接口

在创建 Macvlan 网络之前,需要确认主机上的物理网络接口名称。可以通过以下命令查看:

ip link show

输出示例:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:xx:xx:xx brd ff:ff:ff:ff:ff:ff

在本例中,物理网络接口为 eth0

2. 创建 Macvlan 网络

使用以下命令创建 Macvlan 网络:

docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  --ip-range=192.168.1.128/25 \
  -o parent=eth0 \
  macvlan_network

参数说明:

  • -d macvlan:指定网络驱动为 Macvlan。
  • --subnet:指定子网范围。
  • --gateway:指定网关地址。
  • --ip-range:指定 IP 地址范围。
  • -o parent=eth0:指定物理网络接口。

3. 启动容器并连接到 Macvlan 网络

使用以下命令启动容器并连接到 Macvlan 网络:

docker run -d --name=macvlan_container \
  --network=macvlan_network \
  nginx

4. 验证网络配置

通过以下命令查看容器的网络配置:

docker exec macvlan_container ip addr show

输出示例:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 00:0c:29:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.129/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever

可以看到,容器已成功分配到指定的 IP 地址,并直接连接到物理网络。

常见问题及解决方案

1. 容器无法访问外部网络

原因:可能是网关配置错误或物理网络接口不支持 Macvlan。

解决方案

  • 检查网关配置是否正确。
  • 确认物理网络接口支持 Macvlan。

2. 容器之间无法通信

原因:可能是网络模式配置错误。

解决方案

  • 确保使用桥接模式或 VEPA 模式。
  • 检查防火墙规则是否阻止了容器间的通信。

3. IP 地址冲突

原因:IP 地址范围配置错误。

解决方案

  • 重新配置 --ip-range 参数,确保 IP 地址不冲突。

最佳实践

  1. 选择合适的模式

    • 单主机环境使用桥接模式。
    • 多主机环境使用 VEPA 模式。
  2. 合理分配 IP 地址

    • 使用 --ip-range 参数避免 IP 地址冲突。
  3. 监控网络性能

    • 使用工具(如 cAdvisorPrometheus)监控容器网络性能。
  4. 安全性配置

    • 使用防火墙规则限制容器访问外部网络。
    • 启用网络策略控制(如 CalicoCilium)。