[翻译]Macvlan 网络驱动入门

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: Macvlan 网络驱动入门 Macvlan网络驱动是为了在Docker的用户的使用场景中提供一个稳定的,生产可用,高性能的网络驱动。本文翻译自Docker官方的macvlan文档, 原文链接:https://docs.

Macvlan 网络驱动入门


Macvlan网络驱动是为了在Docker的用户的使用场景中提供一个稳定的,生产就绪的网络驱动。目前Libnetwork 允许用户控制IPv4和IPv6地址管理。对于需要将容器网络和底层网络集成的用户来说,VLAN的驱动也允许他们完全控制二层VLAN taggine。而对于使用不依赖于物理网络约束的overlay网络方式部署网络结构的用户,可以参考multi-host overlay 的驱动部署容器的网络。

Macvlan是一种新的网络虚拟化技术。Linux使用非常轻量的方式实现Macvlan,因为Mavlan不使用传统的Linux bridge做隔离和区分,而是直接与Linux的以太网接口或者子接口关联,以实现在物理网络中网络和连接的隔离。

Macvlan提供了很多独特的功能以及为后面更多模式加入的接口。Macvlan中的那些模式的优势在于比较高的网络性能,以及不依赖于Linux Bridge技术,简化虚拟网络的结构。移除了传统的Docker宿主机的网络设备和容器中虚拟网络设备中间的Linux bridge,而使用容器的虚拟网络接口直接挂载到宿主机的网络接口删个。这样在Docker上就可以更加方便的暴漏服务出去,因为这种方式不需要端口映射就可以让外部访问到容器中的服务。

实现准备

  • 下面这个示例中的宿主机是使用Docker 1.12.0以上的版本的单机上测试的。

  • 所有的示例都可以在运行了Docker的宿主机上测试,示例中使用了sub-interface比如eth0.10可以替换成eth0或者别的可用的宿主机上的parent-interface。子接口名字中有.字符的可以即使的自动的被创建。如果不指定-o parent的参数值,就会自动创建一个dummy的接口保证本地宿主机容器的连通性。

  • 内核要求:

  • 使用uname -r命令输出和检查kernel版本
  • 支持Macvlan的kernel版本:v3.9–3.19 和 4.0+

Macvlan Bridge模式使用示例

Macvlan Bridge模式每个容器有一个独立的MAC地址,用于记录宿主机上的MAC地址的端口的映射。

  • Macvlan驱动的网络会被挂载到一个宿主机上的网络接口,例如宿主机的物理网络接口eth0,用于802.1q VLAN tagging的子接口,例如eth0.10(.10表示VLAN 10),或者绑定宿主机的适配器,将两个以太网接口捆绑成一个逻辑接口。

  • 指定的网关是宿主机的外部的基础网络设施提供的网关

  • 每个Macvlan Bridge模式的Docker网络都是相互隔离的,并且一个网络接口不允许多个网络同时挂载。并且理论上一个宿主机的网络适配器最多只能挂载4,094个子接口。

  • macvlan bridge中,同一个子网内的任何一个容器都可以在不需要网关的情况下与别的容器互相通信。
  • docker network命令对于vlan的驱动同样适用
  • 在Macvlan模式下,在不同网络/子网中的容器不能在没有外部路由的情况下互相访问,或者同一个网络拥有多个子网,子网间也是不能在没有外部路由的情况下互相访问。

在下面的示例中,docker宿主机的eth0接口有一个在172.16.86.0/24网络中的IP和默认的网关地址172.16.86.1。这个网关是一个地址是172.16.86.1的外部路由器。对于bridge模式中,宿主机的eth0是不需要配置IP地址的,它仅仅是为了转发到上层网络中的交换机和路由器。

Simple Macvlan Bridge Mode Example

