Linux 虚拟网络基础---namespace、veth pair、bridge 说明和命令实操

98 篇文章 1 订阅
82 篇文章 3 订阅

namespace

前言

namespace是Linux虚拟网络的一个重要概念,传统的Linux的许多资源是全局的,如果进程id资源。而namespace的目的首先就是讲这些资源做资源隔离。Linux可以在一个Host内创建许多namespace,于是那些原本是linux的全局资源,就变成了namespace范围内的“全局”资源,而且不同namespace的资源相互不可见,彼此透明。

Linux namespace 可以隔离的资源有:uts_ns(内存、版本等底层信息)、ipc_ns(所有与进程通信的信息)、 mnt_ns(当前装载的文件系统)、 pid_ns(有关进程id的信息)、 user_ns(资源配额的信息)、 net_ns(网络信息)。

一个设备(Linux Device)只能位于一个namespace中,不同namespace中的设备可以利用veth pair进行桥接。

命令实操

Linux 操作namespace的命令是ip netns。

[root@virtual ~]# ip netns help
Usage: ip netns list
       ip netns add NAME
       ip netns set NAME NETNSID
       ip [-all] netns delete [NAME]
       ip netns identify [PID]
       ip netns pids NAME
       ip [-all] netns exec [NAME] cmd ...
       ip netns monitor
       ip netns list-id
[root@virtual ~]# 

首先创建一个namespace:

# 查看namespace列表
[root@virtual ~]# ip netns list 
[root@virtual ~]# 
# 新增 namespace ns_test
[root@virtual ~]# ip netns add ns_test
[root@virtual ~]# 
[root@virtual ~]# ip netns list
ns_test
[root@virtual ~]# 

当创建一个namespace后,就可以将一些虚拟设备迁移到这个namespace中去了,比如上一篇中介绍的tap。

# 创建tap,并配置对应IP,详细信息可看上一篇文档
[root@virtual ~]# tunctl -t tap_test
Set 'tap_test' persistent and owned by uid 0
[root@virtual ~]# ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ff
3: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
    link/ether 2e:5c:3f:10:63:12 brd ff:ff:ff:ff:ff:ff
[root@virtual ~]# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.176/24 brd 10.0.0.255 scope global noprefixroute dynamic eth0
       valid_lft 75898sec preferred_lft 75898sec
    inet6 fe80::f816:3eff:fe56:6a87/64 scope link 
       valid_lft forever preferred_lft forever
3: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 2e:5c:3f:10:63:12 brd ff:ff:ff:ff:ff:ff
[root@virtual ~]# ip addr add local 10.0.0.190/24 dev tap_test
[root@virtual ~]# ip a show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.176/24 brd 10.0.0.255 scope global noprefixroute dynamic eth0
       valid_lft 75813sec preferred_lft 75813sec
    inet6 fe80::f816:3eff:fe56:6a87/64 scope link 
       valid_lft forever preferred_lft forever
3: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 2e:5c:3f:10:63:12 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.190/24 scope global tap_test
       valid_lft forever preferred_lft forever
[root@virtual ~]#
# 创建namespace后,将前面创建的tap_test迁移到这个namespace中。
# 迁移之后,在外直接 ip a s 已经看不到这个虚拟设备了
[root@virtual ~]# 
[root@virtual ~]# ip link set tap_test netns ns_test
[root@virtual ~]# 
[root@virtual ~]# ip netns exec ns_test ip a s
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 2e:5c:3f:10:63:12 brd ff:ff:ff:ff:ff:ff
[root@virtual ~]# ip netns exec ns_test ip addr add 192.168.10.190/24 dev tap_test
[root@virtual ~]# ip netns exec ns_test ip a s
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 2e:5c:3f:10:63:12 brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.190/24 scope global tap_test
       valid_lft forever preferred_lft forever
[root@virtual ~]#  

veth pair

前言

veth pair 不是一个设备,而是一对设备,以连接两个虚拟以太端口。操作veth pair,需要跟namespace一起配合,不然就没有意义。

简单的拓扑图:

两个namespace ns1/ns2 中各有一个tap组成veth pair,两个tap 上配置的ip进行互ping。

命令实操

# 创建 veth pair
[root@virtual ~]# ip link add tap1 type veth peer name tap2 
[root@virtual ~]# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.176/24 brd 10.0.0.255 scope global noprefixroute dynamic eth0
       valid_lft 64021sec preferred_lft 64021sec
    inet6 fe80::f816:3eff:fe56:6a87/64 scope link 
       valid_lft forever preferred_lft forever
6: tap2@tap1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether a6:74:e9:cb:8f:f1 brd ff:ff:ff:ff:ff:ff
7: tap1@tap2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 02:d1:8c:8b:44:e9 brd ff:ff:ff:ff:ff:ff
[root@virtual ~]# 

# 创建namespace,并将tap迁移至namespace中:

