Kubernetes

Linux 虚拟网卡网桥操作

1. Linux 网络设备常见操作示例

# 查看激活网卡
ifconfig
# 查看所有网卡
ifconfig -a

# 下线虚拟网卡
ifconfig br-45a70801eb1d down

# 删除虚拟网卡
sudo ip addr del 172.17.0.1 dev vethe9f989b
# 或
sudo tunctl -d vethe9f989b

# 删除虚拟网桥(需先下线)
sudo brctl delbr br-45a70801eb1d

# 将网卡tap0, eth0 移出 bridge(br0)
sudo brctl delif br0 tap0
sudo brctl delif br0 eth0

2. 以 WireGuard 创建 wg0 实现 VPN 通信为例

# 添加 wireguard 类型的虚拟设备 wg0
ip link add dev wg0 type wireguard

# 为虚拟设备 wg0 分配收发网段
ip address add dev wg0 192.168.2.1/24

# 为虚拟设备 wg0 添加对端地址
ip address add dev wg0 192.168.2.1 peer 192.168.2.2

# 配置文件
wg setconf wg0 myconfig.conf

# 设置密钥
wg set wg0 listen-port 51820 private-key /path/to/private-key peer ABCDEF... allowed-ips 192.168.88.0/24 endpoint 209.202.254.14:8172

# 启动虚拟设备 wg0
ip link set up dev wg0

3. 以 VM 同主机通信为例

以这个图来简单说明下,借助 Bridge 来完成同主机两台 VM 的之间的通信流程。首先准备一个 centos 或 ubuntu 虚拟机,然后创建一个 bridge:

ip link add br0 type bridge
ip link set br0 up

然后通过 virt-manager 创建两个 kvm 虚拟机:kvm1 和 kvm2(前提得支持嵌套虚拟化),将它们的 vNIC 挂到 br0 上,如下图:

kvm 虚机会使用 tap 设备作为它的虚拟网卡,我们验证下:

# ps -ef | grep kvm1
libvirt+      3549     1  87 ?        00:22:09 qemu-system-x86_64 -enable-kvm -name kvm1 ... -netdev tap,fd=26,id=hostnet0,vhost=on,vhostfd=28
...

可以看到,其中网络部分参数,-netdev tap,fd=26 表示的就是连接主机上的 tap 设备。

创建的 fd=26 为读写 /dev/net/tun 的文件描述符。

使用 lsof -p 3549 验证下:

# lsof -p 3549
COMMAND    PID USER   FD      TYPE             DEVICE    SIZE/OFF     NODE NAME
qemu-system 3549  libvirt-qemu   26u      CHR             10,200         0t107    135 /dev/net/tun
...

可以看到,PID 为 3549 的进程打开了文件 /dev/net/tun,分配的文件描述符 fd 为 26。

因此,我们可以得出以下结论:在 kvm 虚机启动时,会向内核注册 tap 虚拟网卡,同时打开设备文件 /dev/net/tun,拿到文件描述符 fd,然后将 fd 和 tap 关联,tap 就成了一端连接着用户空间的 qemu-kvm,一端连着主机上的 bridge 的端口,促使两者完成通信。

下面分别给两虚机配上 IP:10.1.1.2/2410.1.1.3/24,ping 一下:

在 bridge 上抓个包看看:

可以看到,br0 上抓到 ping 的 ICMP echo 包和 ARP 包。

  • Bridge 常用使用场景

Bridge 设备通常就是结合 tap/tun、veth-pair 设备用于虚拟机、容器网络里面。这两种网络,在数据传输流程上还有些许不同,我们简单来看下:

首先是虚拟机网络,虚拟机一般通过 tap/tun 设备将虚拟机网卡同宿主机里的 Bridge 连接起来,完成同主机和跨主机的通信。如下图所示:

虚拟机发出的数据包通过 tap 设备先到达 br0,然后经过 eth0 发送到物理网络中,数据包不需要经过主机的的协议栈,效率是比较高的。

其次是容器网络(容器网络有多种引申的形式,这里我们只说 Bridge 网络),容器网络和虚拟机网络类似,不过一般是使用 veth-pair 来连接容器和主机,因为在主机看来,容器就是一个个被隔离的 namespace,用 veth-pair 更有优势。如下图所示:

容器的 Bridge 网络通常配置成内网形式,要出外网需要走 NAT,所以它的数据传输不像虚拟机的桥接形式可以直接跨过协议栈,而是必须经过协议栈,通过 NAT 和 ip_forward 功能从物理网卡转发出去,因此,从性能上看,Bridge 网络虚拟机要优于容器。

  • 总结

Linux Bridge 是虚拟交换机,功能和物理交换机一样,用于连接虚拟机和容器。Bridge 是偏低级的工具,数据中心一般使用更高级工具 Open vSwitch。

留言

您的电子邮箱地址不会被公开。