注意 在Macvlan bridge模式中子网的配置需要跟宿主机的接口的配置一致。例如,使用和宿主机以太网接口一直的子网和网关配置,这个网络接口可以通过-o parent=选项指定。

  • 这个例子中我们使用的父接口是eth0并且它在子网172.16.86.0/24的网段上。在docker network中看到的容器需要和-o parent=使用同样的子网配置。网关是一个网络中的外部的路由器,到这个路有器之间没有ip地址伪装和别的代理。
  • 使用网络驱动需要在创建网络时指明-d 驱动名选项,在这个驱动既-d macvlan选项
  • 父接口配置通过-o parent=eth0,如下:
ip addr show eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 172.16.86.250/24 brd 172.16.86.255 scope global eth0

创建macvlan网络,并启动两个容器挂载到这个网络中:

# Macvlan  (-o macvlan_mode= Defaults to Bridge mode if not specified)
docker network create -d macvlan \
    --subnet=172.16.86.0/24 \
    --gateway=172.16.86.1  \
    -o parent=eth0 pub_net

# Run a container on the new network specifying the --ip address.
docker  run --net=pub_net --ip=172.16.86.10 -itd alpine /bin/sh

# Start a second container and ping the first
docker  run --net=pub_net -it --rm alpine /bin/sh
ping -c 4 172.16.86.10

看一下这俩容器的IP和路由表:


ip a show eth0
    eth0@if3: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 46:b2:6b:26:2f:69 brd ff:ff:ff:ff:ff:ff
    inet 172.16.86.2/24 scope global eth0

ip route
    default via 172.16.86.1 dev eth0
    172.16.86.0/24 dev eth0  src 172.16.86.2

# NOTE: the containers can NOT ping the underlying host interfaces as
# they are intentionally filtered by Linux for additional isolation.
# In this case the containers cannot ping the -o parent=172.16.86.250

你可以通过-o mavlan_mode=bridge参数指定bridge模式,如果不指定 You can explicitly specify the bridge mode option -o macvlan_mode=bridge. 而且在不指定是默认也是bridge模式.

虽然在Macvlan模式中父接口eth0并不需要IP地址,但一般接口不会没有IP地址吧,在创建网络的时候如果使用默认的IPAM的话,可以使用--aux-address=x.x.x.x的表示,这样在分配给容器IP地址时就会排除掉指定的IP地址,下面这个例子就是排除了eth0的网络地址的命令:

docker network create -d macvlan \
    --subnet=172.16.86.0/24 \
    --gateway=172.16.86.1  \
    --aux-address="exclude_host=172.16.86.250" \
    -o parent=eth0 pub_net

另外一个默认的Docker IPAM驱动提供的IP地址选取的参数是ip-range=。这个表示了驱动分配IP地址的范围是ip-range的地址段,而不是使用--subnet=的参数的段。例如下面这个例子,IP地址的分配将从192.168.32.128开始分配。

docker network create -d macvlan  \
    --subnet=192.168.32.0/24  \
    --ip-range=192.168.32.128/25 \
    --gateway=192.168.32.254  \
    -o parent=eth0 macnet32

# Start a container and verify the address is 192.168.32.128
docker run --net=macnet32 -it --rm alpine /bin/sh

网络可以通过如下方式删除:

docker network rm <network_name or id>
  • 注意 在Macvlan你不能ping或者联通宿主机的namespace中的IP地址,比如你创建了容器,并试图ping Docker宿主机上的eth0的地址,这个是通的。这个通信由于安全性和隔离性被kernel的内核模块拦截了。

Docker的网络命令可以参考 使用Docker network命令

Macvlan 802.1q Trunk Bridge 模式使用示例

VLAN技术很长时间都被用作数据中心虚拟化网络的解决方案,并且在今天还有很多的使用。VLAN通过一个12位的标签,区分不同的域的方式实现对单个或者多个子网的逻辑的分组。对于网络工程师来说通过VLAN划分网络和配置例如webdb或者其他需要隔离的服务的安全是在正常不过的事了。

目前一个宿主机上需要连接多个虚拟网络是很正常的,Linux网络很早就支持VLAN的标签,它的标准是802.1q,用于管理网络中的数据隔离。可以通过配置连接到Docker宿主机的以太网连接支持802.1q的VLAN ID,以便于创建Linux的子接口,而每个子接口可以用唯一的VLAN ID。

