资讯专栏INFORMATION COLUMN

进军Docker 1.12,将代理与Swarm完美整合

cartoon / 522人阅读

摘要:其一将用于代理与面向公开的服务之间的通信。数据库上线并开始运行后,我们接下来部署后端。现在,会帮助我们完成全部负载均衡工作。这样所有来自代理的请求都将指向网络,并由后者跨越全部实例执行负载均衡。

七夕大家过得怎么样?今天数人云带大家回归技术和干货。虽然我们能够在Swarm集群当中部署任意数量的服务,但这并不代表各项服务全部可为用户所访问。而新的Swarm网络使得各项服务之间能够更为轻松地实现彼此通信。

下面我们将共同探讨如何利用其对各服务进行公开。我们还将尝试将一套代理机制整合至Swarm网络当中,从而更为充分地发挥1.12版本带来的优势。

在开始进行之前,我们需要设置一套用于演示的集群。

环境设置

要完成本示例,我们假定大家已经拥有一套版本为v0.8或者更高的Docker Machine,其中包含版本为v1.12或者更高的Docker Engine。最便捷的获取方法就是通过Docker Toolbox下载。

如果您是Windows用户,请利用Git Bas运行全部示例(通过Docker Toolbox安装)。

 docker-machine create -d virtualbox node-1
 docker-machine create -d virtualbox node-2
 docker-machine create -d virtualbox node-3
 eval $(docker-machine env node-1)
 docker swarm init 
    --advertise-addr $(docker-machine ip node-1) 
    --listen-addr $(docker-machine ip node-1):2377
 TOKEN=$(docker swarm join-token -q worker)
 eval $(docker-machine env node-2)
 docker swarm join 
    --token $TOKEN 
    $(docker-machine ip node-1):2377
 eval $(docker-machine env node-3)
 docker swarm join 
    --token $TOKEN 
    $(docker-machine ip node-1):2377`

现在我们已经拥有了一套Swarm集群,接下来是部署一项服务。


包含三个节点的Docker Swarm集群

向集群中部署服务

为了检验新的Docker Swarm网络功能,我们首先创建以下两套网络。

 eval $(docker-machine env node-1)
 docker network create --driver overlay proxy
 docker network create --driver overlay go-demo

其一(proxy)将用于代理与面向API公开的服务之间的通信。而其二(go-demo)则面向全部用于构建go-demo服务的容器。该服务包含两套容器,且利用MongoDB用于存储数据,而vfarcic/go-demo则作为配备API的后端。

我们将从数据库起步。由于其不会公共开放,因此不需要将其添加至代理当中。这里,我们直接将其附加至go-demo网络。

  docker service create --name go-demo-db 
  --network go-demo 
  mongo

数据库上线并开始运行后,我们接下来部署后端。由于我们希望外部用户能够使用该API,因此应当将其纳入代理。我们将其同时附加至两套网络(proxy与go-demo)。

  docker service create --name go-demo 
  -e DB=go-demo-db 
  --network go-demo 
  --network proxy 
  vfarcic/go-demo


由三台节点、两套网络与多套容器构成的Docker Swarm集群

现在两套容器都运行在集群当中,且能够彼此通过go-demo网络进行通信。下面将代理引入其中。我们这里使用HAProxy。

需要注意的是,我们并没有指定端口,这意味着没有任何一套容器能够为go-demo网络之外的请求所访问。

设置一项代理服务

我们可以通过多种方式建立代理机制。其一利用HAProxy创建一套新镜像,其中包含各配置文件。这种方式比较适合服务数量相对固定的情况。否则,我们应当创建一套每当有新服务(而非新版本发布)出现时即进行新配置的镜像。

通过第二种方法,其将以分卷形式存在,我们能够在必要时仅修改配置文件而非整套新镜像。然而,这种作法也存在弊端。在部署至一套集群时,我们应当尽可能避免使用分卷。接下来大家会看到,代理就是不需要分卷的机制之一。另外,--volume可替换为docker service命令中的—mount参数。

第三种选项是使用专门与Docker Swarm协作的代理之一。在这种情况下,我们将使用vfarcic/docker-flow-proxy容器,其由Docker Flow: Proxy项目创建而成。其基于HAProxy且拥有多项其它功能,允许我们通过发送HTTP请求对其进行重新配置。

下面一起来看:

  docker service create --name proxy 
    -p 80:80 
    -p 443:443 
    -p 8080:8080 
    --network proxy 
    -e MODE=swarm 
    vfarcic/docker-flow-proxy`

