linux网络命名空间

linux network namespace可在主机上建立隔离的网络环境。每个命名空间都有单独的接口和路由表。进程可与指定的网络命名空间进行关联。

Linux启动时,系统上有一个默认的命名空间,新建的进程将从其父级继承该命名空间。所有进程都继承初始化进程所使用的网络命名空间。

本文通过创建两个网络命名空间,然后,使用ping命令验证网络命名空间中的网络。

查看网络命名空间

ip netns list
ls /var/run/netns

创建网络命名空间

ip netns add <new namespace name>

ip netns add demo

在命名空间中执行命令

sudo ip netns exec demo ip a

也可使用-all参数,在所有现有命名空间上运行命令

sudo ip -all netns exec ip a 

注:如有需要,可在指定的名称空间上分配网络接口

sudo ip link set toad netns x

示例中在"x"命名空间设置”toad“。

虚拟交换机

在这个示例中,使用Open vSwitch做为虚拟交换机,将两个命名空间连接到虚拟交换机,并从一个命名空间向另一命名空间发送ping。

注:虚拟交换机安装参考Open vSwitch安装

添加一个名称为“my_switch”的虚拟交换机:

ovs-vsctl add-br my_switch

确认是否已添加:

>$ovs-vsctl show

6359d3db-c2cd-4f93-9a58-05b10e364934
  Bridge my_switch
    Port my_switch
      Interface my_switch
        type: internal
  ovs_version: "2.5.9"

查看虚拟交换机

>$ip a

5: my_switch: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
  link/ether 92:49:e0:f7:6d:4d brd ff:ff:ff:ff:ff:ff

示例中,使用“veth”将命名空间连接到自定义的虚拟交换机,。

注:veth(虚拟以太网)是一个有趣的结构,是一种始终成对出现的网络设备。可以将这一对想象成一个管道。从管道的一端发出的东西,都会从另一端出来。接下来的两个命令可以解释这一特性。

添加虚拟以太网

为说明以太网的特征,添加一个veth,并查看网络。

>$sudo ip link add type veth
>$ip a

6: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
  link/ether c2:c3:a8:ed:dc:eb brd ff:ff:ff:ff:ff:ff
7: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
  link/ether 56:7e:8a:5d:8d:9f brd ff:ff:ff:ff:ff:ff

删除虚拟以太网

删除虚拟以太网。

sudo ip link del veth0
ip a

创建veth设备

现在回到主题,将命名空间连接到虚拟交换机。

sudo ip link add demo-netns type veth peer name demo-ovs

在“demo”命名空间中设置“demo-netns”:

>$sudo ip link set demo-netns netns demo
>$ip a

8: demo-ovs@demo-netns: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
  link/ether ea:83:5a:14:64:2c brd ff:ff:ff:ff:ff:ff
9: demo-netns@demo-ovs: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
  link/ether 8a:78:e5:54:21:0f brd ff:ff:ff:ff:ff:ff

示例中,demo-netns将位于“mario”命名空间中,“demo-ovs”将连接到虚拟交换机。

使用如下命令会发现demo-netns@demo-ovs不会存在于“默认”命名空间中。

>$ip a
8: demo-ovs@if9: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
  link/ether ea:83:5a:14:64:2c brd ff:ff:ff:ff:ff:ff link-netnsid 0

>$ip netns exec demo ip a

1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
  link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
9: demo-netns@if8: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
  link/ether 8a:78:e5:54:21:0f brd ff:ff:ff:ff:ff:ff link-netnsid 0

如示例所见,“demo-netns”位于“demo”命名空间中。

现在,将另一端(demo-ovs)添加到虚拟交换机中。

>$ovs-vsctl add-port my_switch demo-ovs
>$ovs-vsctl show

6359d3db-c2cd-4f93-9a58-05b10e364934
  Bridge my_switch
    Port my_switch
      Interface my_switch
        type: internal
    Port demo-ovs
      Interface demo-ovs
  ovs_version: "2.5.9"

使用ovs-vsctl add-port命令,将“demo-ovs”添加到“my_switch”中,作为另一个端口。

以上完成了demo网络命名空间的创建。还需同样的方式创建另一个网络命名空间,以实现两个命名空间相互发送ping指令。

ip netns add news
sudo ip -all netns exec ip a
sudo ip link add news-netns type veth peer name news-ovs
sudo ip link set news-netns netns news
ovs-vsctl add-port my_switch news-ovs

创建完新的网络命名空间后,为设备分配地址并启动它们。

打开设备

首先,打开“默认”命名空间中的设备:

sudo ip link set demo-ovs up
sudo ip link set news-ovs up

打开“demo”和“news”命名空间中的所有设备:

sudo ip netns exec demo ip link set dev lo up
sudo ip netns exec demo ip link set dev demo-netns up

sudo ip netns exec news ip link set dev lo up
sudo ip netns exec news ip link set dev news-netns up

分配地址

为命名称空间中的“demo-netns”和“news-netns”设备分配地址:

sudo ip netns exec demo ip addr add 10.0.0.1/24 dev demo-netns
sudo ip netns exec news ip addr add 10.0.0.2/24 dev news-netns

验证设备和IP地址是否正确

>$sudo ip netns exec demo ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  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
9: demo-netns@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
  link/ether 8a:78:e5:54:21:0f brd ff:ff:ff:ff:ff:ff link-netnsid 0
  inet 10.0.0.1/24 scope global demo-netns
    valid_lft forever preferred_lft forever
  inet6 fe80::8878:e5ff:fe54:210f/64 scope link
    valid_lft forever preferred_lft forever

Ping测试

网络命名空间已连接到交换机,设备有一个指定的IP地址,执行ping测试。

>$sudo ip netns exec demo ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=1.06 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.190 ms