Multi Tenant 802.1q Vlans

众所周知,给Linux宿主机配置802.1q的操作时很复杂和痛苦的,它需要配置一系列的文件,以便于在系统重启后依然能保证配置。如果再引入了网桥的话,物理网卡的接口需要挂载到这个网桥上,然后每个网桥获得IP地址。因为还需要再不同网桥上隔离访问,这样就导致了非常复杂的网络配置。

和其他Docker网络驱动类似,驱动的首要目标即缓解管理网络资源时操作的痛苦。为了那个目的,当一个网络在创建网络的时候收到一个并不存在的子接口作为网络的父接口,那么驱动就会在创建网络的时候创建一个VLAN标记的接口。

当宿主机重启时,这个驱动会在Docker daemon重启的时候重新创建网络的网络接口,而不是修改那些复杂的网络配置文件。如果VLAN的子接口是Docker daemon在docker network create的时候创建的,那么在Docker重启后只会重新创建这个子接口,并在在docker network rm的时候删除这个子接口。

如果用户不希望Docker修改-o parent参数中的子接口,那么用户只简单的需要在这个参数中传入一个已经存在的接口作为网络的父接口。像eth0这样的父接口是不会被删除的,只有那些不是master的接口才能被删除。

这个驱动添加和删除的vlan子接口的格式是interface_name.vlan_tag

例如:eth0.50意思是父接口是eth0,挂载在它上面的一个子接口是eth0.50,并且vlan id是50。这个配置等价到ip link的配置命令是: ip link add link eth0 name eth0.50 type vlan id 50

Vlan ID 50

在Docker的宿主机上创建第一个VLAN标记和隔离的网络,通过在创建网络的时候指定了-o parent=eth0.50指定父接口为vlan id为50的接口eth0.50。这个父接口也可以手动指定别的名字,但如果那样就必须手动通过ip link或者配置文件创建和删除父接口。如果通过-o parent指定的接口存在的话,只要这个接口兼容与Linux 网络接口的标准就可以被使用。

# 现在创建网络挂载到VLAN标记的接口上
docker network  create  -d macvlan \
    --subnet=192.168.50.0/24 \
    --gateway=192.168.50.1 \
    -o parent=eth0.50 macvlan50

# 在两个不同的终端上,启动两个Docker容器,然后两个容器就分别可以ping通另外一个。
docker run --net=macvlan50 -it --name macvlan_test5 --rm alpine /bin/sh
docker run --net=macvlan50 -it --name macvlan_test6 --rm alpine /bin/sh

Vlan ID 60

创建另外一个隔离的,VLAN标记的隔离的网络,通过在创建网络的时候指定了-o parent=eth0.60指定父接口为vlan id为60的接口eth0.60,而macvlan_mode=参数的默认值为macvlan_mode=bridge,可以看到在下面这个示例中有相同的结果。

# 现在创建网络挂载到VLAN标记的接口上
docker network  create  -d macvlan \
    --subnet=192.168.60.0/24 \
    --gateway=192.168.60.1 \
    -o parent=eth0.60 -o \
    -o macvlan_mode=bridge macvlan60

# 在两个不同的终端上,启动两个Docker容器,然后两个容器就分别可以ping通另外一个。
docker run --net=macvlan60 -it --name macvlan_test7 --rm alpine /bin/sh
docker run --net=macvlan60 -it --name macvlan_test8 --rm alpine /bin/sh

例子: 多个子网的 Macvlan 802.1q Trunking

下面的例子除了添加了更多的用户选择的容器子网的绑定外和前面的例子是一样的。在MacVlan/Bridge模式,容器只能ping通同一个子网/广播域,除非有外部的路由去路由不同的子网的网络流量。

### 创建多个L2网络
docker network create -d ipvlan \
    --subnet=192.168.210.0/24 \
    --subnet=192.168.212.0/24 \
    --gateway=192.168.210.254  \
    --gateway=192.168.212.254  \
     -o ipvlan_mode=l2 ipvlan210

