linux 网络虚拟化: network namespace 简介

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

NOTE:ip 命令因为需要修改系统的网络配置,默认需要 sudo 权限。这篇文章使用 root 用户执行,请不要在生产环境或者重要的系统中用 root 直接执行,以防产生错误。

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

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

创建 network namespace 也非常简单,直接使用 ip netns add 后面跟着要创建的 namespace 名称。如果相同名字的 namespace 已经存在,命令会报 Cannot create namespace 的错误。

ip netns 命令创建的 network namespace 会出现在 /var/run/netns/ 目录下,如果需要管理其他不是 ip netns 创建的 network namespace,只要在这个目录下创建一个指向对应 network namespace 文件的链接就行。

有了自己创建的 network namespace,我们还需要看看它里面有哪些东西。对于每个 network namespace 来说,它会有自己独立的网卡、路由表、ARP 表、iptables 等和网络相关的资源。ip 命令提供了 ip netns exec 子命令可以在对应的 network namespace 中执行命令,比如我们要看一下这个 network namespace 中有哪些网卡。更棒的是,要执行的可以是任何命令,不只是和网络相关的(当然,和网络无关命令执行的结果和在外部执行没有区别)。比如下面例子中,执行 bash 命令了之后,后面所有的命令都是在这个 network namespace 中执行的,好处是不用每次执行命令都要把 ip netns exec NAME 补全,缺点是你无法清楚知道自己当前所在的 shell,容易混淆。

更新:通过修改 bash 的前缀信息可以区分不同 shell,操作如下:

ip netns exec 后面跟着 namespace 的名字,比如这里的 net1,然后是要执行的命令,只要是合法的 shell 命令都能运行,比如上面的 ip addr 或者 bash

每个 namespace 在创建的时候会自动创建一个 lo 的 interface,它的作用和 linux 系统中默认看到的 lo 一样,都是为了实现 loopback 通信。如果希望 lo 能工作,不要忘记启用它:

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

network namespace 之间通信

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

使用上面提到的方法,我们再创建另外一个 network namespace,这里我们使用 net0 和 net1 两个名字。

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

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

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

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

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

完成这些,我们创建的网络拓扑结构如下所示:

使用 bridge 连接不同的 namespace

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

NOTE:和 bridge 有关的操作也可以使用命令 brctl,这个命令来自 bridge-utils 这个包,读者可以根据自己的发行版进行安装,使用方法请查阅 man 页面或者相关文档。

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

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

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

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

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

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

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

参考资料

linux 网络虚拟化: network namespace 简介的更多相关文章

  1. linux网络虚拟化

    图解几个与Linux网络虚拟化相关的虚拟网卡-VETH/MACVLAN/MACVTAP/IPVLAN http://smilejay.com/2012/08/qemu-kvm-networking-m ...

  2. Docker核心实现技术(命名空间&控制组&联合文件系统&Linux网络虚拟化支持)

    作为一种容器虚拟化技术,Docker深度应用了操作系统的多项底层支持技术. 早期版本的Docker是基于已经成熟的Linux Container(LXC)技术实现的.自Docker 0.9版本起,Do ...

  3. Linux 网络 I/O 模型简介(图文)(转载)

    Linux 网络 I/O 模型简介(图文)(转载) 转载:http://blog.csdn.net/anxpp/article/details/51503329 1.介绍 Linux 的内核将所有外部 ...

  4. Linux ns 6. Network Namespace 详解

    文章目录 1. 简介 1.1 Docker Network 桥接模式配置 2. 代码解析 2.1 copy_net_ns() 2.2 pernet_list 2.2.1 loopback_net_op ...

  5. 【 Linux 网络虚拟化 】Openvswitch

    openvswitch:    openvswitch: 开放的虚拟交换机,虚拟交换就是利用虚拟平台,通过软件的方式形成交换机部件.跟传统的物理交换机相比,虚拟交换机同样具备众多优点:         ...

  6. 【 Linux 网络虚拟化 】Netns

    netns 可以创建一个完全隔离的新网络环境,这个环境包括一个独立的网卡空间,路由表,ARP表,ip地址表,iptables等.总之,与网络有关的组件都是独立的. 创建网络空间: # ip netns ...

  7. Linux 网络 I/O 模型简介(图文)

    1.介绍 Linux 的内核将所有外部设备都看做一个文件来操作(一切皆文件),对一个文件的读写操作会调用内核提供的系统命令,返回一个file descriptor(fd,文件描述符).而对一个sock ...

  8. 网络虚拟化技术(一): Linux网络虚拟化

    创建虚拟网络环境 使用命令 $ ip netns add net0 可以创建一个完全隔离的新网络环境,这个环境包括一个独立的网卡空间,路由表,ARP表,ip地址表,iptables,ebtables, ...

  9. Linux网络下载命令 wget 简介

    wget 是一个命令行的下载工具.对于我们这些 Linux 用户来说,几乎每天都在使用它.下面为大家介绍几个有用的 wget 小技巧,可以让你更加高效而灵活的使用 wget. $ wget -r -n ...

