Docker把网络跟存储这两部分的功能实现都以插件化形式剥离出来,允许用户通过指令来选择不同的后端实现。这也是Docker希望构建围绕着容器的强大生态系统的一些积极的尝试。剥离出来的独立容器网络项目叫libnetwork,从名字就能看出来,它希望将来为不同容器定义统一规范的网络层标准。

容器网络模型

libnetwork中容器网络模型(Container Networking Model,CNM)十分简洁,可以让上层使用网络的大量应用容器最大程度上不去关心底层实现。

容器网络模型的结构如图所示。

包括三种基本元素:

  1. Sandbox(沙盒):代表一个容器(准确地说,是其网络命名空间);
  2. Endpoint(接入点):代表网络上可以挂载容器的接口,会分配IP地址;
  3. Network可以连通多个接入点的一个子网。

对于使用CNM的容器管理系统来说,具体底下网络如何实现,不同子网彼此怎么隔离,有没有QoS,都可以不关心。只要插件能提供网络和接入点,只需把容器给接上或者拔下,剩下的都是插件驱动自己去实现。这样就解耦和容器和网络功能,十分灵活。

首先,是驱动注册自己到网络控制器,网络控制器使用驱动类型,来创建网络,然后在创建的网络上创建接口,最后把容器连接到接口上即可。销毁过程则正好相反,先把容器从接入口上卸载,然后删除接入口和网络即可。

CNM的典型生命周期如图所示:

目前CNM支持的驱动类型有四种:Null、Bridge、Overlay、Remote。简单介绍如下:

  1. Null:不提供网络服务,容器启动后无网络连接;
  2. Bridge:就是Docker传统上默认用Linux网桥和Iptables实现的单机网络;
  3. Overlay:是用vxlan隧道实现的跨主机容器网络;
  4. Remote:扩展类型,预留给其他外部实现的方案,比如有一套第三方的SDN方案(如OpenStack Neutron),就可以接进来。

从位置上看,libnetwork上面支持Docker,下面支持网络插件,自身处于十分关键的中间层。如果熟悉计算机网络协议模型的话,libnetwork就是最核心的TCP/IP层。目前,已有大量的网络方案开始支持libnetwork。包括OpenStack Kuryr项目,通过支持libnetwork,让Docker可以直接使用Neutron提供的网络功能。Calico等团队也编写了插件支持libnetwork,从而无缝地支持Docker网络功能。

Docker网络相关命令

在libnetwork支持下,Docker网络相关命令都作为network的子命令出现。

围绕着管理CNM的生命周期,主要包括以下命令:

  1. ls:列出所有的网络;
  2. create:创建一个网络;
  3. rm:删除一个网络;
  4. connect:把容器接入到网络;
  5. disconnect:把容器从网络卸载下来;
  6. inspect:查看网络的详细信息。

下面分别介绍这些命令。

1.列出网络

命令格式:docker network ls [OPTIONS]

支持参数包括:

-f:指定输出过滤器;

--no-trunc:不截断输出内容。

实际上,在不执行额外网络命令的情况下,用户执行docker network ls命令,一般情况下可以看到已创建的三个网络:

$ docker network ls

NETWORK ID          NAME                DRIVER
461e02c94370 bridge bridge
e4d5886b2d2f none null
adbc1879bac5 host host

分别为三种驱动的网络:null、host和bridge。

2.创建网络

命令格式:docker network create [OPTIONS] NETWORK

支持参数包括:

--aux-address value:辅助的IP地址;

-d,--driver string:网络驱动类型,如bridge或overlay;

--gateway value:网关地址;

--internal:禁止外部对创建网络的访问;

--ip-range value:分配IP地址范围;

--ipam-driver string:IP地址管理的插件类型;

--ipam-opt value:IP地址管理插件的选项;

--ipv6:支持IPv6地址;

--label value:为网络添加元标签信息;

-o,--opt value:网络驱动支持的选项;

--subnet value:网络地址段。

3.删除网络

删除指定的网络。当网络上并不存在接入点时,删除成功。

命令格式:docker network rm NETWORK [NETWORK...]

4.接入容器

将一个容器连接到一个已存在的网络上。命令格式:docker network connect [OPTIONS] NETWORK CONTAINER

支持参数包括:

--alias value:为容器添加一个别名,此别名仅在所添加网络上可见;

--ip string:指定IP地址;

--ip6 string:指定IPv6地址;

