Linux网络虚拟化:探索NetWork Namespace
· 8 min read
NetWork Namespace
是 Linux 2.6
版本引入的,作用是隔离出一个独立的网络栈(包括设备、IP、路由表、端口、防火墙等),它能创建多个隔离的网络空间。
NetWork Namespace简介
NetWork Namespace
是 Linux 2.6
版本引入的,作用是隔离出一个独立的网络栈(包括设备、IP、路由表、端口、防火墙等),它能创建多个隔离的网络空间。
在Linux
系统上,我们可以使用ip
命令来创建和管理Network namespace
。
ip netns 命令手册
SYNOPSIS
ip netns [ list ]:列出所有的network namespace
ip netns add NETNSNAME:添加一个 新的ns
ip [-all] netns del [ NETNSNAME ]:删除所有或者指定的ns
ip netns set NETNSNAME NETNSID:修改netnsname或者netnsid
ip netns identify [ PID ]:把某个进程加入到network namespace中
ip netns pids NETNSNAME:列出加入当前ns的pid
ip [-all] netns exec [ NETNSNAME ] command...:在netns中执行命令,如ping、ifconfig
ip netns monitor:监控
按照操作手册中的命令就可以创建 ns
.
管理Network Namespace
- 创建NS
[root@k8s-master-168 ~]# ip netns add nets1
[root@k8s-master-168 ~]# ip netns list
nets1
- 查看NS中的网络信息
[root@k8s-master-168 ~]# ip netns exec nets1 ip link list
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
[root@k8s-master-168 ~]# ip netns exec nets1 route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
[root@k8s-master-168 ~]# ip netns exec nets1 iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
从结果来看,创建的nets1
网络栈中只有lo
这个未启用的回环设备,并且没有配置路由和防火墙规则等。
- 创建一个网络设备并配置IP
# 创建veth pair虚拟网络设备网卡
# 创建一个veth0和veth1的veth 对,把veth1插入到nets1的网络栈中,veth0默认在跟network namespace中。
[root@k8s-master-168 ~]# ip link add veth0 type veth peer name veth1
[root@k8s-master-168 ~]# ip link set veth1 netns nets1
# 此时查看就发现多了一个网络设备veth1,但是设备没有启动,并且没有配置IP
[root@k8s-master-168 ~]# ip netns exec nets1 ip link list
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
9: veth1@if10: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether aa:54:ee:12:3a:34 brd ff:ff:ff:ff:ff:ff link-netnsid 0
# 启用网卡,并设置ip
[root@k8s-master-168 ~]# ip netns exec nets1 ifconfig veth1 10.1.1.1/24 up
[root@k8s-master-168 ~]# ip netns exec nets1 ifconfig
veth1: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 10.1.1.1 netmask 255.255.255.0 broadcast 10.1.1.255
ether aa:54:ee:12:3a:34 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- 删除veth对和ns
# veth对是一个整体,删除veth0,veth1也就不存在。
[root@k8s-master-168 ~]# ip link del veth0
[root@k8s-master-168 ~]# ip netns del nets1
单主机两个 NetWork Namespace 之间通信
主机上创建两个ns
,它们之间如何通信呢,可以使用veth pair
进行连接。
- 创建两个
ns
#创建两个ns
[root@k8s-master-168 ~]# ip netns add nets1
[root@k8s-master-168 ~]# ip netns add nets2
# 创建veth,并分别插入ns中
[root@k8s-master-168 ~]# ip link add veth0 type veth peer name veth1
[root@k8s-master-168 ~]# ip link set veth0 netns nets1
[root@k8s-master-168 ~]# ip link set veth1 netns nets2
- 配置两个veth网络设备
[root@k8s-master-168 ~]# ip netns exec nets2 ifconfig veth1 10.1.1.2/24 up
[root@k8s-master-168 ~]# ip netns exec nets1 ifconfig veth0 10.1.1.1/24 up
# 检查是否配置成功
[root@k8s-master-168 ~]# ip netns exec nets1 ifconfig
veth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.1.1.1 netmask 255.255.255.0 broadcast 10.1.1.255
inet6 fe80::b4c2:70ff:fe8d:3b0e prefixlen 64 scopeid 0x20<link>
ether b6:c2:70:8d:3b:0e txqueuelen 1000 (Ethernet)
RX packets 8 bytes 656 (656.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 656 (656.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@k8s-master-168 ~]# ip netns exec nets2 ifconfig
veth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.1.1.2 netmask 255.255.255.0 broadcast 10.1.1.255
inet6 fe80::f046:44ff:fe62:1ecc prefixlen 64 scopeid 0x20<link>
ether f2:46:44:62:1e:cc txqueuelen 1000 (Ethernet)
RX packets 9 bytes 726 (726.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 9 bytes 726 (726.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
- 测试网络
# 从nets1 ping nets2网络是通的
[root@k8s-master-168 ~]# ip netns exec nets1 ping 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=0.106 ms
64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=0.079 ms
64 bytes from 10.1.1.2: icmp_seq=3 ttl=64 time=0.083 ms
# 从nets2 ping nets1 网络是通的
[root@k8s-master-168 ~]# ip netns exec nets2 ping 10.1.1.1
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=0.108 ms
64 bytes from 10.1.1.1: icmp_seq=2 ttl=64 time=0.085 ms
64 bytes from 10.1.1.1: icmp_seq=3 ttl=64 time=0.078 ms
单主机多个 NetWork Namespace 之间通信
上述是两个ns
可以采用直接veth
的模式进行通信,就好比采用一根网线,连接两台电脑,如果出现3台电脑需 要通信,此时就不能再通过拉取网线的新式了,在物理网络中是采用交换机来处理这种问题。
在虚拟网络中通常用Linux bridge
, Linux Bridge
可以连接任意真实的物理设备(如:eth0网卡)或任意虚拟设备(如:veth pair设备,tap设备)。
- 创建一个bridge
[root@k8s-master-168 ~]# ip link add name br0 type bridge
[root@k8s-master-168 ~]# ip link set br0 up
- 创建三个ns
# 创建3个ns
[root@k8s-master-168 ~]# ip netns add nets1
[root@k8s-master-168 ~]# ip netns add nets2
[root@k8s-master-168 ~]# ip netns add nets3
# 创建3对veth pair
[root@k8s-master-168 ~]# ip link add type veth
[root@k8s-master-168 ~]# ip link add type veth
[root@k8s-master-168 ~]# ip link add type veth
- 把br0和3个ns版定
# 把veth1、veth3、veth5分别插入nets1、nets2、nets3中
[root@k8s-master-168 ~]# ip link set veth1 netns nets1
[root@k8s-master-168 ~]# ip link set veth3 netns nets2
[root@k8s-master-168 ~]# ip link set veth5 netns nets3
# 把veth0、veth2、veth4插入br0中
[root@k8s-master-168 ~]# ip link set dev veth0 master br0 up
[root@k8s-master-168 ~]# ip link set dev veth2 master br0 up
[root@k8s-master-168 ~]# ip link set dev veth4 master br0 up
# 设置三个ip给veth1、veth3、veth5设备并启用
[root@k8s-master-168 ~]# ip netns exec nets1 ifconfig veth1 10.1.1.1/24 up
[root@k8s-master-168 ~]# ip netns exec nets2 ifconfig veth3 10.1.1.2/24 up
[root@k8s-master-168 ~]# ip netns exec nets3 ifconfig veth5 10.1.1.3/24 up
进过上述配置之后呢就把这三个ns通过br0这个桥绑定上了,就可以做到两两任意访问了。
[root@k8s-master-168 ~]# ip netns exec nets1 ping 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=0.138 ms
64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=0.172 ms
64 bytes from 10.1.1.2: icmp_seq=3 ttl=64 time=0.138 ms
[root@k8s-master-168 ~]# ip netns exec nets1 ping 10.1.1.3
PING 10.1.1.3 (10.1.1.3) 56(84) bytes of data.
64 bytes from 10.1.1.3: icmp_seq=1 ttl=64 time=0.149 ms
64 bytes from 10.1.1.3: icmp_seq=2 ttl=64 time=0.114 ms
64 bytes from 10.1.1.3: icmp_seq=3 ttl=64 time=0.130 ms
跨主机多个 NetWork Namespace 之间通信
跨主机网络通信涉及到需要通过vxlan
、macvlan
、ipvlan
等技术进行跨主机组网,