我们开启的端口80与443将负责处理互联网流量(HTTP与HTTPS)。第三个端口则为8080,我们将利用它向代理发送配置请求。另外,我们强调其应当归属于proxy网络。如此一来,由于go-demo也被附加至同一套网络,意味着代理能够通过SDN对其进行访问。

在这套代理的帮助下,我们实现了最实用的网络路由功能之一。无论大家在哪台服务器上运行该代理,我们都能够向任意节点发送请求,而Docker网络会确保其被重新定向至代理之一。

最后一项参数为环境变量MODE,其负责告知该代理,各容器将被部署至Swarm集群当中。请参阅项目的README文件以了解更多细节信息。

配合代理服务的Docker Swarm集群

需要注意的是,该代理即使已经运行在某一节点当中,仍会被放置于其外以表达其在逻辑上的分离特性。

在开始之前,首先确认代理正在运行。

docker service ps proxy

如果其“最新状态(Last state)”为“运行(Running)”,则可继续。如果不然,请等待直到该服务上线并开始运行。

现在代理已经部署完成,我们应当确保其知晓go-demo服务的存在。

curl "$(docker-machine ip node-1):8080/v1/docker-flow-proxy/reconfigure?serviceName=go-demo&servicePath=/demo&port=8080"

这条请求的作用是重新配置代理以指定服务名称(go-demo)、API的URL路径(/demo)以及该服务的内部端口(8080)。从现在开始,所有指向该代理且使用以/demo开头路径的请求都将被重新定向至go-demo服务。

现在我们可以测试代理是否按预期运行——发送一条HTTP请求进行验证。

curl -i $(docker-machine ip node-1)/demo/hello

该curl命令的输出结果如下所示。

HTTP/1.1 200 OK
Date: Mon, 18 Jul 2016 23:11:31 GMT
Content-Length: 14
Content-Type: text/plain; charset=utf-8
 hello, world!

代理正常起效!它响应了HTTP status 200并向API返回了hello,world!

需要注意的是,这一过程与我们执行操作所在的具体节点无关。由于Docker网络(路由体系)负责实现负载均衡,因此我们能够前往任意服务器。作为示例,下面我们发送同样的请求,但这一次立足于node-3。

curl -i $(docker-machine ip node-3)/demo/hello

结果仍然完全相同。

下面让我们一起了解由该代理生成的配置。

代理配置

如果大家选择自行构建代理解决方案,那么当然需要了解如何配置代理并利用Docker网络中的各项新功能。

下面首先检查Docker Flow: Proxy为我们创建的配置。我们可以进入当前运行的容器并通过/cfg/haproxy.cfg文件查看这部分信息。不过问题是,找到由Docker Swarm运行的一套容器需要配合一点技巧。举例来说,如果我们利用Docker Compose部署此容器,那么其名称会存在一定规律,即使用__格式。而docker service命令会利用散列后的名称运行容器。在我的笔记本上,docker-flow-proxy的创建名称为proxy.1.e07jvhdb9e6s76mr9ol41u4sn。因此,要进入由Docker Swarm部署并运行的容器,我们需要对镜像名称进行过滤。

第一步,我们需要找到代理运行所在的具体节点。

docker service ps proxy

需要注意的是该node列中的值,同时确保在以下命令中使用该正确值。

eval $(docker-machine env node-1) # Change node-1 with the node value previously obtained

此命令将给出以下代理配置输出结果。

 docker exec -it 
    $(docker ps -q --filter "ancestor=vfarcic/docker-flow-proxy") 
    cat /cfg/haproxy.cfg
 exit

配置信息中最重要的部分如下所示。

 frontend services
    bind *:80
    bind *:443
    option http-server-close
    acl url_go-demo path_beg /demo
    use_backend go-demo-be if url_go-demo
 backend go-demo-be
    server go-demo go-demo:8080