--link value:添加链接到另外一个容器;

--link-local-ip value:为容器添加一个链接地址。

5.卸载容器

将一个连接到网络上的容器从网络上移除。命令格式:docker network disconnect [OPTIONS] NETWORK CONTAINER

支持参数包括-f、--force:强制把容器从网络上移除。

6.查看网络信息

查看已存在网络的具体信息。命令格式:docker network inspect [OPTIONS] NETWORK [NETWORK...]

支持参数包括-f、--format string:给定一个golang模板字符串,对输出结果进行格式化。

构建跨主机容器网络

使用libnetwork自带的Overlay类型驱动来轻松实现跨主机的网络通信。Overlay驱动默认采用VXLAN协议,在IP地址可以互相访问的多个主机上之间搭建隧道,让容器可以互相访问。

1.配置网络信息管理数据库

我们知道,在现实世界中,要连通不同的主机需要交换机或路由器(跨子网时需要)这样的互联设备。这些设备一方面是在物理上起到连接作用,但更重要的是起到了网络管理的功能。例如,主机位置在什么地方,地址是多少等信息,都需要网络管理平面来维护。

在libnetwork的网络方案中,要实现跨主机容器网络也需要类似的一个网络信息管理机制,只不过这个机制简单得多,只是一个键值数据库而已,如Consul、Etcd、ZooKeeper等工具都可以满足需求如图所示。

以Consul为例,启动一个progrium/consul容器,并映射服务到本地的8500端口,用如下命令即可:

$ docker run -d \

-p "8500:8500" \

-h "consul" \

progrium/consul -server -bootstrap

所在主机作为数据库节点。

2.配置Docker主机

启动两台Docker主机n1和n2,分别安装好最新的Docker-engine(1.7.0+)。确保这两台主机之间可以通过IP地址互相访问,另外,都能访问到数据库节点的8500端口。

配置主机的Docker服务启动选项如下所示:

DOCKER_OPTS="$DOCKER_OPTS --cluster-store=consul://<consul_node>:8500 --cluster-advertise=eth0:2376"

重新启动Docker服务如下所示:

$ sudo service docker restart

3.创建网络

分别在n1和n2上查看现有的Docker网络,包括三个默认网络:分别为bridge、host和none类型。

n1:$ docker network ls

n2:$ docker network ls

在任意节点上创建网络multi,例如在n1上执行如下命令即可完成对跨主机网络的创建:

n1:$ docker network create -d overlay multi

创建成功后,可以同时在n1和n2上查看到新的网络multi的信息:

n1:$ docker network ls

n2:$ docker network ls

NETWORK ID NAME DRIVER
dc581a3eab4c bridge bridge
ee21a768c6f6 host host
eadd374a1843 multi overlay
8d1ee747b894 none null

此时,还可以通过docker network inspect命令查看网络的具体信息:

$ docker network inspect multi

4.测试网络

在n1上启动一个容器c1,通过--net选项指定连接到multi网络上。查看网络信息,其中一个接口eth0已经连接到了multi网络上:

n1:$ docker run -it --name=c1 --net=multi busybox

/ # ip a

在n2上启动一个容器c2,同样连接到multi网络上。

通过ping c1进行测试,可以访问到另外一台主机n1上的容器c1:

n2:$ docker run -it --name=c2 --net=multi busybox

/ # ping c1