# 测试 192.168.210.0/24 容器间连接性
docker run --net=ipvlan210 --ip=192.168.210.10 -itd alpine /bin/sh
docker run --net=ipvlan210 --ip=192.168.210.9 -it --rm alpine ping -c 2 192.168.210.10

# 测试 192.168.212.0/24 容器间连接性
docker run --net=ipvlan210 --ip=192.168.212.10 -itd alpine /bin/sh
docker run --net=ipvlan210 --ip=192.168.212.9 -it --rm alpine ping -c 2 192.168.212.10

多层 IPv4 IPv6 Macvlan Bridge 模式

示例: Macvlan Bridge模式, 802.1q trunk, VLAN ID: 218, 多个子网 构成的多层

# 创建多个子网网段的macvlan网络
docker network  create  -d macvlan \
    --subnet=192.168.216.0/24 --subnet=192.168.218.0/24 \
    --gateway=192.168.216.1  --gateway=192.168.218.1 \
    --subnet=2001:db8:abc8::/64 --gateway=2001:db8:abc8::10 \
     -o parent=eth0.218 \
     -o macvlan_mode=bridge macvlan216

# 在第一个192.168.216.0/24网段创建一个容器
docker run --net=macvlan216 --name=macnet216_test --ip=192.168.216.10 -itd alpine /bin/sh

# 在第二个192.168.218.0/24网段创建容器
docker run --net=macvlan216 --name=macnet216_test --ip=192.168.218.10 -itd alpine /bin/sh

# 通过192.168.216.0/24的网段的容器Ping 在192.168.216.0/24网段中的第一个容器
docker run --net=macvlan216 --ip=192.168.216.11 -it --rm alpine /bin/sh
ping 192.168.216.10

# 通过192.168.218.0/24的网段的容器Ping 在192.168.218.0/24网段中的第一个容器
docker run --net=macvlan216 --ip=192.168.218.11 -it --rm alpine /bin/sh
ping 192.168.218.10

查看其中一个容器的详情:

docker run --net=macvlan216 --ip=192.168.216.11 -it --rm alpine /bin/sh

root@526f3060d759:/# ip a show eth0
    eth0@if92: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/ether 8e:9a:99:25:b6:16 brd ff:ff:ff:ff:ff:ff
    inet 192.168.216.11/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 2001:db8:abc4::8c9a:99ff:fe25:b616/64 scope link tentative
       valid_lft forever preferred_lft forever
    inet6 2001:db8:abc8::2/64 scope link nodad
       valid_lft forever preferred_lft forever

# 指定的IP V4的网关地址是192.168.216.1
root@526f3060d759:/# ip route
  default via 192.168.216.1 dev eth0
  192.168.216.0/24 dev eth0  proto kernel  scope link  src 192.168.216.11

# 指定的IP V6的网关地址是 2001:db8:abc8::10
root@526f3060d759:/# ip -6 route
  2001:db8:abc4::/64 dev eth0  proto kernel  metric 256
  2001:db8:abc8::/64 dev eth0  proto kernel  metric 256
  default via 2001:db8:abc8::10 dev eth0  metric 1024