随机推荐

  1. Git全面应用

    Git是一个免费的开源分布式版本控制系统,旨在快速高效地处理从小型到大型项目的所有事务. Git易于学习,占地面积小,具有闪电般快速的性能. 它超越了Subversion,CVS,Perforce和C ...

  2. mysql 聚集函数 count 使用详解(转载)

    本文将探讨以下问题 1.count(*) . count(n).count(null)与count(fieldName)2.distinct 与 count 连用3.group by (多个字段) 与 ...

  3. js异步处理历程

    为什么会出现异步: js执行环境是单线程的,异步处理就非常重要. 处理的方法: 方法一:callback hell 解决:解决了异步处理 存在问题:出现多个回调函数嵌套,代码就会比较乱,出现回调地狱现 ...

  4. mysql 关联

    自关联 设计省信息的表结构provinces id ptitle 设计市信息的表结构cityscitys表的proid表示城市所属的省,对应着provinces表的id值 id ctitle proi ...

  5. 【HDFS API编程】从本地拷贝文件,从本地拷贝大文件,拷贝HDFS文件到本地

    接着之前继续API操作的学习 CopyFromLocalFile: 顾名思义,从本地文件拷贝 /** * 使用Java API操作HDFS文件系统 * 关键点: * 1)create Configur ...

  6. Linux 安装zabbix

    Linux 安装zabbix   zabbix是基于web界面的开源分布式监控平台,可以监控各种服务器的配置参数,支持自定义配置和自定义告警,并且可以实现邮件.短信等方式的告警,zabbix基本组件如 ...

  7. 转载:消息队列MQ

    本文大概围绕如下几点进行阐述: 为什么使用消息队列? 使用消息队列有什么缺点? 消息队列如何选型? 如何保证消息队列是高可用的? 如何保证消息不被重复消费? 如何保证消费的可靠性传输? 如何保证消息的 ...

  8. python2操作MySQL

    #coding=utf-8   import MySQLdb   conn = MySQLdb.connect(host='localhost',user='root',passwd='123456' ...

  9. 500G !!史上最全的JAVA全套教学视频网盘分享 (JEECG开源社区)

    500 G JAVA视频网盘分享(JEECG开源社区) [涵盖从java入门到深入架构,Linux.云计算.分布式.大数据Hadoop.ios.Android.互联网技术应有尽有] JEECG开源社区 ...

  10. Chrome 插件PPAPI 开发(一)环境搭建

    前言:本文参考了其他已有的文章,在其基础上简化了一些没有必要的操作. 同时也记录一下chrome 插件ppapi环境的基础搭建.并且感谢已有文章作者的大无畏的分享精神! 在这附上参考文章链接:http ...