Linux-01-虚拟网络、网络命名空间

虚拟网络

        首先Linux具有丰富的虚拟网络功能,我们先简要介绍几个常用的虚拟网络接口类型:

1. Bridge网桥

        Linux Bridge网桥的行为类似于网络交换机。它在与其连接的接口之间转发数据包。它通常用于在路由器、网关上或在主机上的虚拟机和网络命名空间之间转发数据包。它还支持 STP、VLAN 过滤器和多播侦听。


        当我们想要在虚拟机、容器和主机之间建立网络通道时,可以使用网桥。如上图所示,创建了一个桥接设备br0,并将3个VETH 设备(veth1,veth2,veth3)和一个物理设备(eth0)设置为其从属设备,创建命令示例如下

# ip link add br0 type bridge 
# ip link set veth1 master br0 
# ip link set veth2 master br0 
# ip link set veth3 master br0 
# ip link set eth0 master br0

2. Bonded interface网卡绑定

        Linux Bonded interface网卡绑定提供了一种将多个网络接口聚合为单个逻辑“绑定”接口的方法,有热备或负载平衡等模式。

        当我们想增加服务器网卡速度,或实现网卡硬件高可用时,可以使用网卡绑定。如上图所示,服务器挂载了两块网卡,用热备方式绑定了一个虚拟网卡:

#ip link add bond0 type bond miimon 100 mode active-backup
#ip link set eth0 master bond0
#ip link set eth1 master bond0

 3. VLAN

        VLAN,也称为虚拟LAN,通过向网络数据包添加标签TAG来分隔广播域。VLAN允许网络管理员将主机分组到同一交换机下或不同交换机之间。

        当您想在VM、网络命名空间或主机中分隔子网时,可以考虑使用VLAN。如上图所示,创建命令如下:

# ip link add link eth0 name eth0.1 type vlan id 1
# ip link add link eth0 name eth0.2 type vlan id 2

4.VETH虚拟以太网

         VETH(虚拟以太网)设备是一个本地以太网隧道,设备是成对创建的,在一对设备上的某一端传输的数据包会立即在对端被接收。当任一设备关闭时,该对的链路状态为关闭。

        当网络命名空间需要与主主机命名空间通信或网络命名空间相互通信时,可以使用VETH,如下命令,创建了两个命名空间netns1和netns2以及一对VETH设备,并将一端veth1分配给命名空间netns1,将另一端veth2分配给命名空间netns2。这两个名称空间用此VETH对进行网络连接。

# ip netns add net1
# ip netns add net2
# ip link add veth1 netns net1 type veth peer name veth2 netns net2

        如上示例,再分配一对IP地址,我们就可以在两个命名空间之间ping和通信。示例多次提到网络命名空间,下面我们再介绍网络命名空间。 

网络命名空间

        Linux命名空间namespace被很多开源技术(如Kubernetes,Openstack,Docker)广泛使用或者成为核心技术之一。Linux Namespaces强大之处,是它能提供一种隔离系统全局资源的方法, 通过这个方法,每个namespace都了有一份独立的资源。这样,不同的进程在各自的namespace里对同一种资源的访问不会发生冲突。每个Namespace看上去就像一个单独的Linux系统,与hypervisor技术(如Vmware ESX、vSphere)比较,这是一个轻量级,完全免费的系统虚拟化解决方案。

       其中网络命名空间是非常重要的一项技术,接下来我们通过三个示例来讲解使用方法。

直连互通

 

#!/bin/bash 
set euxo -pipefail 
#创建网络命名空间
ip netns add netns1 
ip netns add netns2
#显示创建的命名空间
ip netns show
#创建一对veth虚拟设备
ip link add veth1 type veth peer name veth2
#把veth虚拟设备两端挂载到各自的命名空间
ip link set veth1 netns netns1
ip link set veth2 netns netns2
#分配ip网络,并启动虚拟设备
ip netns exec  netns1 ip addr add 192.168.10.1/24 dev veth1
ip netns exec  netns2 ip addr add 192.168.10.2/24 dev veth2
ip netns exec  netns1 ip link set dev veth1 up
ip netns exec  netns2 ip link set dev veth2 up

现在我们在netns2命名空间中ping一下veth1看到两个命名空间的网络已经互通:

# ip netns exec netns2 ping 192.168.10.1

PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.

64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=0.050 ms

64 bytes from 192.168.10.1: icmp_seq=2 ttl=64 time=0.024 ms

64 bytes from 192.168.10.1: icmp_seq=3 ttl=64 time=0.029 ms

64 bytes from 192.168.10.1: icmp_seq=4 ttl=64 time=0.028 ms

 

 桥接互通

        如上图示例,两个命令空间通过Bridge网桥进行网络连接,创建过程如下:

#!/bin/bash
set euxo -pipefail
#创建网络命名空间
ip netns add netns1
ip netns add netns2
#显示创建的命名空间
ip netns show
#创建bridge网桥
ip link add br0 type bridge
ip link set dev br0 up
#显示创建的bridge网桥
brctl show 
#创建两对veth虚拟设备
ip link add veth1 type veth peer name veth1-br
ip link add veth2 type veth peer name veth2-br
#把veth1虚拟设备一端挂载到netns1命名空间,另一端作为网桥的从属
ip link set veth1 netns netns1
ip link set veth1-br master br0
#把veth2虚拟设备一端挂载到netns2命名空间,另一端作为网桥的从属
ip link set veth2 netns netns2
ip link set veth2-br master br0
#分配ip网络,并启动虚拟设备
ip netns exec  netns1 ip addr add 192.168.10.1/24 dev veth1
ip netns exec  netns2 ip addr add 192.168.10.2/24 dev veth2
ip netns exec  netns1 ip link set dev veth1 up
ip netns exec  netns2 ip link set dev veth2 up
ip link set veth1-br up
ip link set veth2-br up

 现在我们在netns2命名空间中ping一下veth1看到两个命名空间的网络已经互通:

# ip netns exec netns2 ping 192.168.10.1

PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.

64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=0.037 ms

64 bytes from 192.168.10.1: icmp_seq=2 ttl=64 time=0.029 ms

64 bytes from 192.168.10.1: icmp_seq=3 ttl=64 time=0.028 ms

64 bytes from 192.168.10.1: icmp_seq=4 ttl=64 time=0.029 ms

64 bytes from 192.168.10.1: icmp_seq=5 ttl=64 time=0.029 ms

现在可以实现多个网络命名空间通过网桥互相网络通信,接下来我们看下跟宿主机之间的通信,发现跟宿主机网络无法连通,原因很明显,网络空间外的网络设备并不知道192.168.10.0/24这个网络,网络空间内的网络设备也不知道172.30.52.0/24和8.8.8.8网络。

# ip netns exec netns2 ping 172.30.52.194

connect: Network is unreachable

# ip netns exec netns2 ping 8.8.8.8

connect: Network is unreachable

# ping 192.168.10.1

PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.

^C

桥接NAT

        接上面提到的问题,我们配置能出网的网络互通环境。首先创建过程跟上节一致,创建之后我们查看下路由:

# ip netns exec netns1 route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

192.168.10.0    0.0.0.0         255.255.255.0   U     0      0        0 veth1

# ip netns exec netns2 route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

192.168.10.0    0.0.0.0         255.255.255.0   U     0      0        0 veth2

配置网关和路由

#桥接网络上设置子网的gateway
ip addr add 192.168.10.10/24 dev br0
#在网络空间里添加路由

ip netns exec  netns1 ip route add 172.30.52.0/24 via 192.168.10.10
ip netns exec  netns2 ip route add 172.30.52.0/24 via 192.168.10.10

查看主机路由和尝试ping操作

# ip route

default via 172.30.63.253 dev eth0 

169.254.0.0/16 dev eth0 scope link metric 1002 

172.30.48.0/20 dev eth0 proto kernel scope link src 172.30.52.194 

192.168.10.0/24 dev br0 proto kernel scope link src 192.168.10.10 

# ping 192.168.10.2

PING 192.168.10.2 (192.168.10.2) 56(84) bytes of data.

64 bytes from 192.168.10.2: icmp_seq=1 ttl=64 time=0.023 ms

64 bytes from 192.168.10.2: icmp_seq=2 ttl=64 time=0.077 ms

查看网络命名空间如netns2的路由和尝试ping操作 

# ip netns exec netns2 route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

172.30.52.0     192.168.10.10   255.255.255.0   UG    0      0        0 veth2

192.168.10.0    0.0.0.0         255.255.255.0   U     0      0        0 veth2

# ip netns exec netns2 ping 172.30.52.194

PING 172.30.52.194 (172.30.52.194) 56(84) bytes of data.

64 bytes from 172.30.52.194: icmp_seq=1 ttl=64 time=0.046 ms

64 bytes from 172.30.52.194: icmp_seq=2 ttl=64 time=0.041 ms

64 bytes from 172.30.52.194: icmp_seq=3 ttl=64 time=0.039 ms

# ip netns exec netns2 ping 8.8.8.8

connect: Network is unreachable

可以看到,宿主机有到192.168.10.0/24的路由,所以宿主机能ping通netns2和netns1的网络。而netns1和netns2中都有172.30.52.0/24的路由,所以能ping通宿主机。

 最后一步:访问外网8.8.8.8不通的原因一是因为缺少路由,二是没有设置NAT转发。首先我们添加路由

ip netns exec  netns1 ip route add default via 192.168.10.10
ip netns exec  netns2 ip route add default via 192.168.10.10

然后测试发现不通

# ip netns exec netns2 ping 8.8.8.8

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.

^C

添加NAT转发并打开linux的ipv4 forwarding功能

iptables --table nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE

echo 1 > /proc/sys/net/ipv4/ip_forward

再次测试成功:

# ip netns exec netns2 ping 8.8.8.8

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.

64 bytes from 8.8.8.8: icmp_seq=1 ttl=110 time=42.7 ms

64 bytes from 8.8.8.8: icmp_seq=2 ttl=110 time=42.7 ms

 

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炸裂狸花猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值