network namespace 是实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自的网络栈信息。不管是虚拟机还是容器,运行的时候仿佛自己就在独立的网络中。这篇文章介绍 network namespace 的基本概念和用法,network namespace 是 linux 内核提供的功能,这篇文章借助 ip 命令来完成各种操作。

ip 命令管理的功能很多, 和 network namespace 有关的操作都是在子命令 ip netns 下进行的,可以通过 ip netns help 查看所有操作的帮助信息。

默认情况下,使用 ip netns 是没有网络 namespace 的,所以 ip netns ls 命令看不到任何输出。

# ip netns help
Usage: 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
# ip netns ls

使用 ip netns add创建 network namespace

# ip netns add net1
# ip netns ls
net1

ip netns 命令创建的 network namespace 会出现在 /var/run/netns/ 目录下

对于每个 network namespace 来说,它会有自己独立的网卡、路由表、ARP 表、iptables 等和网络相关的资源。ip 命令提供了 ip netns exec 子命令可以在对应的 network namespace 中执行命令。

# ip netns exec net1 ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

还可以通过bash进入network namespace 并更新命令行提示符

# ip netns exec net1 /bin/bash --rcfile <(echo "PS1=\"namespace net1> \"")
namespace net1> ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
namespace net1>

默认情况下,network namespace 是不能和主机网络,或者其他 network namespace 通信的。

1. network namespace 之间通信

有了不同 network namespace 之后,也就有了网络的隔离,但是如果它们之间没有办法通信,也没有实际用处。要把两个网络连接起来,linux 提供了 veth pair 。可以把 veth pair 当做是双向的 pipe(管道),从一个方向发送的网络数据,可以直接被另外一端接收到;或者也可以想象成两个 namespace 直接通过一个特殊的虚拟网卡连接起来,可以直接通信。

使用上面提到的方法,我们再创建另外一个 network namespace,这里我们使用 net0net1 两个名字。网络拓扑结构如下:

我们可以使用 ip link add type veth 来创建一对 veth pair 出来, veth pair 无法单独存在,删除其中一个,另一个也会自动消失。

# ip link add type veth
# ip link
4: veth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000link/ether 36:88:73:83:c9:64 brd ff:ff:ff:ff:ff:ff
5: veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000link/ether fe:7e:75:4d:79:2e brd ff:ff:ff:ff:ff:ff

NOTE: 创建 veth pair 的时候可以自己指定它们的名字,比如 ip link add vethfoo type veth peer name vethbar 创建出来的两个名字就是 vethfoovethbar 。因为这里我们对名字没有特殊要求,所以就直接使用系统自动生成的名字。如果 pair 的一端接口处于 DOWN 状态,另一端能自动检测到这个信息,并把自己的状态设置为 NO-CARRIER

创建结束之后,我们能看到名字为 veth0veth1 两个网络接口,名字后面的数字是系统自动生成的。接下来,要做的是把这对 veth pair 分别放到已经两个 namespace 里面,这个可以使用 ip link set DEV netns NAME 来实现:

# ip link set veth0 netns net0
# ip link set veth1 netns net1
# ip netns exec net0 ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWNlink/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
4: veth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000link/ether 36:88:73:83:c9:64 brd ff:ff:ff:ff:ff:ff
# ip netns exec net1 ip addr
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWNlink/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
5: veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000link/ether fe:7e:75:4d:79:2e brd ff:ff:ff:ff:ff:ff

最后,我们给这对 veth pair 配置上 ip 地址,并启用它们。

# ip netns exec net0 ip link set veth0 up
# ip netns exec net0 ip addr add 10.0.1.1/24 dev veth0
# ip netns exec net0 ip route
10.0.1.0/24 dev veth0  proto kernel  scope link  src 10.0.1.1# ip netns exec net1 ip link set veth1 up
# ip netns exec net1 ip addr add 10.0.1.2/24 dev veth1

可以看到,最每个 namespace 中,在配置玩 ip 之后,还自动生成了对应的路由表信息,网络 10.0.1.0/24 数据报文都会通过 veth pair 进行传输。使用 ping 命令可以验证它们的连通性:

# ip netns exec net0 ping -c 3 10.0.1.2
PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.
64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=0.039 ms
64 bytes from 10.0.1.2: icmp_seq=2 ttl=64 time=0.039 ms
64 bytes from 10.0.1.2: icmp_seq=3 ttl=64 time=0.139 ms--- 10.0.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 0.039/0.072/0.139/0.047 ms

2. 使用 bridge 连接不同的 namespace

虽然 veth pair 可以实现两个 network namespace 之间的通信,但是当多个 namespace 需要通信的时候,就无能为力了。
讲到多个网络设备通信,我们首先想到的交换机和路由器。因为这里要考虑的只是同个网络,所以只用到交换机的功能。linux 当然也提供了虚拟交换机的功能,我们还是用 ip 命令来完成所有的操作。

NOTE: 和 bridge 有关的操作也可以使用命令 brctl,这个命令来自 bridge-utils 这个包。

下图是这部分网络的拓扑结构:

首先我们来创建需要的 bridge,简单起见名字就叫做 br0。

# ip link add br0 type bridge
# ip link set dev br0 up

下面只演示一个 namespace 的操作,其他 namespace 要做的事情和这个类似。创建 veth pair:

# ip link add type veth

把其中一个 veth(veth1) 放到 net0 里面,设置它的 ip 地址并启用它:

# ip link set dev veth1 netns net0
# ip netns exec net0 ip link set dev veth1 name eth0
# ip netns exec net0 ip addr add 10.0.1.1/24 dev eth0
# ip netns exec net0 ip link set dev eth0 up

