一、前言

namespace(命名空间)和cgroup是软件容器化(想想Docker)趋势中的两个主要内核技术。简单来说,cgroup是一种对进程进行统一的资源监控和限制,它控制着你可以使用多少系统资源(CPU,内存等)。而namespace是对全局系统资源的一种封装隔离,它通过Linux内核对系统资源进行隔离和虚拟化的特性,限制了您可以看到的内容。
Linux .8内核提供了6种类型的命名空间:Process ID (pid)、Mount (mnt)、Network (net)、InterProcess Communication (ipc)、UTS、User ID (user)。例如,pid命名空间内的进程只能看到同一命名空间中的进程。mnt命名空间,可以将进程附加到自己的文件系统(如chroot)。在本文中,我只关注网络命名空间 Network (net)。
网络命名空间为命名空间内的所有进程提供了全新隔离的网络协议栈。这包括网络接口,路由表和iptables规则。通过使用网络命名空间就可以实现网络虚拟环境,实现彼此之间的网络隔离,这对于云计算中租户网络隔离非常重要,Docker中的网络隔离也是基于此实现的,如果你已经理解了上面所说的,那么我们进入正题,介绍如何使用网络命名空间。

二、环境准备及状态确认

1.创建测试容器
#创建两个测试容器
[root@localhost ~]# docker run -d -it --name busybox_1 busybox /bin/sh -c "while true;do sleep 3600;done"
[root@localhost ~]# docker run -d -it --name busybox_2 busybox /bin/sh -c "while true;do sleep 3600;done"
[root@localhost ~]# docker ps -a
2.查看容器IP及网络联通性
#查看容器的IP
[root@localhost ~]# docker exec -it busybox_1 ip a
[root@localhost ~]# docker exec -it busybox_2 ip a [root@localhost ~]# docker exec -it busybox_1 /bin/sh
/ # ping 172.17.0.3 #进入容器,ping busybox_2的地址
PING 172.17.0.3 (172.17.0.3): data bytes
bytes from 172.17.0.3: seq= ttl= time=0.133 ms
bytes from 172.17.0.3: seq= ttl= time=0.097 ms
bytes from 172.17.0.3: seq= ttl= time=0.124 ms
[root@localhost ~]# docker exec -it busybox_2 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): data bytes
bytes from 172.17.0.2: seq= ttl= time=0.109 ms
bytes from 172.17.0.2: seq= ttl= time=0.152 ms
现象总结:
同一台宿主机上创建的容器默认是能够互相通信的

三、通过命令行模拟docker容器的网络通信

1.手动创建两个网络名称空间
[root@localhost ~]# ip netns add test1
[root@localhost ~]# ip netns add test2
[root@localhost ~]# ip netns list
test2
test1
2.查看test1网络名称空间网络状态
[root@localhost ~]# ip netns exec test1 ip link
: lo: <LOOPBACK> mtu qdisc noop state DOWN group default qlen #默认只存在lo接口,并且状态为DOWN
link/loopback ::::: brd :::::
3.查看宿主机网络设备
[root@localhost ~]# ip link  #发现除了正常系统存在的lo和eth0网络接口外,还存在其他三个接口
: lo: <LOOPBACK,UP,LOWER_UP> mtu qdisc noqueue state DOWN mode DEFAULT group default qlen
link/loopback ::::: brd :::::
: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc pfifo_fast state UP mode DEFAULT group default qlen
link/ether :::fd::4b brd ff:ff:ff:ff:ff:ff
: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue state UP mode DEFAULT group default
link/ether :::c0::f9 brd ff:ff:ff:ff:ff:ff
: veth0a87245@if104: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether f2:be:7e:3c::3c brd ff:ff:ff:ff:ff:ff link-netnsid
: vethabf8073@if106: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether d6:dd::cf::4a brd ff:ff:ff:ff:ff:ff link-netnsid
4.创建一对veth pair网络接口

什么是veth pair?

veth pair 不是一个设备,而是一对设备,以连接两个虚拟以太端口。操作veth pair,需要跟namespace一起配合。两个namespace ns1/ns2 中各有一个tap组成veth pair,两个tap 上配置的ip进行互ping

简单的拓扑图:

创建一对veth pair