[root@virtual ~]# ip netns add ns1
[root@virtual ~]# ip netns add ns2
[root@virtual ~]# ip link set tap1 netns ns1
[root@virtual ~]# ip link set tap2 netns ns2
[root@virtual ~]# ip netns exec ns1 ip addr add local 192.168.10.200/24 dev tap1
[root@virtual ~]# ip netns exec ns2 ip addr add local 192.168.10.201/24 dev tap2
[root@virtual ~]# ip netns exec ns1 ifconfig tap1 up
[root@virtual ~]# ip netns exec ns2 ifconfig tap2 up
[root@virtual ~]# 
[root@virtual ~]# ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ff
[root@virtual ~]# ip netns list
ns2
ns1 (id: 0)
ns_test
[root@virtual ~]# 
[root@virtual ~]# ip netns exec ns1 ping 192.168.10.201
PING 192.168.10.201 (192.168.10.201) 56(84) bytes of data.
64 bytes from 192.168.10.201: icmp_seq=1 ttl=64 time=0.028 ms
64 bytes from 192.168.10.201: icmp_seq=2 ttl=64 time=0.027 ms
64 bytes from 192.168.10.201: icmp_seq=3 ttl=64 time=0.026 ms
64 bytes from 192.168.10.201: icmp_seq=4 ttl=64 time=0.023 ms
^C
--- 192.168.10.201 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.023/0.026/0.028/0.002 ms
[root@virtual ~]# ip netns exec ns1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
7: tap1@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 02:d1:8c:8b:44:e9 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet 192.168.10.200/24 scope global tap1
       valid_lft forever preferred_lft forever
    inet6 fe80::d1:8cff:fe8b:44e9/64 scope link 
       valid_lft forever preferred_lft forever
[root@virtual ~]# ip netns exec ns2 ip a s
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
6: tap2@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether a6:74:e9:cb:8f:f1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.10.201/24 scope global tap2
       valid_lft forever preferred_lft forever
    inet6 fe80::a474:e9ff:fecb:8ff1/64 scope link 
       valid_lft forever preferred_lft forever
[root@virtual ~]# 

通过以上的测试用例,可以了解通过veth pair连接两个namespace的方法。

后面会有依靠Bridge/Switch 实现三个或多个namespace进行互通。

Bridge

前言

在Linux的语境中,Bridge和Switch是一个概念。Bridge是一个虚拟网络设备,所以具有网络设备的特征,可以配置IP、MAC地址等;Bridge是一个虚拟交换机,和物理交换机有类似的功能。对于普通的网络设备来说,只有两端,从一端进来的数据会从另一端出去,如物理网卡从外面网络中收到的数据会转发给内核协议栈,而从协议栈过来的数据会转发到外面的物理网络中。 而Bridge不同,Bridge有多个端口,数据可以从任何端口进来,进来之后从哪个口出去和物理交换机的原理差不多,要看mac地址。

命令实操

Linux实现Bridge功能是brctl模块。可以直接在命令行上查看,如果没有回显的话,可直接使用yum进行安装。

[root@virtual ~]# brctl
-bash: brctl: command not found
[root@virtual ~]# yum -y install bridge-utils
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
......
Running transaction
  Installing : bridge-utils-1.5-9.el7.x86_64                                                                                           1/1 
  Verifying  : bridge-utils-1.5-9.el7.x86_64                                                                                           1/1 

Installed:
  bridge-utils.x86_64 0:1.5-9.el7                                                                                                          

Complete!
[root@virtual ~]# brctl
Usage: brctl [commands]
commands:
    addbr       <bridge>        add bridge
    delbr       <bridge>        delete bridge
    addif       <bridge> <device>   add interface to bridge
    delif       <bridge> <device>   delete interface from bridge
    hairpin     <bridge> <port> {on|off}    turn hairpin on/off
    setageing   <bridge> <time>     set ageing time
    setbridgeprio   <bridge> <prio>     set bridge priority
    setfd       <bridge> <time>     set bridge forward delay
    sethello    <bridge> <time>     set hello time
    setmaxage   <bridge> <time>     set max message age
    setpathcost <bridge> <port> <cost>  set path cost
    setportprio <bridge> <port> <prio>  set port priority
    show        [ <bridge> ]        show a list of bridges
    showmacs    <bridge>        show a list of mac addrs
    showstp     <bridge>        show bridge stp info
    stp         <bridge> {on|off}   turn stp on/off
[root@virtual ~]# 

根据如下拓扑图,我们模拟创建相应的虚拟网络设备,进行实现:

拓扑图:

命令操作:

