docker网络解析
Docker概念和默认网络
什么是Docker网络呢?总的来说,网络中的容器们可以相互通信,网络外的又访问不了这些容器。具体来说,在一个网络中,它是一个容器的集合,在这个概念里面的一个容器,它会通过容器的IP直接去通信,又能保证在这个集合外的一些容器不能够通过这个容器IP去通信,能做到网络隔离。网络这个概念是由网络的驱动去创建、管理的。网络的驱动又分为全局的和本地的,全局的意思是这个网络可以跨主机,没必要说我的两个容器非要在一个主机上才能通过这个网络去通信,我可以在不同主机上还是通过容器的IP相互通信。
本地网络

首先我们看一个本地网络的图,这个图中有一台主机,上面跑了四个容器,分别分布在两个网络里面,一个是NET1,一个是NET2。NET1里面的两个容器是可以互相通过自己的IP通信的,但是NET1里面的容器和NET2里面的容器又是隔离的,这样就是Docker的一个网络概念。
全局网络

全局网络意思是,一个网络里面的容器是可以跨主机的。C1的容器可以和主机2上的C3容器,通过它们IP直接通信,而不用管所在的主机在哪个地方。这个图里面我们还可以看到一个细节,同一个容器可以加入到两个网络里面,比如C4它可以和网络1里面的两个容器通信,也可以和网络2里面的C5进行通信,这样我们就可以实现更加复杂的一些组合。比如C5是一个数据库的容器,我不想让这个数据被前面的WEB应用或者其他的应用去访问到,只想让我的中间键应用去访问到。这样就可以通过让中间键应用加入到一个后台网络、一个前台网络的组合来实现这种互联和网络的控制。
网络服务发现

在1.10版本增加了网络服务发现,什么意思呢?比如,我的一个网络有两个容器,我们可以直接通过IP进行通信,但是我的容器它可能某一段时间跪掉了,它可能在跪掉之后再去重启,我这时就不知道它的IP了,或者它一关闭之后,我这边感知不到,这样就要触发很多复杂的一些处理流程。在1.10时它去做这样的一件事,它在每个容器里面内置了一个DNS的服务器,在服务器RUN起来之后,会写一个容器名,或者是这个容器的一个别名和它IP的一个解析。外部容器去访问我的DB容器时,它能够通过DB这个名字来解析到DB容器的IP地址,这样在DB容器重启之后,这个解析会动态去调整,就能实现一个服务的发现。
Docker默认的网络驱动
Docker默认的会有一些网络驱动,它本地的网络驱动有这几种。none网络驱动意思是,我创建一个容器,但是没有它的一些网络配置,单独一个命名空间,它不能和其他容器通信,也不能访问外网。host的网络驱动和宿主机共享网络栈、它和宿主机看到同样的接口,包括它自己暴露的端口,都是和宿主机在同一个网络空间里面。

bridge网络驱动,它是一个本地的网络驱动,上图主机上有两个bridge网络,它实际上是通过Linux的bridge去驱动的,通过容器里面挂载一个网卡,对应的是在宿主机上一个veth,容器的请求会直接转发到这个veth上面,bridge上面会对这个请求进行洪泛,它就能到达这个网络里面的另外一个容器。同理,另外一个网络,它跟这个网络里面的容器没有在同一个网桥上面,所以他们之间是互相不能通信的。bridge驱动还会实现另外一个功能,比如说C1的容器,他要访问公网,它通过bridge出去的时候,他最终到达宿主机的接口,他会做一个网络地址的转换,把容器的IP转换成宿主机的IP,这样就能访问公网。或者我的容器可能希望服务映射到外面去,让别的机器或别的公开服务可以访问到,他可以做一个DNAT一个规则,比如我的容器是Nginx,它里面是80端口,我想映射到主机的一个9080,可以直接通过主机的9080去访问,他可以去做一个DNAT的配置,这是bridge的驱动。

Docker默认还有一个overlay的驱动,它主要是去实现跨主机的一个通信,它会在主机之间通过vxlan的方式打一个隧道,实现我的主机上的容器去访问主机上的容器,最终会转换成一个vxlan里面的通信。
Docker跨主机网络
没有跨主机网络时,比如一个应用有两个服务,两个服务不可能部署到同一个机器上,这样没办法做到高可用,所在的主机一挂,上面所有的服务都挂了。如果让它部署到两个主机上面,但是两个主机上面这个容器的IP在主机外面是看不到的。所以只能把容器的IP转换成了一个宿主机的一个IP,或者宿主机的一个访问端点,才能让外部的主机访问。所以,以前的方式是通过端口映射,把容器的一个端口映射到主机的一个端口,让另外一个主机和这个主机映射到这个容器上去通信。这样会带来哪些问题?首先我通过端口映射,比如说我映射到8090端口,我另外再想起一个容器。他就得映射到另外一个端口,因为宿主机上只有这一个8090端口,它不可能说共享这个端口,所以一个主机上去起容器的时候,需要管理端口的列表。映射出去之后是宿主机的一个端口,这样这个端口就是对外暴露的,可能要去控制一下,这个端口只能说主机要去访问,这样要去做一些安全的配置,所以这样的整个架构是非常复杂的。在Docker1.9之后,增加了跨主机的网络,它就可以直接通过容器的IP去通信,通过这个外部跟它是隔离的,这样又能做到安全,我就算再起一个容器,它容器的IP端口是不会冲突的。
封包模式
封包模式,比如overlay驱动,它是用VXLAN的协议去把容器之间的请求封装成VXLAN的请求,将链路层的以太网包封装到UDP包中进行传输。

