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 helpUsage: ip netns listip netns add NAMEip netns set NAME NETNSIDip [-all] netns delete [NAME]ip netns identify [PID]ip netns pids NAMEip [-all] netns exec [NAME] cmd ...ip netns monitorip 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 listns_test[root@virtual ~]#
当创建一个namespace后,就可以将一些虚拟设备迁移到这个namespace中去了,比如上一篇中介绍的tap。
# 创建tap,并配置对应IP,详细信息可看上一篇文档[root@virtual ~]# tunctl -t tap_testSet 'tap_test' persistent and owned by uid 0[root@virtual ~]# ip link list1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:002: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ff3: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000link/ether 2e:5c:3f:10:63:12 brd ff:ff:ff:ff:ff:ff[root@virtual ~]# ip addr show1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ffinet 10.0.0.176/24 brd 10.0.0.255 scope global noprefixroute dynamic eth0valid_lft 75898sec preferred_lft 75898secinet6 fe80::f816:3eff:fe56:6a87/64 scope linkvalid_lft forever preferred_lft forever3: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000link/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 show1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ffinet 10.0.0.176/24 brd 10.0.0.255 scope global noprefixroute dynamic eth0valid_lft 75813sec preferred_lft 75813secinet6 fe80::f816:3eff:fe56:6a87/64 scope linkvalid_lft forever preferred_lft forever3: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000link/ether 2e:5c:3f:10:63:12 brd ff:ff:ff:ff:ff:ffinet 10.0.0.190/24 scope global tap_testvalid_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 s1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:003: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000link/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 s1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:003: tap_test: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000link/ether 2e:5c:3f:10:63:12 brd ff:ff:ff:ff:ff:ffinet 192.168.10.190/24 scope global tap_testvalid_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 s1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ffinet 10.0.0.176/24 brd 10.0.0.255 scope global noprefixroute dynamic eth0valid_lft 64021sec preferred_lft 64021secinet6 fe80::f816:3eff:fe56:6a87/64 scope linkvalid_lft forever preferred_lft forever6: tap2@tap1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000link/ether a6:74:e9:cb:8f:f1 brd ff:ff:ff:ff:ff:ff7: tap1@tap2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000link/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 list1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:002: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000link/ether fa:16:3e:56:6a:87 brd ff:ff:ff:ff:ff:ff[root@virtual ~]# ip netns listns2ns1 (id: 0)ns_test[root@virtual ~]#[root@virtual ~]# ip netns exec ns1 ping 192.168.10.201PING 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 ms64 bytes from 192.168.10.201: icmp_seq=2 ttl=64 time=0.027 ms64 bytes from 192.168.10.201: icmp_seq=3 ttl=64 time=0.026 ms64 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 2999msrtt min/avg/max/mdev = 0.023/0.026/0.028/0.002 ms[root@virtual ~]# ip netns exec ns1 ip a1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:007: tap1@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000link/ether 02:d1:8c:8b:44:e9 brd ff:ff:ff:ff:ff:ff link-netnsid 1inet 192.168.10.200/24 scope global tap1valid_lft forever preferred_lft foreverinet6 fe80::d1:8cff:fe8b:44e9/64 scope linkvalid_lft forever preferred_lft forever[root@virtual ~]# ip netns exec ns2 ip a s1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:006: tap2@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000link/ether a6:74:e9:cb:8f:f1 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 192.168.10.201/24 scope global tap2valid_lft forever preferred_lft foreverinet6 fe80::a474:e9ff:fecb:8ff1/64 scope linkvalid_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-utilsLoaded plugins: fastestmirrorLoading mirror speeds from cached hostfile......Running transactionInstalling : bridge-utils-1.5-9.el7.x86_64 1/1Verifying : bridge-utils-1.5-9.el7.x86_64 1/1Installed:bridge-utils.x86_64 0:1.5-9.el7Complete![root@virtual ~]# brctlUsage: brctl [commands]commands:addbr <bridge> add bridgedelbr <bridge> delete bridgeaddif <bridge> <device> add interface to bridgedelif <bridge> <device> delete interface from bridgehairpin <bridge> <port> {on|off} turn hairpin on/offsetageing <bridge> <time> set ageing timesetbridgeprio <bridge> <prio> set bridge prioritysetfd <bridge> <time> set bridge forward delaysethello <bridge> <time> set hello timesetmaxage <bridge> <time> set max message agesetpathcost <bridge> <port> <cost> set path costsetportprio <bridge> <port> <prio> set port priorityshow [ <bridge> ] show a list of bridgesshowmacs <bridge> show a list of mac addrsshowstp <bridge> show bridge stp infostp <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 tap8: tap1_peer@tap1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 10009: tap1@tap1_peer: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 100010: tap2_peer@tap2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 100011: tap2@tap2_peer: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 100012: tap3_peer@tap3: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 100013: tap3@tap3_peer: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 100014: tap4_peer@tap4: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 100015: tap4@tap4_peer: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000[root@virtual ~]#[root@virtual ~]# ip netns listns_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 listns4ns3ns2ns1ns_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 br117: 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_beerinterface 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.201PING 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 ms64 bytes from 192.168.10.201: icmp_seq=2 ttl=64 time=0.032 ms64 bytes from 192.168.10.201: icmp_seq=3 ttl=64 time=0.031 ms64 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 2999msrtt min/avg/max/mdev = 0.027/0.032/0.041/0.008 ms[root@virtual ~]# ip netns exec ns1 ping 192.168.10.202PING 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 ms64 bytes from 192.168.10.202: icmp_seq=2 ttl=64 time=0.033 ms64 bytes from 192.168.10.202: icmp_seq=3 ttl=64 time=0.037 ms64 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 2999msrtt min/avg/max/mdev = 0.027/0.034/0.041/0.007 ms[root@virtual ~]# ip netns exec ns1 ping 192.168.10.203PING 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 ms64 bytes from 192.168.10.203: icmp_seq=2 ttl=64 time=0.027 ms64 bytes from 192.168.10.203: icmp_seq=3 ttl=64 time=0.033 ms64 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 2999msrtt 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.200PING 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 ms64 bytes from 192.168.10.200: icmp_seq=2 ttl=64 time=0.024 ms64 bytes from 192.168.10.200: icmp_seq=3 ttl=64 time=0.033 ms64 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 2999msrtt min/avg/max/mdev = 0.022/0.027/0.033/0.005 ms[root@virtual ~]#
IT火车![Linux easy-rsa制作证书[实测最简步骤]-IT火车](https://idc.birk.cn/wp-content/uploads/2024/02/5c9c04de835c4a4c8ceb13e457a0c4e2-220x150.gif)
最新评论