原文链接:https://docs.docker.com/engine/userguide/networking/get-started-macvlan/#dual-stack-ipv4-ipv6-macvlan-bridge-mode
目录
相关文章
|
2月前
|
存储 监控 安全
单位网络监控软件:Java 技术驱动的高效网络监管体系构建
在数字化办公时代,构建基于Java技术的单位网络监控软件至关重要。该软件能精准监管单位网络活动,保障信息安全,提升工作效率。通过网络流量监测、访问控制及连接状态监控等模块,实现高效网络监管,确保网络稳定、安全、高效运行。
75 11
|
4月前
|
机器学习/深度学习 数据采集 人工智能
未来的守护神:AI驱动的网络安全之盾,如何用智慧的光芒驱散网络黑暗势力?揭秘高科技防御系统背后的惊天秘密!
【10月更文挑战第3天】随着网络技术的发展,网络安全问题日益严峻,传统防御手段已显不足。本文探讨了构建AI驱动的自适应网络安全防御系统的必要性及其关键环节:数据采集、行为分析、威胁识别、响应决策和执行。通过Python库(如scapy、scikit-learn和TensorFlow)的应用实例,展示了如何利用AI技术提升网络安全防护水平。这种系统能够实时监控、智能分析并自动化响应,显著提高防护效率与准确性,为数字世界提供更强大的安全保障。
88 2
|
5月前
|
机器学习/深度学习 人工智能 算法
深度学习入门:理解神经网络与反向传播算法
【9月更文挑战第20天】本文将深入浅出地介绍深度学习中的基石—神经网络,以及背后的魔法—反向传播算法。我们将通过直观的例子和简单的数学公式,带你领略这一技术的魅力。无论你是编程新手,还是有一定基础的开发者,这篇文章都将为你打开深度学习的大门,让你对神经网络的工作原理有一个清晰的认识。
|
2月前
|
JSON Dart 前端开发
鸿蒙应用开发从入门到入行 - 篇7:http网络请求
在本篇文章里,您将掌握鸿蒙开发工具DevEco的基本使用、ArkUI里的基础组件,并通过制作一个简单界面掌握使用
85 8
|
2月前
|
机器学习/深度学习 资源调度 算法
图卷积网络入门:数学基础与架构设计
本文系统地阐述了图卷积网络的架构原理。通过简化数学表述并聚焦于矩阵运算的核心概念,详细解析了GCN的工作机制。
162 3
图卷积网络入门:数学基础与架构设计
|
2月前
|
运维 监控 安全
公司监控软件:SAS 数据分析引擎驱动网络异常精准检测
在数字化商业环境中,企业网络系统面临复杂威胁。SAS 数据分析引擎凭借高效处理能力,成为网络异常检测的关键技术。通过统计分析、时间序列分析等方法,SAS 帮助企业及时发现并处理异常流量,确保网络安全和业务连续性。
61 11
|
2月前
|
Web App开发 网络协议 安全
网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark
Wireshark是一款开源和跨平台的抓包工具。它通过调用操作系统底层的API,直接捕获网卡上的数据包,因此捕获的数据包详细、功能强大。但Wireshark本身稍显复杂,本文将以用抓包实例,手把手带你一步步用好Wireshark,并真正理解抓到的数据包的各项含义。
134 2
|
2月前
|
机器学习/深度学习 人工智能 算法
深度学习入门:用Python构建你的第一个神经网络
在人工智能的海洋中,深度学习是那艘能够带你远航的船。本文将作为你的航标,引导你搭建第一个神经网络模型,让你领略深度学习的魅力。通过简单直观的语言和实例,我们将一起探索隐藏在数据背后的模式,体验从零开始创造智能系统的快感。准备好了吗?让我们启航吧!
100 3
|
3月前
|
数据采集 XML 存储
构建高效的Python网络爬虫:从入门到实践
本文旨在通过深入浅出的方式,引导读者从零开始构建一个高效的Python网络爬虫。我们将探索爬虫的基本原理、核心组件以及如何利用Python的强大库进行数据抓取和处理。文章不仅提供理论指导,还结合实战案例,让读者能够快速掌握爬虫技术,并应用于实际项目中。无论你是编程新手还是有一定基础的开发者,都能在这篇文章中找到有价值的内容。
|
3月前
|
机器学习/深度学习 人工智能 算法框架/工具
深度学习中的卷积神经网络(CNN)入门
【10月更文挑战第41天】在人工智能的璀璨星空下,卷积神经网络(CNN)如一颗耀眼的新星,照亮了图像处理和视觉识别的路径。本文将深入浅出地介绍CNN的基本概念、核心结构和工作原理,同时提供代码示例,带领初学者轻松步入这一神秘而又充满无限可能的领域。