这里有一个简单的图来介绍封包模式,首先举个例子,从C1去访问宿主机上C2的容器,先通过C1发出这个包之后,它首先进行封包,要查找中心化存储C2是在哪个主机上的,查到的是这个主机上,就把这个请求的包封装成宿主机之间的包,把这个包送达到对应宿主机上,再通过一定的约定去解包,最终转发到另外一个主机上的一个容器。其缺点是对带宽的损耗比较大,因为看到这里去封包,它肯定是把这个容器的包上面又加了一层包,这个包上面肯定会有一些自己的占用,一般像封包模式,MTU最终都会小于宿主机之间的MTU,它还会造成一些资源占用。比如说在这个地方去封包的时候,它可能会占用CPU去做一下封包操作,还会占用CPU去做解包的操作,所以会增加主机上的负载,但是它的好处是对基础设施要求比较低,它只需要两个宿主机之间可以三层互通。

下面我们以Docker的overlay驱动来介绍下封包的实现,它的封包方式是基于VXLAN。上图是它的针格式,VXLAN内部把一个二层的包、链路层的一个请求封装成一个VXLAN的一个包,这里面会有一个约定的信息,比如VXLAN ID,还有一个外部的UDP的头,最终会把这个包通过UDP发往对应的主机上面去,对应的主机再做VXLINE的解包。Docker还会做IP的地址管理和网络信息同步。
路由模式

如上图,比如,主机1上的容器想要访问主机2的容器,首先这个机器上是没有主机2的IP地址,它出了机器之后到达路由器,再通过路由器上的路由表,去把对应的请求网端转发到对应的主机2上面,主机2上面是有这个容器的IP,所以它就能够做到这个容器的跨主机通信。它的好处在于它没有封包,所以它的性能很好,但是它对于基础设施有一些要求,比如我的基础设施要支持、能够配置这个路由表,如果用Linux路由要支持二层的转发。

VPC网络驱动是在阿里云的VPC基础上,能够实现容器互通的一种方案。首先在Docker DM启动时,或者是在创建网络时,会从每个机器的一个中心化存储里面,拿到两个自己的网端,比如这个机器上的网端,比如左边主机上的网端就是172.19.1.1/24,它通过阿里云的openapi去配置这个转发表,把这个网端的地址都转发到这个主机上面。另外一个主机启动时,把它拿到一个可用的网端,去配置阿里云的一个路由表,把这个网端的请求转发到自己的主机上面,比如说我这边的一个容器想要去访问主机2上C2的容器时,它这个包最终到达,通过vSwitch到达阿里云VPC的vRouter时,通过查询路由表把实时的请求包转发到主机2上面,最终实现C1和C2的通信。
跨主机网络方案对比
封包模式的优点是对基础设施的要求比较低,但是它性能损耗比较大,路由模式是没有封包的,所以它性能比较好,但是对基础设施有一定要求,比如说要支持路由表,或者要支持二层的转发。
阿里云服务的网络方案
容器服务上面现在有两种集群,一种是阿里云的ECS集群,这种集群的节点都是在阿里云的同地域或者同一个VPC下面的ECS,或者是混合云的集群,阿里云的混合云集群节点是在用户自己建立的机房,或者分布在不同的云供应商上面。

在阿里云的ECS集群上面,网络架构是这样的,容器之间去通信,还是通过overlay驱动,它的好处是对基础设施要求比较低,所以它只需要主机之间互通就可以了,容器去访问外网,或者容器想要暴露端口给外网就通过一个gateway_bridge的网桥、本地的一个驱动,这个是供容器访问外网和容器的端口映射。在ECS集群上面,VPC网络是通过VPC驱动的路由表把对应的请求转发到容器所在机器上面,它去访问外网和做端口映射也是和刚才所介绍的overlay是同样的。

混合云集群是结合阿里云的VPC技术去实现容器之间的网络互通。在混合云集群里面是通过专线的方式,把对应的数据中心的请求转发到我的数据中心里面,或者把数据中心的请求访问VPC的,通过专线的一个路由也可以转发到VPC里面,再通过路由表把容器的请求转发到对应的主机上面,最终实现的方式是把我VPC里面的容器和数据中心里面的容器互通。

