阿里云容器服务团队将为大家奉献一系列深入学习的文章来帮助大家了解docker 1.12的最新动态。
<a href="https://yq.aliyun.com/articles/55973">第一部分:在阿里云上体验docker 1.12内置的编排能力</a>
第二部分:在阿里云上体验docker 1.12的路由能力和容器应用分发部署 (本文)
docker 1.12除了提供内置的编排能力,也提供了服务路由支持 routing mesh,和新的多容器应用分发和部署机制。
这里我们先介绍两个概念
分布式应用打包 (distributed application bundle,简称dab):dab 是一个用于应用分发的文件格式,其中可以包含多个容器服务定义。
stack(应用栈):可以从一个dab文件创建一个应用栈实例,一个应用栈中包含多个服务实例。
如果你熟悉docker compose,这些概念听起来是不是很熟悉?一个docker compose模板中可以包含多个服务的描述,而利用compose模板可以创建一个完整的应用。但是docker compose本身被设计成为面向单机的开发工具,并不能对分布式应用进行部署、管理。而dab提供了一个标准化的分发格式解决了这个问题。另外docker提供了工具,可以将一个已有docker compose模板转换成dab格式,并部署为docker stack实例。
本文中,我们会部署一个wordpress dab应用到阿里云上的swarm模式docker集群中,其中包含两个服务wordpress和mysql。我们还会利用阿里云 slb实现wordpress任务容器的路由和负载均衡。
在这个环境中我们将创建一个三个ecs实例构成的swarm集群,其中一个是manager。另外我们会创建一个slb实例来实现服务的路由和负载均衡,集群中三个ecs实例都会作为slb的后端服务器。我们会在集群上部署应用,并配置服务路由。大概的拓扑示意图如下:
首先我们创建一个slb实例
slb创建成功之后,我们利用docker-machine来创建三个ecs节点来组成docker集群执行环境。
我们首先在命令行上配置一些共用的环境变量
然后我们可以通过如下命令在阿里云上创建3个ecs实例,它还会自动升级操作系统内核,安装配置最新的测试版docker引擎,并将新创建的slb实例添加为指定slb的后端服务器。
等待三个ecs实例会创建完成,我们可以通过如下命令登录到 node-1,初始化docker swarm集群,显示master节点的ecs内网"eth0"地址
上面的命令会返回如下内容
之后,我们把node-2和node-3作为worker加入docker swarm集群,执行<code>docker-machine ssh <node></code> 之后拷贝上文返回的第一个命令来添加一个worker节点
这样整个docker集群就已经创建成功了,现在我们来部署一个wordpress应用。
注:这一节是为了介绍dab的创建过程,心急的同学可以忽略。
这里我们可以看到它包含两个服务"wordpress"和"mysql", 我们可以利用 <code>docker-compose bundle</code> 命令生成dab格式文件。
注:目前dab/docker service/stack的能力还不完备,有很多docker compose声明还不能被正确处理,比如volume支持等等。
产生的"wordpress.dab"文件内容如下
我们要登录到集群的master节点来部署应用,首先我们从github上获取相应的示例文件
利用 <code>docker deploy</code>命令来部署"wordpress" stack,docker命令缺省会在本目录寻找同名的.dab文件作为stack部署描述。
之后,我们可以利用<code>docker service ls</code>和<code>docker stack tasks</code>命令来查看相应service/task状态
现在我们通过<code>docker service inspect</code>命令检查"wordpress_wordpress"服务状态
我们可以看到这个"wordpress_wordpress"服务发布了一个tcp端口“30000”来对外提供服务。那么我们怎么访问这个服务呢?
阿里云的slb提供了对多台ecs服务器进行流量分发的负载均衡服务。下面我们将利用slb服务来配置对swarm集群中的服务的路由和负载均衡。
首先添加侦听端口,我们选择"http"和"8080"(可以任选)作为前端协议[端口], "http"和"30000"作为后端的协议[端口]。注意 :后端端口必须与服务状态中的"publishedport"端口值保持一致。
配置健康检查配置时,可以把“/license.txt”作为检查路径,这样只要wordpress服务的apache可以被访问就认为服务是健康的
完成配置
随后,我们就会在slb负载均衡实例上看到相应的侦听端口和健康检查状态
访问slb实例的公网ip地址,我们就可以看到熟悉的wordpress设置界面了,
我们还可以利用<code>docker service scale</code>命令对服务进行伸缩,也可以试验一下负载均衡的效果
看完上面的示例,大家一定非常关心相应服务和路由的网络配置。我们就来简单分析一下。在"node-1"节点上,我们执行下面的命令
我们可以看到有两个集群范围的overlay网络"ingress"和"wordpress_default"。其中"ingress"是在集群创建之后就自动创建的接入路由网络,而后者是部署"wordpress.dab"的时候自动创建的。
如果没有手工指定,swarm manager会自动给需要对外访问的服务分配一个在30000-32767之内的publishedport。在上文中"wordpress_wordpress"所分配的端口为30000。
在swarm集群内的每个节点上,都侦听着相同的publishedport来为服务提供接入路由。所以我们可以在slb上配置一个侦听端口对集群中节点进行转发和负载均衡,而不管后端节点是否运行着服务的任务容器。swarm集群中的所有节点都可以通过ingress网络连接到运行的任务容器,并保证入口流量被引导到正确的容器实例上。
关于routing mesh的ingress网络的负载均衡,其设计如下图。我们可以看到每个服务实际上都被分配了一个虚拟ip,而虚拟ip到服务任务容器端口之间的负载均衡是通过ipvs来实现的。
注意:routing mesh的端口映射机制和bridge网络下容器publish端口的实现完全不同,不要混淆。
我们可以通过下面的命令来看看iptables中ecs节点主机端口到服务虚拟ip的转发配置
docker 1.12带来了新的分布式应用打包格式,可以给在集群上部署多容器应用带来很多便利。但是目前dab的能力和成熟度都有待提高,和docker compose的兼容性也存在一些问题,希望会在未来版本中逐渐解决。
如果你了解阿里云容器服务,会发现很多新swarm模式下的服务概念和我们实现有很多相似性。我们目前是通过对现有开源编排方案上做增强来提供类似的能力。比如我们扩展了docker compose中service的概念,加强生命周期管理,提供服务伸缩和自动恢复支持等。不远的未来我们也会提供平滑的升级,支持docker最新的编排技术。
在网络方面,docker swarm模式的routing mesh可以和外部的负载均衡技术结合。在阿里云上我们利用slb实现了docker服务路由和负载均衡。目前这个工作还需要一些手动工作来完成的,在稍后我们会推出全自动化的方式自动配置slb监听端口,让整个流程完全自动化。
此外,我们可以看到docker swarm模式和阿里云容器服务的路由设计原理上是类似的,只是容器服务中每个节点利用haproxy为服务提供7层或4层的路由实现,而docker engine是每个节点利用ipvs做为4层的路由实现。7层的优势在于可以支持virtual host、session affinity等较复杂的路由策略,而基于kernel空间的4层路由可以有更好的性能表现。我们计划会融合这些技术在阿里云容器服务中给大家带来更好的体验。