linux中的虚拟网卡
容器中会使用linux的虚拟网卡,那么这个虚拟网卡怎么来的?多个容器之间又是怎么通讯的?下面会给出说明。
单独的虚拟网卡
- 创建一个新的网络命名空间net1
- ip netns add net1
- 检查网络空间的link状态
- ip netns exec net1 ip link list
- 创建一对虚拟网卡,将一端添加到net1中
- ip link add veth1 type veth peer name veth1_p
- ip link set veth1 netns net1
- 执行完毕后,veth1将被添加到net1的空间中,在宿主机只能看到veth1_p了
- 分别给这虚拟网卡两端配置上ip地址,然后up起来
- ip addr add 192.168.0.100/24 dev veth1_p
- ip netns exec net1 ip addr add 192.168.0.101/24 dev veth1
- ip link set dev veth1_p up
- ip netns exec net1 ip link set dev veth1 up
- 检查veth1的配置和veth1_p的配置
- ip netns exec net1 ifconfig
- ifconfig
- 检查宿主机到net1中的veth1的通讯
- ip netns exec net1 ping 192.168.0.100 -I veth1
多个虚拟网卡
多个虚拟网卡的操作和单个的步骤是一样的,无非是创建多个网络命名空间,net1,net2,net3等等。但是我们不仅要让宿主机和容器内的虚拟网卡通讯,我们还需要容器之间保证网络通讯,更重要的是我们需要在一个宿主机上面创建大量的网络空间和虚拟网卡,为了简化配置,我们需要使用网桥,将不同的网络空间中的虚拟网卡的一端都挂载在同一个网桥上面,利用网桥的转发功能来实现这些虚拟网卡的通讯。
- 确保安装了网桥工具
- dnf install bridge-utils -y
- apt install bridge-utils -y
- 和创建单个虚拟网卡的过程一样,分别创建veth1,veth1_p和veth2,veth2_p两对虚拟网卡,分别对应两个网络命名空间net1和net2
ip netns add net1 ip link add veth1 type veth peer name veth1_p ip link set veth1 netns net1 ip netns exec net1 ip addr add 192.168.0.101/24 dev veth1 ip netns exec net1 ip link set veth1 up
- 分别配置veth1和veth2的IP地址为192.168.0.101/24,192.168.0.102/24并启用虚拟网卡
- 此时这两个虚拟网卡是各自独立的,互相是不能访问的
ip netns exec net2 ping 192.168.0.101 -I veth2 PING 192.168.0.101 (192.168.0.101) from 192.168.0.102 veth2: 56(84) bytes of data. 2 packets transmitted, 0 received, 100% packet loss, time 1054ms
ip netns exec net1 ping 192.168.0.102 -I veth1 PING 192.168.0.102 (192.168.0.102) from 192.168.0.101 veth1: 56(84) bytes of data. ^C --- 192.168.0.102 ping statistics --- 15 packets transmitted, 0 received, 100% packet loss, time 14363ms
- 开始创建网桥,设定网桥IP,并将p头插入到网桥中
- brctl addbr br0
- ip link set dev veth1_p master br0
- ip link set dev veth2_p master br0
- ip addr add 192.168.0.100/24 dev br0
- 启动插入网桥的p头以及网桥本身
- ip link set veth1_p up
- ip link set veth2_p up
- ip link set br0 up
- 检查网桥状态和虚拟网卡的通讯
- brctl show
bridge name bridge id STP enabled interfaces br0 8000.ca0127d574d8 no veth1_p veth2_p
- ip netns exec net1 ping 192.168.0.102 -I veth1 ```bash ip netns exec net1 ping 192.168.0.102 -I veth1 PING 192.168.0.102 (192.168.0.102) from 192.168.0.101 veth1: 56(84) bytes of data. 64 bytes from 192.168.0.102: icmp_seq=1 ttl=64 time=0.073 ms 64 bytes from 192.168.0.102: icmp_seq=2 ttl=64 time=0.091 ms 64 bytes from 192.168.0.102: icmp_seq=3 ttl=64 time=0.075 ms 64 bytes from 192.168.0.102: icmp_seq=4 ttl=64 time=0.087 ms 64 bytes from 192.168.0.102: icmp_seq=5 ttl=64 time=0.076 ms ^C — 192.168.0.102 ping statistics — 5 packets transmitted, 5 received, 0% packet loss, time 4096ms
- brctl show
``` - 发现已经通了。
- 如果要删除网桥
- 先停用已经启动的接口和网桥
- ip link set veth1_p down
- ip link set veth2_p down
- ip link set br0 down
- 删除网桥
- brctl delbr br0
- 再启用p头,恢复原始状态
- ip set link veth1_p up
- ip set link veth2_p up
- 先停用已经启动的接口和网桥
总结
这下应该清楚,虚拟网卡的目的是为了隔离网络,为容器服务。那么首先要有一个独立的网络命名空间,然后创建出一对虚拟网卡。将其中的一个加入到对应的网络命名空间,然后分别设置对应的IP地址,就可以通过宿主机访问该虚拟网络。
但是此时两个容器之间是不通的。即使你创建出新的虚拟网卡对,加入到同一个网络命名空间中,设定同一段IP地址,也是不通的。
要想容器间通讯,需要增加网桥,并且配置合适的地址。