本文的作者是 Luke Marsden ,本文的原文地是 Deploying and migrating a multi-node ElasticSearch-Logstash-Kibana cluster using Docker
注:本文没有全部翻译,是摘取性翻译,只翻译本人认为关键的部分。要看全文请看原文
设置 ELK
首先,对 ELK 的各种组件和它们所扮演的角色做一个快速预览。
- Logstash 接收日志消息和转发它们到 ElasticSearch
- ElasticSearch 在数据库中存储这些日志消息
- Kibana 连接 ElasticSearch 来检索这些日志数据并通过一个 web 接口呈现它们
我们要做的第一件事情就是要把我们的三个应用以及它们的依赖关系打包进独立的 Docker。我已经为你做了这些,并放在 DockerHub 上:
部署 ELK 到一个多节点集群
使用 Flocker 工作有两个配置文件: application configuration 和 deployment configuration。让我们首先看下 application configuration
。
application configuration
是一个非常简单的 yaml 文件,它描述了你的应用是怎样由多个能相互通信的 Docker 容器组成。为此,我们通常把它作 application.yml
。如果你对 Docker 的 Fig 工具很熟悉的话,你将立刻认识到和 Flocker
的 application yml
很多相似的地方。
下面是需要启动所有三个容器的 application.yml
,还有端口映射,能让它们彼此通信,以及在 ElasticSearch 容器中创建一个 Flocker-managed 的 Docker 数据卷。
"version": 1
"applications":
"elasticsearch":
"image": "clusterhq/elasticsearch"
"ports":
- "internal": 9200
"external": 9200
"volume":
"mountpoint": "/var/lib/elasticsearch/"
"logstash":
"image": "clusterhq/logstash"
"ports":
- "internal": 5000
"external": 5000
"links":
- "local_port": 9200
"remote_port": 9200
"alias": "es"
"kibana":
"image": "clusterhq/kibana"
"ports":
- "internal": 8080
"external": 80
让我们特别值得注意的几件事:
- ElasticSearch 应用有一个卷和挂载点指定,在这个例子中是
/var/lib/elasticsearch
,Flocker 的一大优点就是有能力在两个主机之间可以迁移数据卷 -
links
允许容器之间相互交流,甚至当它们位于不同的主机 -
ports
代理一个 Docker 主机上的端口(”external”)到容器中的端口(”internal”)
部署 ElasticSearch
现在我们有我们自己的 ELK stack 镜像和定义的 application.yml
。我们需要部署这些容器到多个主机上。我在我们前面提到的第二份配置文件 deployment configuration
中指定我想把我们的容器部署到哪里。
在这个例子中,我们将部署每个服务到它自己的虚拟服务器。如果你希望这样做,你实际上可以使用任何主机并且步骤在虚拟机上同样有效。裸机,或是任何组合。比如,因为性能原因,你想在裸机上运行 ElasticSearch,但是为降低成本在虚机上运行 Logstash 和 Kibana,这取决于你,Flocker 是与底层主机无关的。
deployment config
也仅仅是一个 yaml 文件,deployment.yml
通过列出的一个或多个 IP 地址告诉 Flocker 去哪里部署每个容器和定义在 application.yml
的应用别名。
在这个例子中,我们部署我们每个容器到不同的虚机:
"version": 1
"nodes":
"172.16.255.250": ["elasticsearch"]
"172.16.255.251": ["logstash"]
"172.16.255.252": ["kibana"]
当我们使用 Flocker 提供的 CLI 工具运行 flocker-deploy 命令的时候,容器将被自动部署,做好网络和启动我们在部署配置中定义的服务器。
alice@mercury:~/flocker-tutorial$ flocker-deploy deployment.yml application.yml
alice@mercury:~/flocker-tutorial$
从一台服务器把 ElasticSearch 的数据迁移到另外一台
现在 ElasticSearch 已经在集群的多个节点部署了。但如果其中一个你的 ElasticSearch 查询消耗了你的 m3.large EC2 实例的 90% 可用内存,并且几分钟后你查询不出为什么。你不能真的提供缓慢的性能直到你查出性能差劲的根本原因,因此你想把 ElasticSearch 迁移到一个更大内存的服务器,15 GB 内存的 m3.xlarge 。
使用 Flocker,这会变得非常容易。仅仅需要用新的 IP 地址更新你的 deployment.yml
,然后重新运行 flocker-deploy,你的 ElasticSearch 容器和它的数据卷将被自动移动到新的节点,将已经正式去原来节点的连接自动路由到新的节点。
老的:
"version": 1
"nodes":
"172.16.255.250": ["elasticsearch"]
"172.16.255.251": ["logstash"]
"172.16.255.252": ["kibana"]
新的:
"version": 1
"nodes":
"172.16.255.250": []
"172.16.255.251": ["logstash"]
"172.16.255.252": ["kibana"]
"172.16.255.253": ["elasticsearch"]
这里说明了当你重新运行 flocker-deploy
从节点1去迁移 ElasticSearch 到节点2的时候发生了什么:
- Flocker 检查是否你已经改变了你的配置
- 因为它看起来你好像已经从 172.16.255.250 移动 ElasticSearch 到 172.16.255.253 了,它初始化一个迁移
- 迁移通过推送整个节点1的数据卷内容到节点2开始。在这个期间,节点1依然接受连接,因此你的用户或其他依赖于那些数据的进程不会感受任何连接问题
- 一旦所有的数据被拷贝完,运行在节点1的应用被关闭
- 数据被复制过来之后的任何对数据卷的改变这时将被复制,依赖于你的数据库多繁忙,这可能只是几百kb 的变化
- 一旦这些最后的少许改变被复制过来,Flocker 不干涉节点2的卷
- ElasticSearch 在节点2启动
我们称这个方式为 two-phase 推送,因为数据在两个阶段迁移。在第一阶段,也是时间最长的阶段,当数据卷被拷贝过来,数据库继续提供连接服务。它仅仅在第二阶段,应用程序会经历停机。我们正在积极地朝着一个世界,当应用运行在一个容器中,它们的数据可以在两台机器之间无缝迁移,甚至整个数据中心在一个基于虚机的世界灵活的移动。
我希望这篇文章对你部署和迁移 ELK 有用。如果想获取更多信息,请移步 follow along with our step-by-step Getting Started guide 来学习安装和使用 Flocker。除了 ElasticSearch 之外,我们还有部署和管理 MongoDB, PostgreSQL 和 MySQL 的例子。