[root@localhost ~]# ip link add veth-test1 type veth peer name veth-test2    #创建 veth-test1 和 veth-test2 一对pair
[root@localhost ~]# ip link #查看是否添加成功 108 109
: veth-test2@veth-tes1: <BROADCAST,MULTICAST,M-DOWN> mtu qdisc noop state DOWN mode DEFAULT group default qlen
link/ether be::e6::be: brd ff:ff:ff:ff:ff:ff
: veth-tes1@veth-test2: <BROADCAST,MULTICAST,M-DOWN> mtu qdisc noop state DOWN mode DEFAULT group default qlen
link/ether da::e4:b1:cc: brd ff:ff:ff:ff:ff:ff
5.将veth-test1 接口添加到test1网络名称空间中去
[root@localhost ~]# ip link  set veth-test1  netns test1
[root@localhost ~]# ip netns exec test1 ip link #查看是否添加成功,状态为DOWN
: lo: <LOOPBACK,UP,LOWER_UP> mtu qdisc noqueue state UNKNOWN mode DEFAULT group default qlen
link/loopback ::::: brd :::::
: veth-tes1@if108: <BROADCAST,MULTICAST> mtu qdisc noop state DOWN mode DEFAULT group default qlen
link/ether da::e4:b1:cc: brd ff:ff:ff:ff:ff:ff link-netnsid
6.检查宿主机本地网络接口(109: veth-tes1@veth-test2已经没有了)
[root@localhost ~]# ip link
: lo: <LOOPBACK,UP,LOWER_UP> mtu qdisc noqueue state UNKNOWN mode DEFAULT group default qlen
link/loopback ::::: brd :::::
: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc pfifo_fast state UP mode DEFAULT group default qlen
link/ether :::fd::4b brd ff:ff:ff:ff:ff:ff
: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue state UP mode DEFAULT group default
link/ether :::c0::f9 brd ff:ff:ff:ff:ff:ff
: veth0a87245@if104: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether f2:be:7e:3c::3c brd ff:ff:ff:ff:ff:ff link-netnsid
: vethabf8073@if106: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether d6:dd::cf::4a brd ff:ff:ff:ff:ff:ff link-netnsid
: veth-test2@if109: <BROADCAST,MULTICAST> mtu qdisc noop state DOWN mode DEFAULT group default qlen
link/ether be::e6::be: brd ff:ff:ff:ff:ff:ff link-netnsid
7.参照之前步骤,将veth-test2 接口添加到test2网络名称空间中去
[root@localhost ~]# ip link  set veth-test2  netns test2
[root@localhost ~]# ip netns exec test2 ip link
8.为两个网络名称空间的网络接口分别添加一个IP地址
[root@localhost ~]# ip netns exec test1 ip addr add 192.168.1.1/ dev veth-test1  #为test1网络名称空间中veth-test1接口添加IP,地址为192.168.1.1
[root@localhost ~]# ip netns exec test2 ip addr add 192.168.1.2/ dev veth-test2 #同上
[root@localhost ~]# ip netns exec test1 ip a #查看test1网络名称接口状态,veth-test1已经绑定了IP,但是状态为DOWN
: lo: <LOOPBACK,UP,LOWER_UP> mtu qdisc noqueue state UNKNOWN group default qlen
link/loopback ::::: brd :::::
inet 127.0.0.1/ scope host lo
valid_lft forever preferred_lft forever
inet6 ::/ scope host
valid_lft forever preferred_lft forever
: veth-tes1@if108: <BROADCAST,MULTICAST> mtu qdisc noop state DOWN group default qlen
link/ether da::e4:b1:cc: brd ff:ff:ff:ff:ff:ff link-netnsid
inet 192.168.1.1/ scope global veth-tes1
valid_lft forever preferred_lft forever
[root@localhost ~]# ip netns exec test2 ip a #同上
: lo: <LOOPBACK> mtu qdisc noop state DOWN group default qlen
link/loopback ::::: brd :::::
: veth-test2@if109: <BROADCAST,MULTICAST> mtu qdisc noop state DOWN group default qlen
link/ether be::e6::be: brd ff:ff:ff:ff:ff:ff link-netnsid
inet 192.168.1.2/ scope global veth-test2
valid_lft forever preferred_lft forever
9.启动以上两个网络接口
[root@localhost ~]# ip netns exec test1 ip link set dev veth-test1 up
[root@localhost ~]# ip netns exec test2 ip link set dev veth-test2 up
[root@localhost ~]# ip netns exec test1 ip link
: lo: <LOOPBACK,UP,LOWER_UP> mtu qdisc noqueue state UNKNOWN mode DEFAULT group default qlen
link/loopback ::::: brd :::::
: veth-tes1@if108: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue state UP mode DEFAULT group default qlen
link/ether da::e4:b1:cc: brd ff:ff:ff:ff:ff:ff link-netnsid
[root@localhost ~]# ip netns exec test2 ip link
: lo: <LOOPBACK> mtu qdisc noop state DOWN mode DEFAULT group default qlen
link/loopback ::::: brd :::::
: veth-test2@if109: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue state UP mode DEFAULT group default qlen
link/ether be::e6::be: brd ff:ff:ff:ff:ff:ff link-netnsid
10.测试通信
#网络通信测试
[root@localhost ~]# ip netns exec test1 ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) () bytes of data.
bytes from 192.168.1.2: icmp_seq= ttl= time=0.056 ms
bytes from 192.168.1.2: icmp_seq= ttl= time=0.057 ms [root@localhost ~]# ip netns exec test2 ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) () bytes of data.
bytes from 192.168.1.1: icmp_seq= ttl= time=0.039 ms
bytes from 192.168.1.1: icmp_seq= ttl= time=0.084 ms

