(转) Docker - Docker1.12服务发现,负载均衡和Routing Mesh
看到一篇介绍 Docker swarm以及如何编排的好文章,挪放到这里,自己学习的同时也分享出来。
原文链接: http://wwwbuild.net/dockerone/414200.html
Docker社区目前最热的话题莫过于Docker 1.12的发布, 明显的感觉就是大家都在讨论Docker 1.12的新功能,各种关于1.12的使用手册,文章,深度教程层出不穷, 一句话总结来说, 不知道Docker 1.12都不好意思跟人打招呼了。
个人理解Docker 1.12最大的功能莫过于SwarmKit的引入,这应该算是Docker发展里程碑式的一个Release(上一个里程碑应该是runC和Containerd的剥离,标志着Docker公司自己孤独地玩到容器标准化概念引入),自此再也不要说Docker是主机容器管理了, Docker已经能够管理一群主机上的容器了。概念上Docker引入了node、service、task甚至更高于service一层的stack, 自此大家会发现容器和网络已经不是Docker的first-class概念, 取而代之的是service、 stack和跨主机网络。Docker SwarmKit的引入给容器编排投入了一颗重磅炸弹, 给我的感觉是原来容器编排还可以这么玩,终于不要某某sos和某8s的全家桶了, 在容器编排的远古时代(其实也不远,就是观念陈旧)不装个五六七八个组件都不好意思跟人说是编排, 真的有这个必要么? 当然了, Docker Swarm主要功能还是是借鉴了“远古时代”的几款产品, 吸收了前人的优秀经验。 让我列几个牛哄哄的功能给大家吧:
内置Raft, 妈妈再也不用担心我还要依赖Zookeeper、Etcd、Consul了, 光部署这些东西就浪费我一整天外加三台机器。
不区分管理节点和Worker节点,想让谁上就让谁上, 猜想是参考了人家Nomad吧, 关键还能运行时Promote、Demote, 太方便了。
Service,Stack外加DAB, 用过都说好, 方便。
Rolling Update, Scale一个Service,灰度发布分分钟搞定(虽然有点鸡肋),这个不用说也是借鉴了Kubernetes。
一张图展示一下Docker1.12的和老版本的功能对比。
当然当前Docker 1.12的功能还很初级,还没有听说过有人大规模生产级的应用(据说能管理2000个节点,10W个容器),不过看的出来SwarmKit team新功能推出的速度还是相当快的。 个人很看好这一趋势。
下面分享一下Docker的一个服务是如何被外部访问的。
在没有Docker的时代我们更喜欢的两种办法来部署一个服务 1, 单个机器上的单个进程,绑定到固定IP上的固定端口, 这种方式的优点是简单明了,程序员同学们需要做的事情最大化的优化单个进程的处理能力, 保障这个进程不会因为各种问题退出, 因为一旦退出就没得玩了。 2, 单个机器上的多个进程绑定到固定端口, 前面放一个代理工具。
容器化后大家发现以前的做法或多或少需要做些调整, 第一,由于主机概念被弱化,集群概念被突出, 应用程序不再依赖某个主机或者某个端口; 第二, 容器生命周期不固定, 容器可以随时被启动被停止, 容器的数量可多可少(这就是我们常说的弹性)。由于上面提到的两个容器化的特性,一些新的问题被引入,聪明的工程师们想到了一些解决办法来应对这些问题, 第一个解决办法就是我们要谈到的服务发现,针对的问题是服务对外地址不定和服务随时被启动停止。 服务被发现以后要解决是如何把任务按照一定规则负载到容器中, 这就是第二个我们要谈的负载均衡。 负载均衡解决了单一入口负载到多个容器上问题, 但是由于容器调度之后可能落到多个机器上, 假如某些主机上面没有工作的容器,而对外服务时候又希望服务可以被访问, Routing Mesh概念引入是解决多个入口点负载到单个容器的问题。
服务发现
单纯的服务发现很好实现, 无非就是监测Container的启动、停止, 根据这些变动记录下服务到底可以通过哪些IP+端口可以被访问, 理论上实现一个初级的可用的服务发现不会超过十行代码。成熟的服务发现还需要额外的工作比如健康检查, 注意到我们之前是假设了容器启动就可以对外服务, 实际中情况可能远非如此, 一个应用启动之后可能要准备环境, 加载数据之后才可以对外服务,健康检查是保证服务可用之后再对外服务。 另外一个成熟的服务发现必备条件是高可用, 明眼人可能已经发现之前的简单版本不具备高可用和状态一致性, 这也是为什么Docker引入了Raft协议。
负载均衡
传统理解的负载均衡根据协议不同可以分为7层的和4层的, 7层负载均衡特点是可以支持很复杂的用户规则,比如HTTP header、Cookie等应用逻辑, 而4层只能支持到IP地址负载不同服务。
Docker1.12的服务发现和负载均衡是结合到一起的, 实现办法有两种,DNS轮询和IPVS。 理解这两种策略之前需要知道的一个前提是Docker为每个服务都分配了一个虚拟IP, 这个IP对应的不是具体的一个Task或者一个具体的Container,而是专门为一个服务保留。
下面我们举例子分别说明一下两种负载均衡实现:
首先准备一下环境。
第一步如下图所示用Go写一段小代码, 编译成二进制放在一个ubuntu基础镜像里, 同时我的ubuntu里面安装了一些基础的网络工具, 比如dig、curl、 ping等, 保存成镜像ubuntu-base。
第二步, 根据Docker官方安装文档 我们在虚拟机环境里启动两个虚拟机, 构造一个Docker Swarm集群。
第三步, 创建一个Overlay网络, 取名overlay-test。
下面我们试一下DNS轮训模式的服务发现和负载均衡, 设置一个服务使用DNS轮询还是VIP, 只要设置好endpoint-mode这个参数就好, 如下图所示:
使用下面命令启动我们的服务:
docker service create –network overlay-test –name demo –replicas=4 –endpoint-mode=dnsrr ubuntu-base
—network overlay-test是指定使用刚刚创建的Overlay网络, –replicas=4 指定task数量, –endpoint-mode=dnsrr使用dnsrr方式做负载均衡。
启动成功后如下图所示:
当前机器上运行docker ps会发现有只有两个容器生成, 原因是另外两个task被调度到另外一台主机上。
下一步我们考虑进入容器中看一下虚拟出来的网络情况。
我们之前明明指定了使用overlay-test网络, 按理应该只有两块网卡, 实际上Docker却为我们生成了4块, 多出来的两块是Docker为容器做的手脚, 让我来一一讲解为什么会有4块网卡的出现。
lo网卡不用多说, 是本地网卡, 也叫回环网卡;
eth2属于之前创建的overlay-test网络;
eth1和docker_gwbridge网桥构成的网络可以使容器内的服务可以在主机上访问, 主机上telnet 172.18.0.4可以访问到我们的服务,如下图:
eth0是ingress网络中的一块网卡, 是为了Routing Mesh而设,稍后我们会详细说明。
继续回到容器里面看我们查看一下服务情况, 执行命令:
大家会发现通过服务名或者容器ID都能找到IP地址, 区别是服务名发现了本机上所有提供服务的容器IP, 至此同时实现了服务发现和内部负载均衡。
以上就是通过DNS轮询实现的服务发现和负载均衡, 这样的负载均衡是有一些缺点的, 比如:
一些应用可能缓存DNS请求, 导致容器变化之后DNS不能实时更新;
DNS生效时间也导致不能实时反映服务变化情况;
由于以上原因导致的负载均衡不够准确。
下面我来演示一下VIP和IPVS模式的服务发现和负载均衡。 VIP和IPVS原理上比较容易理解, 就是Docker为每个服务分配了一个VIP, DNS解析服务名称或者自定义的别名到这个VIP上。
由于VIP本身没有容器提供服务,Docker把到VIP的请求通过IPVS技术负载到后面的容器上。
Docker发布一个服务时候默认会选择VIP模式, 下面我们用同样的镜像演示一下。
docker service create –network overlay-test –name demo –replicas=4 –endpoint-mode=vip —publish 8080:8080 ubuntu-base
启动服务之后我们inspect一下, 会发现Virtual IPs有两个入口, 期中10.0.0.2就是overlay-test网络下面的一个Endpoint, 这个Endpoint是服务而非容器的。
我们进入容器中执行dig命令会发现:
此时DNS解析出来的是一个虚拟地址, 虚拟地址通过IPVS和一系列的iptables规则动态转发到容器中。 这样的负载均衡屏蔽了DNS轮询的时效性问题,同时可以支持UDP等协议, 性能也非常好。 缺点是不能做比如回话保持, 基于URL等应用层协议的规则的转发。
下面聊聊Routing Mesh, Routing Mesh的目的是每个主机上都为服务预留端口, 保证每台机器上都可以访问到服务。实现的办法就是Ingress网络, 之前我们提到容器中会多出一块网络,我们Inspect ingress网络,同时会发现网络对应的容器上多出一个容器 ingress-sbox
一个请求到主机端口8080之后, 数据包的流向如下所示:
主机端口8080 => Ingress-sbox-VIP:8080 => 容器Ingress-sbox => IPVS分发到containers。
大家可以看到访问主机之后数据包流到了一个特殊的Sandbox容器里, 这个容器和我们的容器共享一个Ingress网络,通过Iptables和IPVS等重定向到了最终容器之上。 达到了服务在任何一台主机的8080端口都可达的目的。
已上就是我理解的Docker SwarmKit的几种功能, 一些新的网络技术大家也在讨论,比如Macvlan和Ipvlan等, 通过这些技术Docker的应用场景越来越丰富, 越来越成熟, 让我们拭目以待。
国内首个基于Docker SwarmKit的容器管理面板——数人云Crane第一版最新出炉,欢迎点击“阅读原文”申请体验,点赞or吐槽都可以。
(转) Docker - Docker1.12服务发现,负载均衡和Routing Mesh的更多相关文章
- .net core grpc consul 实现服务注册 服务发现 负载均衡(二)
在上一篇 .net core grpc 实现通信(一) 中,我们实现的grpc通信在.net core中的可行性,但要在微服务中真正使用,还缺少 服务注册,服务发现及负载均衡等,本篇我们将在 .net ...
- .Net Core Grpc Consul 实现服务注册 服务发现 负载均衡
本文是基于..net core grpc consul 实现服务注册 服务发现 负载均衡(二)的,很多内容是直接复制过来的,..net core grpc consul 实现服务注册 服务发现 负载均 ...
- .net core Ocelot Consul 实现API网关 服务注册 服务发现 负载均衡
大神张善友 分享过一篇 <.NET Core 在腾讯财付通的企业级应用开发实践>里面就是用.net core 和 Ocelot搭建的可扩展的高性能Api网关. Ocelot(http:// ...
- Docker(二)-在Docker中部署Nginx实现负载均衡(视频教程)
本教程介绍利用Docker部署Nginx服务实现负载均衡. (双击全屏播放)
- 关于Ocelot和Consul 实现GateWay(网关) 服务注册 负载均衡等方面
Ocelot 路由 请求聚合 服务发现 认证 鉴权 限流熔断 内置负载均衡器 Consul 自动服务发现 健康检查 通过Ocelot搭建API网关 服务注册 负载均衡 1. ...
- 解决docker中使用nginx做负载均衡时并发过高时的一些问题
# 解决docker中使用nginx做负载均衡时并发过高时的一些问题 1.问题产生原因: 由于通过nginx作为负载均衡服务,在访问并发数量达到一定量级时jmeter报错. nginx日志关键信息:a ...
- 搭建服务与负载均衡的客户端-Spring Cloud学习第二天(非原创)
文章大纲 一.Eureka中的核心概念二.Spring RestTemplate详解三.代码实战服务与负载均衡的客户端四.项目源码与参考资料下载五.参考文章 一.Eureka中的核心概念 1. 服务提 ...
- 一起来学Spring Cloud | 第三章:服务消费者 (负载均衡Ribbon)
一.负载均衡的简介: 负载均衡是高可用架构的一个关键组件,主要用来提高性能和可用性,通过负载均衡将流量分发到多个服务器,多服务器能够消除单个服务器的故障,减轻单个服务器的访问压力. 1.服务端负载均衡 ...
- RabbitMQ(四):使用Docker构建RabbitMQ高可用负载均衡集群
本文使用Docker搭建RabbitMQ集群,然后使用HAProxy做负载均衡,最后使用KeepAlived实现集群高可用,从而搭建起来一个完成了RabbitMQ高可用负载均衡集群.受限于自身条件,本 ...
随机推荐
- vue 的小秘密
1.组件可以通过$refs调用其方法. 2.组件上也可用v-model. <input v-model="something"> == 同等 <input v-b ...
- Selenium学习笔记(1) - 自动化测试体系与原理
技术体系 基于代码的测试(Code-Based Testing) 基于协议的测试(Protocol-Based Testing) 基于界面的测试(GUI-Based Testing) 工作原理 基于代 ...
- IOS-导航路线
1.可以将需要导航的位置丢给系统自带的APP进行导航 2.发送网络请求到公司服务器获取导航数据, 然后自己手动绘制导航 3.利用三方SDK实现导航(百度) >当点击开始导航时获取用户输入的起点和 ...
- jQuery 图片自动播放
var imgArray = new Array("images/1.jpg", "images/2.jpg","images/3.jpg" ...
- python基础之迭代器协议和生成器(二)
一.什么是迭代器: 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器是一个可以记住遍历的位置的对象. 迭代器的 ...
- NSSet基本使用
int main(int argc, const char * argv[]) { @autoreleasepool { //创建一个集合对象 注:如果集合中写了两次或多次同一个对象 打印只能看到一个 ...
- 在 Ubuntu 上搭建 Hadoop 分布式集群 Eclipse 开发环境
一直在忙Android FrameWork,终于闲了一点,利用空余时间研究了一下Hadoop,并且在自己和同事的电脑上搭建了分布式集群,现在更新一下blog,分享自己的成果. 一 .环境 1.操作系统 ...
- Android Broadcast 和 BroadcastReceiver的权限机制
在Android应用开发中,有时会遇到以下两种情况, 1. 一些敏感的广播并不想让第三方的应用收到 : 2. 要限制自己的Receiver接收某广播来源,避免被恶意的同样的ACTION的广播所干扰. ...
- 10.排序数组中和为给定值的两个数字[Find2NumbersWithGivenSum]
[题目] 输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字.要求时间复杂度是O(n).如果有多对数字的和等于输入的数字,输出任意一对即可. 例如输入数组1 ...
- R 语言赋值运算符:`<-` , `=`, `<<-`
<- 与 = 间的区别 <- 与 = 在大部分情况下是应该可以通用的.并且,相对于 <<- 运算符,它们的赋值行为均在它们自身的环境层(environment hierarch ...