对于第一部分(frontend),熟悉HAProxy的朋友应该不会感到陌生。其接收来自端口80(HTTP)以及443(HTTPS)的请求。如果路径以/demo开头,其会被重新定向至后端go-demo处。在这里,各请求会被发送至go-demo在端口8080上的地址。此地址同时亦是我们所部署的服务名称。由于go-demo同proxy存在于同一网络当中,因此Docker能够确保该请求被重新定向至目标容器。很简单,对吧?我们无需再另行指定IP以及外部端口。

接下来的问题是,如何实现负载均衡。举例来说,我们要如何指定该代理跨越全部实例执行循环?

负载均衡

在开始进行负载均衡解释之前,首先创建几个go-demo服务实例。

 eval $(docker-machine env node-1)
 docker service scale go-demo=5

稍等一会儿,就将有5个go-demo服务实例开始运行。


包含规模化go-demo服务与代理实例的Docker Swarm集群

我们该如何让代理将请求均衡至全部实例当中?答案是不用——我们并不需要执行特别的操作。

正常来讲,如果我们不使用Docker Swarm功能,则可使用以下配置方式:

backend go-demo-be
    server instance_1 :
    server instance_2 :
    server instance_3 :
    server instance_4 :
    server instance_5 :

然而在新的Docker网络当中,我们将不再需要进行上述配置。原本的作法只会在新副本添加或者删除时,给我们的实例监控与代理更新工作造成麻烦。

现在,Docker会帮助我们完成全部负载均衡工作。更准确地讲,当该代理将某条请求重新定向至go-demo时,其实际将其发送至Docker网络并由后者执行跨越全部服务副本(实例)的负载均衡。这套方案的意义在于,代理负责将端口80(或者443)重新定向至网络中的正确服务处,其它任务则全部由Docker完成。

大家可以随意向该服务发送更多请求,并检查其中一套副本的日志记录。在这里,大家会发现其接收到的请求约为总体请求数量的五分之一——与我们的服务实例数量恰好吻合。

总结

Docker网络与Docker 1.12及更高版本提供的Swarm相结合,无疑开启了一道通向更多新机遇的大门。不同容器与负载均衡之间的内部通信只是其中的一小部分,我们亦可以更为轻松地配置公开代理。另外,我们需要确保面向API进行公开的全部服务皆以代理形式接入同一网络。在此之后,我们要做的就是进行配置以将所有请求重新定向至目标服务名称。这样所有来自代理的请求都将指向Docker网络,并由后者跨越全部实例执行负载均衡。

但新的问题在于,这套方案的具体效率是否理想。毕竟我们在体系中引入了新的层。尽管过去我们也会使用代理以及服务,但现在Docker网络会在二者之间建立负载均衡机制。答案是,由此带来的运行负担非常有限。Docker利用Linux IPVS实现负载均衡,其作为Linux内核的组成部分已经拥有超过15年历史,而且事实证明其是一种极为高效的负载均衡实现方式。事实上,其速度表现远远优于nginx或者HAProxy。

下一个问题是,我们是否需要代理机制。是的,当然需要。DOcker所使用的IPVS只负责实现负载均衡。我们还需要一套代理以接收来自端口80与443的请求,并根据其实际路径将其重新定向至各目标服务。在此基础之上,我们还可以利用它执行多种任务,包括SSL握手以及验证等等。

那么这种作法存在哪些缺点?首先想到的肯定是粘性会话。如果我们希望同一用户向同一实例发送请求,那么这套方案显然并不适用。另一个问题是,我们是否应当在服务之内实现粘性会话,或者应该将其作为独立实体。这个问题我们在本文中暂时不作讨论,只需要明确这里提到的方案并不适用于粘性会话即可。

那么其具备哪些优势?首先,整个实现过程非常简单。我们用不着在部署新副本时对代理进行重新配置。如此一来,整个流程将非常便捷。由于我们不需要包含全部端口IP及端口的列表,因此也就无需使用Registrator以及Consul Template之类的工具。过去,我们需要利用Registrator以监控Docker事件,并将IP及端口保存在键值存储方案(例如Consul)当中。信息存储完成后,我们会利用Consul Template重新创建代理配置。虽然不少项目都能简化这一流程,但Docker Swarm与Docker网格的再现从根本上降低了其实施难度。