# 创建对于设备
[root@virtual ~]# ip link add tap1 type veth peer name tap1_peer
[root@virtual ~]# ip link add tap2 type veth peer name tap2_peer
[root@virtual ~]# ip link add tap3 type veth peer name tap3_peer
[root@virtual ~]# ip link add tap4 type veth peer name tap4_peer
[root@virtual ~]# 
[root@virtual ~]# ip a s | grep tap
8: tap1_peer@tap1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
9: tap1@tap1_peer: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
10: tap2_peer@tap2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
11: tap2@tap2_peer: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
12: tap3_peer@tap3: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
13: tap3@tap3_peer: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
14: tap4_peer@tap4: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
15: tap4@tap4_peer: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
[root@virtual ~]# 
[root@virtual ~]# ip netns list
ns_test
[root@virtual ~]# ip netns add ns1
[root@virtual ~]# ip netns add ns2
[root@virtual ~]# ip netns add ns3
[root@virtual ~]# ip netns add ns4
[root@virtual ~]# ip netns list
ns4
ns3
ns2
ns1
ns_test
[root@virtual ~]# 
# 将设备迁移至namespace
[root@virtual ~]# ip link set tap1 netns ns1
[root@virtual ~]# ip link set tap2 netns ns2
[root@virtual ~]# ip link set tap3 netns ns3
[root@virtual ~]# ip link set tap4 netns ns4
[root@virtual ~]# 
# 创建 Bridge
[root@virtual ~]# brctl addbr br1
[root@virtual ~]# ip a s | grep br1
17: br1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
[root@virtual ~]# 
# 将tap 添加到 Bridge中
[root@virtual ~]# brctl addif br1 tap1_peer
[root@virtual ~]# brctl addif br1 tap2_peer
[root@virtual ~]# brctl addif br1 tap3_beer
interface tap3_beer does not exist!
[root@virtual ~]# brctl addif br1 tap3_peer
[root@virtual ~]# brctl addif br1 tap4_peer
[root@virtual ~]# 
# 配置 tap 对应的ip地址
[root@virtual ~]# ip netns exec ns1 ip addr add local 192.168.10.200/24 dev tap1
[root@virtual ~]# ip netns exec ns2 ip addr add local 192.168.10.201/24 dev tap2
[root@virtual ~]# ip netns exec ns3 ip addr add local 192.168.10.202/24 dev tap3
[root@virtual ~]# ip netns exec ns4 ip addr add local 192.168.10.203/24 dev tap4
[root@virtual ~]# 
# 将 Bridge 以及所有 tap 状态设置为 up
[root@virtual ~]# ip link set br1 up
[root@virtual ~]# ip link set tap1_peer up
[root@virtual ~]# ip link set tap2_peer up
[root@virtual ~]# ip link set tap3_peer up
[root@virtual ~]# ip link set tap4_peer up
[root@virtual ~]# ip netns exec ns1 ip link set tap1 up
[root@virtual ~]# ip netns exec ns2 ip link set tap2 up
[root@virtual ~]# ip netns exec ns3 ip link set tap3 up
[root@virtual ~]# ip netns exec ns4 ip link set tap4 up
[root@virtual ~]# 
# 相互进行ip 互ping ,验证网络连通
[root@virtual ~]# ip netns exec ns1 ping 192.168.10.201
PING 192.168.10.201 (192.168.10.201) 56(84) bytes of data.
64 bytes from 192.168.10.201: icmp_seq=1 ttl=64 time=0.041 ms
64 bytes from 192.168.10.201: icmp_seq=2 ttl=64 time=0.032 ms
64 bytes from 192.168.10.201: icmp_seq=3 ttl=64 time=0.031 ms
64 bytes from 192.168.10.201: icmp_seq=4 ttl=64 time=0.027 ms
^C
--- 192.168.10.201 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.027/0.032/0.041/0.008 ms
[root@virtual ~]# ip netns exec ns1 ping 192.168.10.202
PING 192.168.10.202 (192.168.10.202) 56(84) bytes of data.
64 bytes from 192.168.10.202: icmp_seq=1 ttl=64 time=0.041 ms
64 bytes from 192.168.10.202: icmp_seq=2 ttl=64 time=0.033 ms
64 bytes from 192.168.10.202: icmp_seq=3 ttl=64 time=0.037 ms
64 bytes from 192.168.10.202: icmp_seq=4 ttl=64 time=0.027 ms
^C
--- 192.168.10.202 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.027/0.034/0.041/0.007 ms
[root@virtual ~]# ip netns exec ns1 ping 192.168.10.203
PING 192.168.10.203 (192.168.10.203) 56(84) bytes of data.
64 bytes from 192.168.10.203: icmp_seq=1 ttl=64 time=0.059 ms
64 bytes from 192.168.10.203: icmp_seq=2 ttl=64 time=0.027 ms
64 bytes from 192.168.10.203: icmp_seq=3 ttl=64 time=0.033 ms
64 bytes from 192.168.10.203: icmp_seq=4 ttl=64 time=0.031 ms
^C
--- 192.168.10.203 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.027/0.037/0.059/0.014 ms
[root@virtual ~]# 
[root@virtual ~]# ip netns exec ns4 ping 192.168.10.200
PING 192.168.10.200 (192.168.10.200) 56(84) bytes of data.
64 bytes from 192.168.10.200: icmp_seq=1 ttl=64 time=0.022 ms
64 bytes from 192.168.10.200: icmp_seq=2 ttl=64 time=0.024 ms
64 bytes from 192.168.10.200: icmp_seq=3 ttl=64 time=0.033 ms
64 bytes from 192.168.10.200: icmp_seq=4 ttl=64 time=0.030 ms
^X^C
--- 192.168.10.200 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.022/0.027/0.033/0.005 ms
[root@virtual ~]# 
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值