最后,把另一个 veth(veth0)连接到创建的 bridge 上,并启用它:

# ip link set dev veth0 master br0
# ip link set dev veth0 up

可以通过 bridge命令(也是 iproute2 包自带的命令)来查看 bridge 管理的 link 信息:

# bridge link
17: veth0 state UP : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 2

最后通过 ping 命令来测试网络的连通性:

# ip netns exec net0 ping -c 3 10.0.1.3
PING 10.0.1.3 (10.0.1.3) 56(84) bytes of data.
64 bytes from 10.0.1.3: icmp_seq=1 ttl=64 time=0.251 ms
64 bytes from 10.0.1.3: icmp_seq=2 ttl=64 time=0.047 ms
64 bytes from 10.0.1.3: icmp_seq=3 ttl=64 time=0.046 ms--- 10.0.1.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2008ms

如果对 docker 网络熟悉的话,其实这和 docker 默认的 bridge 网络模型非常相似。当然要实现每个 namespace 对外网的访问还需要额外的配置(设置默认网关,开启 ip_forward,为网络添加 NAT 规则等)。

参考:
https://blog.kghost.info/2013/03/01/linux-network-emulator/
http://blog.scottlowe.org/2013/09/04/introducing-linux-network-namespaces/
https://cizixs.com/2017/02/10/network-virtualization-network-namespace/
https://blog.csdn.net/sld880311/article/details/77650937

ip netns的使用及network namespace 简介相关推荐

  1. linux 的ip 设置lo_linux网络虚拟化: network namespace 简介及实验

    namespace(命名空间)和cgroup是软件容器化(想想Docker)趋势中的两个主要内核技术.简单来说,cgroup是一种对进程进行统一的资源监控和限制,它控制着你可以使用多少系统资源(CPU ...

  2. 使用openvswitch网桥连接不同的network namespace

    Namespace是Linux提供的一种内核级别环境隔离的方法,在Linux中Namespace实际上有6中,这里只是单纯的说明一下网络命名空间(Network Namespace).在实际应用中,N ...

  3. Linux namespace之:network namespace

    理解network namespace network namespace用来隔离网络环境,「在network namespace中,网络设备.端口.套接字.网络协议栈.路由表.防火墙规则等都是独立的 ...

  4. Linux Namespace系列(06):network namespace (CLONE_NEWNET)

    network namespace用来隔离网络设备, IP地址, 端口等. 每个namespace将会有自己独立的网络栈,路由表,防火墙规则,socket等. 每个新的network namespac ...

  5. ip netns 命令(备忘)

    Linux Network Namespace Linux Network Namespace 是实现容器化的基础 ip netns 是基于 Linux Network Namespace 的一个实用 ...

  6. linux unshare 命令,Linux ip netns 命令

    /var/run/netns/ 目录下的一个对象.比如有一个名称为 net1 的 network namespace 对象,则可以由打开 /var/run/netns/net1 对象产生的文件描述符引 ...

  7. ip netns 命令使用

    ip netns 命令用来管理 network namespace.它可以创建命名的 network namespace,然后通过名字来引用 network namespace,所以使用起来很方便. ...

  8. Linux网络虚拟化基石 network namespace

    1 网络虚拟化基石 network namespace Linux的namespace的作用就是"隔离内核资源". 在Linux的世界里,文件系统挂载点.主机名.POSIX进程间通 ...

  9. linux网络命名空间详解,Linux Network Namespace (netns) 详解

    Linux Network Namespace (netns) 详解 Network Namespace (以下简称netns)是Linux内核提供的一项实现网络隔离的功能,它能隔离多个不同的网络空间 ...

最新文章

  1. 【leetcode】Search in Rotated Sorted Array II(middle)☆
  2. 超纯超美的曲线(Peter De Jong Attractor)
  3. 论java之反射机制,访问类中私有变量,调用私有方法
  4. 怎么使用config?
  5. Mac安装RocketMQ和可视化控制台教程
  6. 使用python学线性代数_最简单的神经网络简介| 使用Python的线性代数
  7. 进入Google:《Google成功的七堂课》读后感
  8. 为什么要使用MQ消息中间件?
  9. Pytorch permute()的简单用法
  10. Atitit 文件存储标准化api 总结 目录 1. 操作系统,进行操作 1 1.1. FileUtils类的应用 1 1.2. 各大api 比较 2 2. Java。Io用apache的commo
  11. 超像素分割算法研究:SLIC分割算法原理讲解
  12. VMware Workstation12安装win 7企业版激活
  13. 研发数据安全解决方案
  14. java实现pdf旋转_Java实现PDF文本旋转倾斜的方法
  15. 联想小新Air2020ill版换硬盘及安装Win11详细过程
  16. 强大的实用的mac软件卸载应用软件,彻底清除App残留
  17. win系统加入方舟服务器秒退,win10方舟生存进化进服务器闪退解决方法
  18. tp link拨号失败 服务器无响应,pppoe拨号失败解决方法_pppoe怎么设置
  19. java数组声明语句代码,Java 数组(学习 Java 编程语言 013-014)
  20. Utorrent 设置

热门文章

  1. mysql的sql经典写法收录
  2. NTT Docomo研究主管Kazuaki OBANA:NTT DOCOMO NFV案例解析
  3. SQL Server Profiler
  4. WEB站点服务器安全配置
  5. Hbase 架构(未完待续)
  6. WSUS客户端无法发现
  7. 关于H5跳转到小程序和android的方法
  8. 【251】◀▶IEW-Unit16
  9. hdu 1300(dp)
  10. MountFlags of reg