Docker Flow: Proxy——要还是不要?

在本文中,我们讲述了如何利用Docker Flow: Proxy项目配置HAProxy。其中包含HAProxy及一系列其它API,允许我们利用简单的HTTP请求对代理进行重新配置。另外,其还消除了对手动配置或者模板的依赖性。

在另一方面,建立自定义解决方案的流程也变得更为简单。本文只稍稍列举几项重点即解释了整个构建过程,这在nginx或者HAProxy配置工作中是完全无法想象的。

所以我的建议是先尝试一下Docker Flow: Proxy,而后再做决定。

接下来该做些什么?

今天我们已经总结了Docker v1.12带来的一系列Swarm与网络新功能,特别是在公开代理方面的改进。

那么我们是不是就能够成功运行Swarm群集了呢?还差得远!本文仅仅只是开始,我们还有大量问题有待回答。Docker Compose发生了哪些改变?我们该如何在不造成停机的前提下部署新版本?是否还有其它值得一试的工具?

后续的内容,也敬请大家期待!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/26672.html

相关文章

  • 代码级干货 | 进阶Docker 1.12,全新的分布式应用捆绑包

    摘要:利用分布式应用捆绑包简称部署服务相较于利用大量参数创建网络及服务,这里我们选择使用一个文件。 在Docker 1.12版本中,全新的Swarm捆绑包相较于原有编排及调度机制做出了巨大改进。它不再需要运行一组独立的Swarm容器,这部分容器已经被直接捆绑在Docker Engine当中,故障转移策略更为可靠,服务发现机制实现内置,新的网络功能极为顺畅……看起来很棒是不是? 数人云这...

    2i18ns 评论0 收藏0
  • Docker 1.12的哪些特性使它更像 kubernetes?

    摘要:本文涵盖了中的六大新特性内置命令服务发现自愈功能安全负载均衡滚动升级,相关的使用文档和视频链接也都包含在里面。同时,内部负载均衡要求一个可用的容器。现在开箱即用的负载均衡,上公开暴露的端口在所有节点都是可以访问的。 Docker 1.12版本最近刚刚发布,这篇文章对它的新特性进行了概述和对比描述。本文涵盖了 Docker 1.12 中的六大新特性:内置 swarm命令、服务发现、自愈功...

    chaos_G 评论0 收藏0
  • 代码篇 | Docker1.12+Swarm构建动态微服务应用

    摘要:首先启动该命令。这项机制在实际生产当中无疑非常重要。那么下面我们回顾一下之前了解到的信息我们创建了一款小型动态微服务应用,完全由构成。在多数情况下,这能够为应用后端服务建立起独立的代理机制。 这次数人云与大家分享的文章里,主要介绍了Docker Swarm如何凭借革新对整体场景进一步加以简化。事实上,如今我们已经可以轻松且直观地构建起一套Docker Swarm集群,快来一起体验一下吧...

    JellyBool 评论0 收藏0
  • 关于Docker 1.12中的最新功能,你需要了解这些

    摘要:已然落幕,留下了无数激动人心的声音。随着版本的发布,众多新功能新提升的出现,无疑将对为中心的生态圈产生不小的影响。很明显,部分变更将帮助更好地完成规模化使命,甚至可以说这一规模化发展思路正是本届大会的主旨所在。 DockerCon已然落幕,留下了无数激动人心的声音。随着Docker1.12版本的发布,众多新功能新提升的出现,无疑将对Docker为中心的生态圈产生不小的影响。今天小数与大...

    wua_wua2012 评论0 收藏0
  • Docker Swarm在生产环境中的进阶指南

    摘要:应该如何解决本文将给出若干提示,如何在生产环境中使用。路由匹配服务发现负载均衡跨容器通讯非常可靠。在单个端口上运行一个服务,节点的任意主机都可以访问,负载均衡完全在后台实现。 上周数人云给大家分享了——《你可能需要的关于Docker Swarm的经验分享》今天给大家带来这位作者大大的后续文章——《Docker Swarm在生产环境中的进阶指南》 当在本地开发环境中使用Docker,或者...

    galaxy_robot 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<