-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
huangzixun5
committed
Apr 26, 2024
1 parent
08090b7
commit 8620b2f
Showing
1 changed file
with
176 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
--- | ||
title: 常见的容器虚拟网卡驱动 | ||
icon: lightbulb | ||
author: Evilsp | ||
--- | ||
|
||
# Veth-Pair | ||
|
||
Veth-Pair 是最常见的容器虚拟网卡,Veth-Pair 的工作原理可以简单的理解为一根两端为网卡的电缆,其一端的网卡在网络命名空间 A,其另一端的网卡在网络命名空间 B。 | ||
|
||
> 网络命名空间是 Linux 中的一种概念,其具体体现为 Linux 网络资源结构体中的一个名为 net_ns 的成员,其作用是实现逻辑上的本机网络资源分组和隔离 | ||
它的作用由其原理可以简单地得出:即 Veth-Pair 负责将传送到其一端网卡的流量发送到另一端,从另一端的网卡流出,这使得 Veth-Pair 可以用于沟通两个网络命名空间中流动的网络包。 | ||
|
||
由于在容器环境下,有时会有多个容器属于不同的网络命名空间,这时就由 Veth-Pair 来负责沟通它们之间传递的流量,具体方式大致有如下两种: | ||
|
||
1. Veth Pair 的一端在容器网络 ns A,另一端连接到网桥设备上(需要注意的是,Linux 中的网桥设备是网络命名空间无关的,也就是说一旦创建了一个网桥设备,任何网络命名空间的流量都能直接关联到它): | ||
通过这种方式,可以将多个容器网络命名空间通过网桥进行联通,使得它们之间能够通信。除此之外,如果将主网络命名空间也和这个网桥进行联通,那么主机的网络流量包就可以直接被路由到任何一个通过 Veth-Pair 接入到网桥上的容器网络命名空间 | ||
|
||
> 在 Linux 中,网桥设备相当于一个可以自学习的三层交换机 | ||
2. Veth-Pair 的一端在容器网络 ns A,另一端连接到默认网络命名空间: | ||
在这种情况下,通过在默认网络命名空间配置网络规则,可以将来自外部的流量直接路由到 Veth-Pair 的默认网络命名空间端,同时,可以简单地对要进入 Veth-Pair / 从 Veth-Pair 出来的网络流量包做处理 | ||
|
||
Veth-Pair 的一个创建示例: | ||
|
||
``` bash | ||
|
||
# 创建一个 veth 接口对 | ||
ip link add veth0 type veth peer name veth1 | ||
|
||
# 创建一个新的网络命名空间 | ||
ip netns add netns1 | ||
|
||
# 将 veth1 接口移动到新创建的网络命名空间 | ||
ip link set veth1 netns netns1 | ||
|
||
# 配置宿主机侧的接口 | ||
ip addr add 192.168.1.1/24 dev veth0 | ||
ip link set veth0 up | ||
|
||
# 配置网络命名空间侧的接口 | ||
ip netns exec netns1 ip addr add 192.168.1.2/24 dev veth1 | ||
ip netns exec netns1 ip link set veth1 up | ||
|
||
``` | ||
|
||
# IPVlan | ||
|
||
IPVlan 是一种 Linux 网络驱动,它允许你基于单个网络接口创建多个虚拟网络接口。这些虚拟接口共享它们绑定到的那个网络接口的 MAC 地址,但它们可以有不同的 IP 地址。 | ||
|
||
由于 IPVlan 是跨网络命名空间的资源,就和 Veth-Pair 一样,因此这种技术常用于容器化环境,例如 Docker,以便为每个容器提供独立的网络接口。 | ||
|
||
IPVLAN 有三种不同的工作模式:L2 模式、L3 模式和 L3S 模式。下面进行分别阐述: | ||
|
||
## L2 模式 | ||
|
||
在 L2(二层)模式下,IPVLAN 行为类似于传统的以太网交换机。它在 OSI 模型的第二层(数据链路层)操作,这意味着这些处于 L2 模式的 IPVLAN 设备可以接收和响应 ARP(地址解析协议)请求。这允许容器内的虚拟设备像物理设备一样参与到本地网络中。 | ||
|
||
L2 模式有如下优点: | ||
- 性能:L2 模式通常提供较好的性能,因为它减少了对网络流量的处理。 | ||
- 控制:在 L2 模式下,容器的网络流量不会经过主机的 netfilter 链(Linux 内核的包过滤框架),这意味着在默认网络命名空间中不会有额外的网络流量控制。 | ||
|
||
## L3 模式 | ||
|
||
在 L3(三层)模式下,IPVLAN 在 OSI 模型的第三层(网络层)操作。在这种模式下,虚拟设备不会响应 ARP 请求,因此需要在网络上的相关设备上手动配置邻居条目,以识别 IPVLAN 接口的 IP 地址。 | ||
|
||
- 性能:L3 模式可能会降低一些性能,因为它涉及到更多的网络层处理。 | ||
- 控制:在 L3 模式下,容器的出站流量会经过主机的 netfilter 的 POSTROUTING 和 OUTPUT 链,这提供了对出站流量更多的控制。入站流量的处理与 L2 模式相同,即不经过任何 netfilter 模块处理。 | ||
|
||
## L3S 模式 | ||
|
||
L3S 模式是 L3 模式的一个变种,它提供了更加细致的网络流量控制。 | ||
|
||
- 性能:与 L3 模式类似,L3S 模式可能会对性能有一定的影响。 | ||
- 控制:在 L3S 模式下,容器的入站和出站流量都会经过主机的 netfilter 链。这提供了对流量的全面控制,允许管理员对进出容器的网络流量应用复杂的规则和策略。 | ||
|
||
## 总结 | ||
|
||
总结来说,对于 IPVlan 来说,L2 模式更侧重于性能,适用于需要高速网络通信但对流量控制要求不高的场景。L3 模式和 L3S 模式则提供了更多的控制能力,适用于需要精细网络流量管理的环境。选择哪种模式取决于你对性能和控制的具体需求。 | ||
|
||
一个创建示例: | ||
|
||
```bash | ||
|
||
# 如果还没有创建网络命名空间,创建一个新的网络命名空间 ns2 | ||
ip netns add ns2 | ||
# 创建一个ipvlan接口 | ||
ip link add ipvlan1 link eth0 type ipvlan mode l2 | ||
# 将 ipvlan1 接口移动到新的网络命名空间 ns2 | ||
ip link set ipvlan1 netns ns2 | ||
# 在网络命名空间ns2中为ipvlan1接口分配 IP 地址并启用它: | ||
ip netns exec ns2 ip addr add 192.168.1.3/24 dev ipvlan1 | ||
ip netns exec ns2 ip link set ipvlan1 up | ||
|
||
``` | ||
|
||
## 可能的疑问 | ||
1. 如果机器没有连接物理网卡,IPVlan 能够发挥作用吗? | ||
|
||
能,在这种情况下,机器内部的,目标 IP 为 IPVlan 网卡的流量能够正确到达 IPVlan | ||
|
||
2. IPVlan 的父设备一定是一个物理网卡吗? | ||
|
||
不一定,但是如果父设备是一个虚拟网卡,那么该虚拟网卡的出流量应该能够到达本机上的物理网卡 | ||
|
||
3. IPVLAN 的父设备的 Mac 地址一定要继承自一个物理网卡的 Mac 吗? | ||
|
||
不一定,因为可以 Mac 虚拟化,不一定需要使用物理网卡的 Mac | ||
|
||
4. 为什么可以 Mac 虚拟化,不需要使用物理网络接口的 Mac 地址? | ||
|
||
因为交换机的学习策略是:当其检测到一个包从其端口 B 发入时,它就会将该包的源 Mac(这里假设其为 Mac A )和端口 B 绑定。在这之后,发送到交换机的,目标 Mac 为 Mac A 的包都会被发送到端口 B。 | ||
因此,即使这些虚拟网卡发出的包的源 Mac(这里称其为 Mac B )和物理网卡的 Mac(这里称其为 Mac C ) 不同,也不会有任何影响,交换机在学习到这个包的源 Mac 之后,还是会将其和物理网卡所在的端口 B 绑定。这样,无论目标是 Mac B 还是 Mac C 的包都会被发送到物理网卡,进而进入操作系统。操作系统在这之后,将这些包按照目标 Mac 分配到不同的 Linux 网络设备即可 | ||
|
||
# MacVlan | ||
|
||
MacVlan 是一种 Linux 网络驱动,允许你基于单个网络接口创建多个虚拟接口,每个都有自己的 MAC 地址。这使得每个虚拟接口都表现得像是一个独立的网络设备。MacVlan 通常用于容器和虚拟机网络,它们可以利用这种技术在同一物理主机上实现网络隔离和独立的网络栈。 | ||
|
||
其具体原理也很简单,就是创建多个 Linux 网络设备,这些网络设备模仿物理网卡的行为发送网络包,并且各自有自己的 IP 和 Mac。与 IPVlan 相同,MacVlan 也是跨网络命名空间的资源,这使得它也能用于容器网络 | ||
|
||
## Bridge mode (桥接模式) | ||
|
||
这允许所有基于同一设备的 MacVlan 接口能互相通信,这通常用于需要容器间通信的场景。需要注意的是,桥接设备并不创建一个 Linux 网桥设备,这只是一个内部机制 | ||
|
||
## Private mode (私有模式) | ||
|
||
在这种情况下,设置为私有模式的 MacVlan 接口无法与基于同一设备的其他 MacVlan 接口通信,但是它们可以与外部网络通信 | ||
|
||
## VEPA mode (Virtual Ethernet Port Aggregator, 虚拟以太网端口聚合器模式) | ||
|
||
VEPA 模式是一种标准化的网络虚拟化方法,定义在 IEEE 802.1Qbg 中。在 VEPA 模式下,虚拟接口之间的通信不是在本地主机内部处理,而是通过外部交换机进行。这意味着即使通信是在同一宿主机上的虚拟接口之间进行的,数据包也会先被发送到外部交换机,然后交换机再将数据包路由回适当的接收虚拟接口。 | ||
|
||
VEPA 模式的工作原理如下: | ||
|
||
1. 数据包转发:当一个虚拟接口想要与另一个虚拟接口通信时,它会发送一个以太网帧。在正常的局域网通信中,这些帧会在本地处理,但在 VEPA 模式下,这些帧会被发送到宿主机的物理网络接口。 | ||
2. 外部交换机处理:物理网络接口将数据包发送到外部交换机。这个交换机必须支持VEPA或类似的边缘虚拟桥接(EVB)协议。交换机接收到数据包后,不会像在传统局域网中那样仅根据MAC地址表进行转发。 | ||
3. 数据包路由:交换机会根据它的配置,将数据包路由回到发送它的宿主机的正确虚拟接口。这可能涉及到应用安全策略、访问控制列表(ACL)或其他网络策略。 | ||
4. 数据包接收:目标虚拟接口接收从交换机返回的数据包,并将其传递给相应的虚拟机或容器。 | ||
|
||
VEPA 模式的主要优势是可以利用物理交换机的标准化处理和策略,例如 VLANs、访问控制列表 (ACLs) 和其他网络策略。这种模式特别适合需要外部交换机参与流量管理和监控的环境。 | ||
|
||
## Passthrough Mode(透传模式) | ||
|
||
透传模式是一个特殊的 MacVlan 模式,它允许一个单一的虚拟接口继承其父接口的 MAC 地址。这种模式通常用于需要直接控制物理网络接口的场景,例如当你希望一个特定的应用或容器拥有对网络接口的独占访问权时。 | ||
|
||
在透传模式下,由于虚拟接口使用的是父接口的 MAC 地址,它实际上在网络上表现得就像宿主机的物理接口一样。这种模式的缺点是它限制了单个物理接口上可以创建的 MacVlan 接口数量,因为所有的MacVlan 接口都共享同一个 MAC 地址。 | ||
|
||
透传模式通常用于性能敏感的应用,因为它减少了对宿主机网络栈的依赖,从而可能降低了延迟和提高了吞吐量。但是,这种模式也牺牲了灵活性,因为不能在同一物理接口上创建多个独立的虚拟接口。 | ||
|
||
## MacVlan 的缺陷 | ||
|
||
MacVlan 的一个潜在缺点是,由于每个虚拟接口都有自己的 MAC 地址,这可能会导致交换机的 MAC 地址表迅速增长,尤其是在大规模部署时。此外,虚拟接口之间默认是无法相互通信的(除非在桥接模式下),因此需要额外的配置来实现这一点。 | ||
|
||
## MacVlan 的主要用途 | ||
|
||
1. 网络隔离:在同一宿主机上运行的不同容器或虚拟机可以拥有独立的 MAC 地址和 IP 地址,从而在网络层面实现隔离。 | ||
2. 无需桥接:与传统的桥接网络相比,MacVlan 不需要创建和管理 Linux 网桥。虚拟接口直接绑定到物理接口上。 | ||
3. 绕过网桥的限制:在某些环境中,网络策略可能不允许桥接流量。MacVlan 提供了一种绕过这些限制的方法。 | ||
4. 性能:MacVlan 可以提供比传统 Linux 网桥更好的性能,因为它减少了对宿主机 CPU 的依赖,从而减少了上下文切换。 | ||
|
||
一个 MacVlan 的创建示例: | ||
|
||
```bash | ||
|
||
# 首先,创建一个新的网络命名空间 | ||
ip netns add ns1 | ||
# 创建一个 macvlan 接口 | ||
ip link add macvlan1 link eth0 type macvlan mode bridge | ||
# 将 macvlan1 接口移动到新的网络命名空间 ns1 | ||
ip link set macvlan1 netns ns1 | ||
# 在网络命名空间ns1中为macvlan1接口分配 IP 地址并启用它 | ||
ip netns exec ns1 ip addr add 192.168.1.2/24 dev macvlan1 | ||
ip netns exec ns1 ip link set macvlan1 up | ||
|
||
``` |