看到一篇介绍 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主要功能还是是借鉴了“远古时代”的几款产品, 吸收了前人的优秀经验。 让我列几个牛哄哄的功能给大家吧:

  1. 内置Raft, 妈妈再也不用担心我还要依赖Zookeeper、Etcd、Consul了, 光部署这些东西就浪费我一整天外加三台机器。

  2. 不区分管理节点和Worker节点,想让谁上就让谁上, 猜想是参考了人家Nomad吧, 关键还能运行时Promote、Demote, 太方便了。

  3. Service,Stack外加DAB, 用过都说好, 方便。

  4. 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块网卡的出现。

  1. lo网卡不用多说, 是本地网卡, 也叫回环网卡;

  2. eth2属于之前创建的overlay-test网络;

  3. eth1和docker_gwbridge网桥构成的网络可以使容器内的服务可以在主机上访问, 主机上telnet 172.18.0.4可以访问到我们的服务,如下图:

  4. eth0是ingress网络中的一块网卡, 是为了Routing Mesh而设,稍后我们会详细说明。

继续回到容器里面看我们查看一下服务情况, 执行命令:


大家会发现通过服务名或者容器ID都能找到IP地址, 区别是服务名发现了本机上所有提供服务的容器IP, 至此同时实现了服务发现和内部负载均衡。

以上就是通过DNS轮询实现的服务发现和负载均衡, 这样的负载均衡是有一些缺点的, 比如:

  1. 一些应用可能缓存DNS请求, 导致容器变化之后DNS不能实时更新;

  2. DNS生效时间也导致不能实时反映服务变化情况;

  3. 由于以上原因导致的负载均衡不够准确。

下面我来演示一下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的更多相关文章

  1. .net core grpc consul 实现服务注册 服务发现 负载均衡(二)

    在上一篇 .net core grpc 实现通信(一) 中,我们实现的grpc通信在.net core中的可行性,但要在微服务中真正使用,还缺少 服务注册,服务发现及负载均衡等,本篇我们将在 .net ...

  2. .Net Core Grpc Consul 实现服务注册 服务发现 负载均衡

    本文是基于..net core grpc consul 实现服务注册 服务发现 负载均衡(二)的,很多内容是直接复制过来的,..net core grpc consul 实现服务注册 服务发现 负载均 ...

  3. .net core Ocelot Consul 实现API网关 服务注册 服务发现 负载均衡

    大神张善友 分享过一篇 <.NET Core 在腾讯财付通的企业级应用开发实践>里面就是用.net core 和 Ocelot搭建的可扩展的高性能Api网关. Ocelot(http:// ...

  4. Docker(二)-在Docker中部署Nginx实现负载均衡(视频教程)

    本教程介绍利用Docker部署Nginx服务实现负载均衡. (双击全屏播放)

  5. 关于Ocelot和Consul 实现GateWay(网关) 服务注册 负载均衡等方面

    Ocelot   路由  请求聚合  服务发现 认证  鉴权 限流熔断 内置负载均衡器 Consul   自动服务发现    健康检查 通过Ocelot搭建API网关   服务注册   负载均衡 1. ...

  6. 解决docker中使用nginx做负载均衡时并发过高时的一些问题

    # 解决docker中使用nginx做负载均衡时并发过高时的一些问题 1.问题产生原因: 由于通过nginx作为负载均衡服务,在访问并发数量达到一定量级时jmeter报错. nginx日志关键信息:a ...

  7. 搭建服务与负载均衡的客户端-Spring Cloud学习第二天(非原创)

    文章大纲 一.Eureka中的核心概念二.Spring RestTemplate详解三.代码实战服务与负载均衡的客户端四.项目源码与参考资料下载五.参考文章 一.Eureka中的核心概念 1. 服务提 ...

  8. 一起来学Spring Cloud | 第三章:服务消费者 (负载均衡Ribbon)

    一.负载均衡的简介: 负载均衡是高可用架构的一个关键组件,主要用来提高性能和可用性,通过负载均衡将流量分发到多个服务器,多服务器能够消除单个服务器的故障,减轻单个服务器的访问压力. 1.服务端负载均衡 ...

  9. RabbitMQ(四):使用Docker构建RabbitMQ高可用负载均衡集群

    本文使用Docker搭建RabbitMQ集群,然后使用HAProxy做负载均衡,最后使用KeepAlived实现集群高可用,从而搭建起来一个完成了RabbitMQ高可用负载均衡集群.受限于自身条件,本 ...

随机推荐

  1. Netty(RPC高性能之道)原理剖析

    1,Netty简述 Netty 是一个基于 JAVA NIO 类库的异步通信框架,用于创建异步非阻塞.基于事件驱动.高性能.高可靠性和高可定制性的网络客户端和服务器端 RPC高性能分析,请参考文章“[ ...

  2. MVVM架构说明1

    MVVM是Model-View-ViewModel的简写.微软的WPF带来了新的技术体验,如Sliverlight.音频.视频.3D.动画……,这导致了软件UI层更加细节化.可定制化.同时,在技术层面 ...

  3. pxcook-高效易用的自动标注工具, 生成前端代码

    1.pxcook.sketch(http://www.fancynode.com.cn/pxcook)

  4. puppet笔记

    简介: puppet是一种Linux.Unix平台的集中配置管理系统,使用ruby语言,可管理配置文件.用户.cron任务.软件包.系统服务等.puppet把这些系统实体称之为资源,puppet的设计 ...

  5. kvm学习篇

    云计算:一种资源的使用模式 弹性,按需付费资源降低成本 公有云:亚马逊.阿里云私有云:混合云: 安装: yum install qemu-kvm qemu-kvm-tools virt-manager ...

  6. 【lightoj-1039】A Toy Company(BFS)

    The toy company "Babies Toys" has hired you to help develop educational toys. The current ...

  7. C++中关于标准输出流cout中使用递增运算符的问题

    今天听同学提起一个问题,在C++中运行下面的语句会得到什么结果: ; cout << a++ << a++ << a++; 起初我个人想当然地认为会输出012,然而 ...

  8. java String 转 Long 两种方法区别

    Long.ValueOf("String")返回Long包装类型 包装类型: Byte,Integer,Short,Long,Boolean,Character,Float,Dou ...

  9. kubernetes1.7正式发布

    Kubernetes发布历史回顾 Kubernetes 1.0 - 2015年7月发布 Kubernetes 1.1 - 2015年11月发布 Kubernetes 1.2 - 2016年3月发布 K ...

  10. Could not publish to the server.Please assign JRE to the server

    1.错误描述 2.错误原因 由错误提示可知,是Tomcat未绑定JRE,导致报错 3.解决办法 (1)删除新建Tomcat (2)重新新建一个Tomcat,配置好Tomcat路径和JRE路径