libnetwork插件化网络功能的更多相关文章

  1. TinyFrame升级之八:实现简易插件化开发

    本章主要讲解如何为框架新增插件化开发功能. 在.net 4.0中,我们可以在Application开始之前,通过PreApplicationStartMethod方法加载所需要的任何东西.那么今天我们 ...

  2. docker——libnetwork插件网络功能

    从1.7.0版本开始,Docker正是把网络和存储这两部分的功能都以插件化形式剥离出来,允许用户通过指令来选择不同的后端实现.剥离出来的独立容器网络项目叫libnetwork,从名字就能看出,它希望将 ...

  3. Taro 2.2 全面插件化,支持拓展和定制个性化功能

    自 2.2 开始,Taro 引入了插件化机制,允许开发者通过编写插件的方式来为 Taro 拓展更多功能或者为自身业务定制个性化功能,欢迎大家进行尝试,共同讨论~ 当前版本 2.2.1 官方插件 Tar ...

  4. Android插件化开发

    客户端开发给人的印象往往是小巧,快速奔跑.但随着产品的发展,目前产生了大量的门户型客户端.功能模块持续集成,开发人员迅速增长.不同的开发小组开发不同的功能模块,甚至还有其他客户端集成进入.能做到功能模 ...

  5. RN学习1——前奏,app插件化和热更新的探索

    react_native_banner-min.png React Native(以下简称RN)有大量前端开发者的追捧.前端开发是一个活跃的社区,一直尝试着一统前后端,做一个全栈开发,RN就是他们在客 ...

  6. Unity多玩家网络游戏开发教程1章Unity带有网络功能

    Unity网络多玩家游戏开发教程第1章Unity自带网络功能 Unity拥有大量的第三方插件.专门提供了对网络功能的支持. 可是.大部分开发人员第一次接触到的还是Unity自带的网络功能.也就是大家常 ...

  7. iOS 插件化开发汇总 Small框架

    应用插件化背景 目前很多应用功能越来越多,软件显得越来越臃肿.因此插件化就成了很多软件发展的必经之路,比如支付宝这种平台级别的软件: 页上密密麻麻的功能,而且还在增多,照这个趋势发展下去,软件包的大小 ...

  8. 有关Android插件化思考

    最近几年移动开发业界兴起了「 插件化技术 」的旋风,各个大厂都推出了自己的插件化框架,各种开源框架都评价自身功能优越性,令人目不暇接.随着公司业务快速发展,项目增多,开发资源却有限,如何能在有限资源内 ...

  9. Android插件化-RePlugin项目集成与使用

    前言:前一段时间新开源了一种全面插件化的方案-- RePlugin,之前一种都在关注 DroidPlugin 并且很早也在项目中试用了,但最终没有投入到真正的生产环节,一方面是项目中没有特别需要插件化 ...

随机推荐

  1. fully delete project in Eclipse

    选择你的项目(test)右击,选择delete——弹出框中勾选删除全部,如下如所示: 正常情况下,这样就能删除干净了,有时候你项目在运行,这时候你点击删除,那就会报下面的错误提示,虽然不会影响你其它项 ...

  2. kafka不停止服务的情况下修改日志保留时间

    kafka配置文件如下: broker.id=1 port=9092 host.name=ssy-kafka1 num.network.threads=4 num.io.threads=8 socke ...

  3. Regex Golf练习笔记(1)

    正则表达式进阶练习:https://alf.nu/RegexGolf  (此练习笔记) 正则表达式验证:https://regexr.com/ (1) (2) 注释:每个词的三个字母在后面重复出现了一 ...

  4. Javascript设计模式理论与实战:享元模式

    享元模式不同于一般的设计模式,它主要用来优化程序的性能,它最适合解决大量类似的对象而产生的性能问题.享元模式通过分析应用程序的对象,将其解析为内在数据和外在数据,减少对象的数量,从而提高应用程序的性能 ...

  5. python3--django for 循环中,获取序号

    功能需求:在前端页面中,for循环id会构不成连续的顺序号,所以要找到一种伪列的方式来根据数据量定义序号 因此就用到了在前端页面中的一个字段 forloop.counter,完美解决 <tbod ...

  6. Ruby on Rails 目录结构

    目录结构 + app/ #控制器.模型.视图.帮助方法.邮件.静态资源 + bin/ #rails脚本 + config/ #路由.数据库等 + db/ #数据库模式.迁移文件 + lib/ #扩展模 ...

  7. 使用客户端软件向服务端php程序发送post数据,php接受三种方法

    方法一:$_POST; 方法二:$GLOBALS['HTTP_RAW_POST_DATA'],需要在php.ini开启 always_populate_raw_post_data = On: 方法三: ...

  8. hdu2829 Lawrence

    题目链接:戳我 朴素DP:\(dp[i][j]=dp[i-1][k]+cost[k+1][j]\) 其中dp[i][j]表示炸第i次的时候,处理到前j个的最小值是多少.cost[i][j]表示的是i, ...

  9. JAVA 定时器时间格式

    格式: [秒] [分] [小时] [日] [月] [周] [年] 通配符说明: \*:表示所有值.例如:在分的字段上设置"\*",表示每一分钟都会触发. ?:表示不指定值.使用的场 ...

  10. Android四种数据存储方式

    一.SharedPreference数据存储篇 1.作用范围 (1).它是一种轻型的数据存储方式 (2).本质是基于XML文件存储key-value键值对数据 (3).通常用来存储一些简单的配置方式 ...