虚拟网卡
==虚拟网卡(Virtual Network Interface,简称vNIC) 是一种在软件层面模拟的网卡设备,不依赖于物理硬件,而是通过操作系统或虚拟化技术实现网络通信功能。==它允许计算机在虚拟环境中模拟物理网卡的行为,用于连接虚拟网络或与物理网络交互。
核心特点
1.软件模拟
- 通过软件算法模拟物理网卡的功能,如数据包的接收、发送、MAC地址处理等。
- 无需物理硬件支持,可在无物理网卡的设备上运行。
2.灵活配置
- 用户可自由设置虚拟网卡的IP地址、MAC地址、子网掩码等参数。
- 支持动态调整网络配置,适应不同场景需求。
3.跨平台兼容
- 可在Windows、Linux、macOS等操作系统上运行。
- 常见于虚拟机(如VMware、VirtualBox)、容器(如Docker)、云服务(如AWS、Azure)等场景。
虚拟网卡:TUN/TAP
TUN/TAP 是 Linux 内核中提供的两种虚拟网络设备,用于在用户空间程序和内核网络栈之间传输数据。
1.TUN(网络层虚拟设备)
- 工作层次:网络层(第三层)。
- 处理数据:IP 数据包。
- 特点:
模拟一个网络层接口,允许用户空间程序接收和发送 IP 层的数据包。
常用于 VPN 应用,将网络流量从一个远程网络重定向到本地虚拟网络接口。
没有 MAC 地址,仅处理 IP 层数据,无法进行二层操作(如发送 ARP 包或以太网广播)。
2.TAP(链路层虚拟设备)
- 工作层次:数据链路层(第二层)。
- 处理数据:以太网帧。
- 特点:
模拟一个以太网接口,允许用户空间程序发送和接收以太网帧。
通常用于虚拟机网络、桥接网络、虚拟交换机等场景,以模拟完整的二层网络通信。
拥有 MAC 地址,可以处理二层数据帧,支持二层广播和 MAC 层功能。
工作机制
数据传输:数据在用户空间和内核之间通过设备文件(如 /dev/net/tun)传输。
- 用户空间 → 虚拟设备 → 内核网络栈:用户空间程序通过文件描述符将数据(IP 包或以太网帧)写入 TUN/TAP 设备,内核接收到数据后,根据设备类型(TUN 或 TAP)将数据包发送到内核网络栈的对应层。
- 内核网络栈 → 虚拟设备 → 用户空间:当内核网络栈收到外部网络的数据包,并且这些数据包的目标是虚拟网络设备时,内核会将这些数据包发送到 TUN 或 TAP 设备,设备接收到数据后,通过文件描述符将数据传递到用户空间。
VPN应用程序例子
应用程序通过tun设备对外发送数据包后,tun设备就会把数据包通过字符设备发送给VPN应用程序,VPN接收到数据包,重新封装出新的报文;然后通过协议栈发送到物理网卡上;
虚拟网卡tun实战
1.查看当前的物理网卡,eth0就是我们的物理网卡
ifconfig
通过ip link
命令 创建一个虚拟网卡
ip tuntap add dev tun0 mod tun
查看网卡信息,新添加的虚拟网卡默认是DOWN
状态.需要用-a 参数显示
ifconfig -a
激活网卡
ip link set tun0 up
再次通过ifconfig
查看,可以看到网卡状态UP
了;
分配ip地址
ip addr add 10.5.0.1/24 dev tun0
通过ifconfig
进行查看
此时说明我们的虚拟网卡已经添加好了,通过 del 可以删除网卡
ip tuntap del dev tun0 mod tun
虚拟网卡:veth
使用 tun/tap 设备传输数据需要经过两次协议栈,不可避免地会有一定的性能损耗,
所以引入了新的网卡实现方式 veth.
veth(Virtual Ethernet)是一种虚拟网卡设备,在 Linux 内核中实现,用于在两个网络命名空间之间创建点对点连接。
- 成对出现:veth 设备总是成对出现,例如 veth0 和 veth1,它们之间形成一个虚拟的以太网连接。
- 网络命名空间隔离:veth 设备的一端可以放置在一个网络命名空间中,另一端放置在另一个网络命名空间中,从而实现不同命名空间之间的通信。
- 数据传输:从一个 veth 设备发送的数据包会直接传输到其对端的 veth 设备,就像在物理以太网中通过网线连接的两台设备一样。
工作原理
- 内核网络栈处理:veth 设备的数据传输由 Linux 内核的网络栈处理。当一个 veth 设备接收到数据包时,内核会将数据包直接传递给其对端的 veth 设备,而不会经过物理网络接口。
- 高效通信:由于 veth 设备之间的通信在内核中完成,没有物理网络接口的开销,因此通信效率非常高。
虚拟网卡veth实战
查看当前网卡信息
ifconfig
创建两个网络空间
ip netns add ns1ip netns add ns2ip netns list
ns2
ns1
创建一个虚拟网卡对
ip link add veth11 type veth peer name veth12
执行 ifconfig -a
可以看到网卡多了 2 个
将网卡挪到不同的命名空间中
sudo ip link set veth11 netns ns1
sudo ip link set veth12 netns ns2
激活我们的网卡
ip netns exec ns1 ip link set veth11 up
ip netns exec ns2 ip link set veth12 up
设置ip地址
ip netns exec ns1 ip addr add 10.5.0.1/24 dev veth11
ip netns exec ns2 ip addr add 10.5.0.2/24 dev veth12
相互ping一下
ip netns exec ns1 ping 10.5.0.2
ip netns exec ns2 ping 10.5.0.1
删除网络命名空间
ip netns del ns1
ip netns del ns2
弊端:随着网络设备的增多,网络连线的复杂程度将成倍增长。
虚拟交换机
在现实生活中,一台设备往往与多台设备进行通信,路由器很好的解决了这个问题,将设备通过路由器的二层交换,那么设备就能通过路由器IP分配来进行通信;
Linux Bridge
最主要的功能就是二层交换,是对现实的虚拟机进行模拟;
Linux Bridge
,由brctl
命令创建和管理。
实战
创建三个 netns,三对 veth pair,分别一端在 netns 中,另一端连接在网桥上;
新建网络命名空间
root@VM-8-12-ubuntu:~# ip netns add ns1
root@VM-8-12-ubuntu:~# ip netns add ns2
root@VM-8-12-ubuntu:~# ip netns add ns3
创建 veth 对
root@VM-8-12-ubuntu:~# ip link add veth2-ns type veth peer name veth2-br
root@VM-8-12-ubuntu:~# ip link add veth1-ns type veth peer name veth1-br
root@VM-8-12-ubuntu:~# ip link add veth3-ns type veth peer name veth3-br
将 ns 一段的网卡移入到命名空间
root@VM-8-12-ubuntu:~# ip link set dev veth1-ns netns ns1
root@VM-8-12-ubuntu:~# ip link set dev veth2-ns netns ns2
root@VM-8-12-ubuntu:~# ip link set dev veth3-ns netns ns3
启动网卡,并配置 ip,开启本地回环,
root@VM-8-12-ubuntu:~# ip netns exec ns1 ip link set veth1-ns up
root@VM-8-12-ubuntu:~# ip netns exec ns2 ip link set veth2-ns up
root@VM-8-12-ubuntu:~# ip netns exec ns3 ip link set veth3-ns up
root@VM-8-12-ubuntu:~# ip netns exec ns1 ip link set lo up
root@VM-8-12-ubuntu:~# ip netns exec ns2 ip link set lo up
root@VM-8-12-ubuntu:~# ip netns exec ns3 ip link set lo up
root@VM-8-12-ubuntu:~# ip netns exec ns1 ip addr add 10.100.0.11/24 dev veth1-ns
root@VM-8-12-ubuntu:~# ip netns exec ns2 ip addr add 10.100.0.12/24 dev veth2-ns
root@VM-8-12-ubuntu:~# ip netns exec ns3 ip addr add 10.100.0.13/24 dev veth3-ns
测试网络联通性,此时是不通的
root@VM-8-12-ubuntu:~# ip netns exec ns3 ping 10.100.0.11
PING 10.100.0.11 (10.100.0.11) 56(84) bytes of data.
^C
--- 10.100.0.11 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2037ms
创建网桥
root@VM-8-12-ubuntu:~# brctl addbr testbr0
root@VM-8-12-ubuntu:~# ifconfig -a
启动网桥
ip link set testbr0 up
配置ip地址
ip addr add 10.100.0.1/24 dev testbr0
将veth的另一端打开
ip link set veth1-br up
ip link set veth2-br up
ip link set veth3-br up
将veth的另一端与网桥连接上
brctl addif testbr0 veth1-br
brctl addif testbr0 veth2-br
brctl addif testbr0 veth3-br
尝试ping一下
ip netns exec ns3 ping 10.100.0.11
ip netns exec ns2 ping 10.100.0.13
如果发现不能转发,原因是 linux 加入了 bridge_netfilter
。需要开启允许通过:
iptables -A FORWARD -i testbr0 -j ACCEPT
释放空间
ip link del veth1-br
ip link del veth2-br
ip link del veth3-br
ip link del testbr0
ip netns del ns1
ip netns del ns2
ip netns del ns3