在生产环境中使用Apache Mesos和Docker
本文翻译自 IVO VERBERK博客,Docker容器软件已受到了从科技巨头到企业的广泛注意。但是,随着容器概念转变成为现实世界中的成熟技术,那么问题就变成了:怎么样才能快速把Docker应用于生产环境中呢?
介绍
在生产环境中安全有效地的运行Docker容器会有很多复杂的挑战。许多复杂性挑战都是在跨多主机间运行容器产生的。这些跨主机的容器可能需要保持或共享状态,也可能需要相互通信,还可能会随时消失。为了高容错性和可用性,你需要一个自动化的基础平台来关注存储、网络、容器调度和负载均衡等。
在这篇文章里,我将会描述一个基于Apache Mesos的Docker架构。我认为,作为一个为Docker容器提供跨主机间运行的平台,Mesos在性能和成熟度方面已经经过了严格的测试。这篇文章的目的是通过快速地开始和实践来升级Docker在生产中的架构。在这里,我不会深入解释所有(魔鬼)脚本,大部分脚本只需简单地用Vagrant启动虚拟机就可以了。如果你在技术实现上有任何问题请留下你的评论。
我们首先来看看总体架构。
架构
Docker registry: 保证每个Docker镜像的来源
Nginx: 为Docker容器提供负责均衡
Apache Mesos: 作为开启Docker任务的集群调度器
Mesosphere Marathon: 负责所有Docker容器的生命周期
Consul(-template): 为发现和动态配置提供服务
Registrator: 为发现Docker容器提供服务
安装
我已经创建了一个Vagrant安装配置,它可以在你的本地电脑上运行所有的栈。为了使它能够成功运行,你需要把下面的入口添加到本地的hosts文件中:
192.168.33.11 mm1.localdomain mm1 192.168.33.12 mm2.localdomain mm2 192.168.33.13 mm3.localdomain mm3 192.168.33.14 ms1.localdomain ms1 192.168.33.15 ms2.localdomain ms2 192.168.33.16 ms3.localdomain ms3 192.168.33.21 ms4.localdomain ms4 192.168.33.20 app-test app-production
下一步,你需要复制我的GitHub库获得所有必要的脚本,设置和辅助文件。下面的所有命令都是在这个库的根目录下进行的。
脚本用于提供配置虚拟机,它只会在第一次创建虚拟机时才运行。如果由于某些原因脚本没有运行成功你可以通过下面的命令触发它:vagrant provision {{vm name}}
注意由于需要下载很多安装包和Docker镜像,有时为了等待脚本运行完,这条命令运行需要一些时间。
Docker仓库
首先,我们需要一个私人的Docker仓库,因此我们就可以确保Docker镜像的来源。这个Docker仓库将会在容器内运行,它将会通过一个永久的容器数据库本地存储这些镜像。vagrant up registry
这个仓库会在IP地址为192.168.33.19上可用。我就可以在不采取任何安全措施下使用这个仓库。虽然在生产环境中这显然是一个错误的做法,但是对于本地测试环境使用这会是一个很好的选择。为了使用不安全的仓库你需要在你的docker daemon中添加一些选项:--insecure-registry 192.168.33.19:5000
对于boot2docker或Docker机器来说,你可以在/var/lib/boot2docker/profile (ssh into the vm first)找到daemon选项。
Nginx 负载均衡
接下来,我们需要一些负责均衡器来路由流入后台容器的流量。为此,我们会用一个定制的Nginx容器来完成,为了动态更新和重载配置,Nginx容器会运行consul-template。
cd Docker/Nginx docker build -t 192.168.33.19:5000/nginx . docker push 192.168.33.19:5000/nginx
看看github仓库上的镜像配置。基本上,consul-template会一直监听Consul中任何应用服务的改变和相应地重新加载Nginx的配置。
创建两台准备运行Nginx容器的虚拟机:vagrant up lb1 lb2
这两台负载均衡器会通过vrrp协议彼此通信,除非其中一个掉线了,否则虚拟IP将不会失效。运行的负载均衡器在IP地址为192.168.33.20和前面添加应用测试或应用生产记录的本地hosts文件中的IP上可用。
Mesos: masters and slaves
我们至少需要3个Mesos master节点来确保完全控制集群。正如上面架构图所示,master服务器上也会运行Consul服务器,Marathon框架,ZooKeeper和Registrator容器。相对于http://www.ivoverberk.nl/towar ... esos/目前Zookeeper作为Mesos的的先决条件,我更倾向于用Consul作为发现需要的服务,因为Consul提供了很多好的优势以及consul-tempate会是一个额外的好工具。对于master节点,Registrator并不是严格必须的;但是为了一致性我在Mesos的master节点和slave节点上都添加了它。Marathon framework会帮我们管理Docker容器的生命周期。开启Master节点:vagrant up mm1 mm2 mm3
它会按序地开启虚拟机。如果单独地同时在不同的终端上创建这些虚拟机速度会快很多。运行实际的Docker容器时需要一些Mesos slave节点。我们已经创建了4个slave节点。其中的两个(ms1和ms2)在测试环境中使用,其他两个(ms3和ms4)在生产环境中使用。Registrator可以添加或删除Consul服务目录中的任何容器。开启第一个slave节点:vagrant up ms1
在第一个slave节点安装完成后,开启剩下的节点:vagrant up ms2 ms3 m4
第一个slave节点充当NFS服务器,它是其他slave节点成功完成它们的脚本运行的前提条件。我选择用NFS作为介绍分布式文件系统的简单方式。
你也可以考虑其他选择比如GlusterFS、Ceph等文件系统。如果它们更适合你的环境,你也可以跳过使用本地分布式存储系统而去寻找基于云的解决方案。
概观
好了,到目前为止,我们已经在我们的本地机器上拥有了一个完整的Mesos栈。现在,我们可以看看这些组成部分是怎么样相互协作创建生产平台的Docker。通过下面的URL可以使用基于web的GUI接口:
http://mm1.localdomain:5050 (Mesos)
http://mm1.localdomain:8080 (Marathon)
http://mm1.localdomain:8500 (Consul)
在Mesos的接口上,你应该可以看到4个运行的slave节点和一个运行的Marathon框架。对于Consul应该只有两个入口和Marathon应该提供了一个空应用概述。
应用部署
在里面,我已经包含了一个小的演示应用(Notejam)可以测试我们框架。Notejam是一个简单的记笔记应用,它创建了一个登陆会话和在sqlite3数据库上创建了一个存储信息的文件。建立一个Docker镜像我们才能够部署:
cd Docker/App docker build -t 192.168.33.19:5000/app . docker push 192.168.33.19:5000/app
看看github仓库上的镜像配置。把我们刚刚建立的镜像部署到集群中的测试slave节点上:
cd Docker/App APP_VERSION=latest APP_ENV=test ./deploy.sh
检查Marathon接口看看部署是不是已经开始了。由于镜像需要从slave节点上拉取下来,第一次运行可能需要一些时间。如果这三个容器已经开启了你可以跳到: http://app-test。这个应用应该可见。在页面底部应该有一个状态线,这表明这个环境中的应用是在运行的和环境中的容器是在被服务的,刷新这个页面将会展现这个应用是被多个后台提供服务的。
现在我们升级我们的应用到集群中的生产节点上:
cd Docker/App APP_VERSION=latest APP_ENV=production ./deploy.sh
这个应用现在应该可以在http://app-production上访问的到。我希望你能看到把这个步骤应用到自动化部署是非常容易的。在这个架构概览中,你可以找到必要组成部分。
你可以通过Marathon接口添加或减少后台容器的数量。负载均衡器会随着容器的变化自动更新。
未来
虽然这篇博客中描述的安装配置是一个可靠的,非常简单的初级的预生产Docker架构,但是,在某些领域还有一些未解决的问题比如存储,网络和管理。接下来一系列博客文章将会专注于深入探索这些领域。