刚才我们介绍的都是容器之间通信,我们可以不通过端口映射的方式做到端口不冲突,怎么能够做到我想要外部访问时,也能做到就一个负载均衡,怎么能做到一个机器上面部署多个容器,然后端口不冲突呢?这时候阿里云就提供了这样的一个负载均衡方案。比如说我的网站有两个域名,一个是购物的域名,一个是付款的,但是我总共就三台机器,每个服务要做到高可用,所以起了很多的容器,这样在同一个主机上就要去处理,怎么让它保障单个不冲突,容器服务是提供一个这样的方案,我们在集群里面会部署一套路由的一个服务,首先请求,比如说我的公司域名的泛解析会解析到我的路由服务上面去,路由服务再通过请求的域名Host,去把这个请求直接转发到容器上面,最终实现我的一个请求可以转发到容器上面,但是我的容器并没有映射出端口,也不需要去解决端口冲突的问题。
docker网络解析的更多相关文章
- 容器docker网络解析
如果想要实现两台主机之间相连通信,最直接的办法是找一根网线连起来, 多台的话需要用网线将他们链接再交换机上. linux中能够起到虚拟交换机的网络设备是网桥birdge, 工作再链路层, 主要是根据m ...
- 一篇不一样的docker原理解析
转自:https://zhuanlan.zhihu.com/p/22382728 https://zhuanlan.zhihu.com/p/22403015 在学习docker的过程中,我发现目前do ...
- docker网络
docker网络 Docker 允许通过外部访问容器或容器互联的方式来提供网络服务. 端口映射允许外部访问容器 --link 容器互联 容器桥接网络 .通过--link容器通信,给test2添加一 ...
- Docker网络和容器的通信
Docker的本地网络实现其实就是利用了Linux上的网络命名空间和虚拟网络设备(特别是veth pair). 基本原理 直观上看,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)与外界 ...
- Docker网络及命令
Docker常用命令 docker version #查看版本 docker search centos #搜索可用docker镜像 docker images 查看当前docker所有镜像 dock ...
- docker网络之overlay
使用docker network的好处是:在同一个网络上的容器之间可以相互通信,而无需使用expose端口特性 本文使用docker-swarm进行overlay网络的分析.使用2个vmware模拟2 ...
- docker 网络的几种模式
docker 网络分为单机和多机,我们来了解一下docker的单机网络 docker单机网络分为以下几种: 1)bridge NetWork,使用--net=bridge指定,默认设置.2)Host ...
- docker——网络配置
一.网络启动与配置参数 Docker启动时会在主机上自动创建一个docker0虚拟网桥,实际上是一个Linux网桥,可以理解为一个软件交换机,它会在挂载其上的接口之间进行数据转发.同时,Docker随 ...
- docker网络模式----入门docker的难点
众所周知,现在docker是轻量级虚拟化的典型代表!这段时间想要建立一个分布式系统,但是手头上主机没那么多,所以使用docker进行虚拟化,但是在使用的过程中对网络这一部分是一直不太理解,特别找了一篇 ...
随机推荐
- Mac OSX操作系统安装和配置Zend Server 6教程(3)
Zend Server安装好以后,在php.ini文件中,没有默认时区.就是导致很多警告信息出现的根本. 接下来,我们看看如果修改这个文件. 首先,进入php.ini文件.此文件在目录zend/etc ...
- 如何把va_list可变参数传送到下一级函数中(如传送到printf)
最近我在一个LCD上想实现打印格式化字符串的功能,实现这样的功能可有两种方式: 一 最直接的就是自己去解析类似于printf功能的一个函数: 二 比较简单的方法是使用已有的sprintf功能,把格式化 ...
- 读书笔记—CLR via C#章节8-10
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 【学习笔记】锋利的jQuery(一)选择器
一.要点阐述 1,jQuery创建于2006年1月的一个开源项目,强调理念是“write less,do more”,压缩后大小30KB左右.. 2,jQuery里的方法都被设计程自动操作对象集合,而 ...
- Android学习笔记-Intent(一)
Intent对象在Android官方API这样描述:It is a passive data structure holding an abstract description of an opera ...
- VMware NAT方式 CentOS 6.8配置静态IP
一.打开虚拟机设置,配置网络连接,如下图 二.编辑 /etc/sysconfig/network,以配置网关 vim /etc/sysconfig/network NETWORKING=yes HOS ...
- 从网络上获取图片并保存在sdCard上
package com.aib.soft; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileO ...
- Sparse Filtering
Sparse Filtering 当前很多的特征学习(feature learning)算法需要很多的超参数(hyper-parameter)调节, Sparse Filtering则只需要一个超参数 ...
- DDD社区官网
DDD社区官网上一篇关于聚合设计的几个原则的简单讨论: 聚合是用来封装真正的不变性,而不是简单的将对象组合在一起 聚合应尽量设计的小 聚合之间通过ID关联 聚合内强一致性,聚合之间最终一致性 从聚合和 ...
- (转)NoSQL——Redis在win7下安装配置的学习一
NoSQL——Redis在win7下安装配置的学习一 有些也是从网上看来的 1.下载安装 Redis它没有windows的官方版本,但是又非官方的版本,到官网上去下载相应的版本,我的电脑是win7 ...