Linux网络虚拟化:探索NetWork Namespace

May 12, 2022

NetWork Namespace简介

NetWork NamespaceLinux 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 之间通信

veth1

主机上创建两个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 之间通信

bridge

上述是两个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 之间通信

跨主机网络通信涉及到需要通过vxlanmacvlanipvlan等技术进行跨主机组网,


LRF 记录学习、生活的点滴