docke通信之Linux 网络命名空间的更多相关文章

  1. Linux网络命名空间

        命名空间(Linux namespace)是linux内核针对实现虚拟化引入的一个特性.创建的每个进程都有自己的命名空间,运行在其中的进程都像是在独立的操作系统中运行一样,命名空间保证了进程之 ...

  2. [国嵌笔记][007][Linux网络配置]

    Vmware网络设置 1.bridged(桥接模式) 如果网络中能提供多个IP地址,则使用桥接方式.虚拟机与主机的IP地址彼此独立. 2.NAT(网络地址转换模式) 如果只能提供一个IP地址,则使用N ...

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

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

  4. [Linux网络、命名空间、veth设备对、docker的host模式、container模式、none模式、brideg模式、网桥的增删查,容器与网桥的连接断开]

    [Linux网络.命名空间.veth设备对.docker的host模式.container模式.none模式.brideg模式.网桥的增删查,容器与网桥的连接断开] 网络名称空间 为了支持网络协议栈的 ...

  5. (转) 在linux网络UDP通信中,关于客户端是否绑定的理解

    最近在做一个实例,是用RTSP协议完成.服务器已经有了,只需要把客户端做好就行了,在做的过程中发现了一些问题,就是关于UDP客户端是否绑定的问题. 也许大家在书上看到的大多都是说UDP客户端不需要绑定 ...

  6. 深入理解linux网络技术内幕读书笔记(三)--用户空间与内核的接口

    Table of Contents 1 概论 1.1 procfs (/proc 文件系统) 1.1.1 编程接口 1.2 sysctl (/proc/sys目录) 1.2.1 编程接口 1.3 sy ...

  7. Linux的命名空间详解--Linux进程的管理与调度(二)【转】

    Linux Namespaces机制提供一种资源隔离方案. PID,IPC,Network等系统资源不再是全局性的,而是属于特定的Namespace.每个Namespace里面的资源对其他Namesp ...

  8. Linux的命名空间详解--Linux进程的管理与调度(二)

    转自:http://blog.csdn.net/gatieme/article/details/51383322 日期 内核版本 架构 作者 GitHub CSDN 2016-05-12 Linux- ...

  9. 由PPPOE看Linux网络协议栈的实现

    http://www.cnblogs.com/zmkeil/archive/2013/05/01/3053545.html 这个标题起得比较纠结,之前熟知的PPPOE是作为PPP协议的底层载体,而实际 ...

随机推荐

  1. Mysql使用ReplicationDriver驱动实现读写分离

    数据库的主从复制环境已经配好,该要解决系统如何实现读写分离功能了.Mysql的jdbc驱动提供了一种实现ReplicationDriver. 1 数据库地址的两种写法 参考:https://dev.m ...

  2. 谈谈JavaScript Navigator 对象属性

    Navigator 对象属性 可以在Navigator对象上使用以下属性: 属性 描述 appCodeName 返回浏览器的代码名称 appName 返回浏览器的名称 appVersion 返回浏览器 ...

  3. JPA笔记1 ManyToOne

    persistence.xml <?xml version="1.0" encoding="UTF-8"?> <persistence ver ...

  4. SQLServer修改表名、修改列名

    基本语法 修改表名:EXEC sp_rename ‘原有表名’, '新表名'; 修改列名:EXEC sp_rename ‘表名.[原有列名]’, ‘新列名' , 'COLUMN'; EXEC sp_r ...

  5. python 之serial、pyusb 使用开发

    说明:本次是在windows 系统操作实现的. serial 使用场景,获取得力扫码枪的扫码数据,该扫码枪支持三种通讯接口设置,如下图 即插即用的是 USB-KBW功能,插上去即可获取扫码数据,第二种 ...

  6. C语言之++和--

    #include<stdio.h> int main(void) { int a; a = ; printf("a++ = %d\n", a++); printf(&q ...

  7. 201871010112-梁丽珍《面向对象程序设计(java)》第十四周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  8. 解决IIS7、IIS7.5 应用程序池回收假死的方法

    最近iis网站一直假死状态,都懵了,查看程序有没有关闭数据库,反复捣鼓,还一直测试是否是程序应用池自动回收问题依然没有效果.经过老师提醒,找到了解决办法,在此做个笔记! 原因在于:应用程序池超时配置被 ...

  9. MySQL数据库练习

    1.数据准备 以下为db文件,通过Navicat Premium导入数据库 /* 数据导入: Navicat Premium Data Transfer Source Server : localho ...

  10. USACO Stamps

    洛谷 P2725 邮票 Stamps https://www.luogu.org/problem/P2725 JDOJ 1797: Stamps 邮票 https://neooj.com:8082/o ...