[翻译]Macvlan 网络驱动入门

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器镜像服务 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
目录
相关文章
|
1月前
|
机器学习/深度学习 数据采集 人工智能
未来的守护神:AI驱动的网络安全之盾,如何用智慧的光芒驱散网络黑暗势力?揭秘高科技防御系统背后的惊天秘密!
【10月更文挑战第3天】随着网络技术的发展,网络安全问题日益严峻,传统防御手段已显不足。本文探讨了构建AI驱动的自适应网络安全防御系统的必要性及其关键环节:数据采集、行为分析、威胁识别、响应决策和执行。通过Python库(如scapy、scikit-learn和TensorFlow)的应用实例,展示了如何利用AI技术提升网络安全防护水平。这种系统能够实时监控、智能分析并自动化响应,显著提高防护效率与准确性,为数字世界提供更强大的安全保障。
60 2
|
2月前
|
机器学习/深度学习 人工智能 算法
深度学习入门:理解神经网络与反向传播算法
【9月更文挑战第20天】本文将深入浅出地介绍深度学习中的基石—神经网络,以及背后的魔法—反向传播算法。我们将通过直观的例子和简单的数学公式,带你领略这一技术的魅力。无论你是编程新手,还是有一定基础的开发者,这篇文章都将为你打开深度学习的大门,让你对神经网络的工作原理有一个清晰的认识。
|
2月前
|
监控 安全 数据安全/隐私保护
智能家居安全入门:保护你的网络家园
本文旨在为初学者提供一份简明扼要的指南,介绍如何保护自己的智能家居设备免受网络攻击。通过分析智能家居系统常见的安全漏洞,并提供实用的防御策略,帮助读者建立起一道坚固的数字防线。
|
6天前
|
消息中间件 编解码 网络协议
Netty从入门到精通:高性能网络编程的进阶之路
【11月更文挑战第17天】Netty是一个基于Java NIO(Non-blocking I/O)的高性能、异步事件驱动的网络应用框架。使用Netty,开发者可以快速、高效地开发可扩展的网络服务器和客户端程序。本文将带您从Netty的背景、业务场景、功能点、解决问题的关键、底层原理实现,到编写一个详细的Java示例,全面了解Netty,帮助您从入门到精通。
24 0
|
11天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
1月前
|
弹性计算 人工智能 运维
Terraform从入门到实践:快速构建你的第一张业务网络(上)
本次分享主题为《Terraform从入门到实践:快速构建你的第一张业务网络》。首先介绍如何入门和实践Terraform,随后演示如何使用Terraform快速构建业务网络。内容涵盖云上运维挑战及IaC解决方案,并重磅发布Terraform Explorer产品,旨在降低使用门槛并提升用户体验。此外,还将分享Terraform在实际生产中的最佳实践,帮助解决云上运维难题。
123 1
Terraform从入门到实践:快速构建你的第一张业务网络(上)
|
23天前
|
Java
[Java]Socket套接字(网络编程入门)
本文介绍了基于Java Socket实现的一对一和多对多聊天模式。一对一模式通过Server和Client类实现简单的消息收发;多对多模式则通过Server类维护客户端集合,并使用多线程实现实时消息广播。文章旨在帮助读者理解Socket的基本原理和应用。
19 1
|
2月前
|
域名解析 网络协议 应用服务中间件
网络编程入门如此简单(四):一文搞懂localhost和127.0.0.1
本文将以网络编程入门者视角,言简意赅地为你请清楚localhost和127.0.0.1的关系及区别等。
146 2
网络编程入门如此简单(四):一文搞懂localhost和127.0.0.1
|
1月前
|
机器学习/深度学习 PyTorch 算法框架/工具
深度学习入门案例:运用神经网络实现价格分类
深度学习入门案例:运用神经网络实现价格分类
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的卷积神经网络(CNN)入门与实践
【8月更文挑战第62天】本文以浅显易懂的方式介绍了深度学习领域中的核心技术之一——卷积神经网络(CNN)。文章通过生动的比喻和直观的图示,逐步揭示了CNN的工作原理和应用场景。同时,结合具体的代码示例,引导读者从零开始构建一个简单的CNN模型,实现对图像数据的分类任务。无论你是深度学习的初学者还是希望巩固理解的开发者,这篇文章都将为你打开一扇通往深度学习世界的大门。