【编者按】本文来自 Baqend Tech Blog,描述了如何在 Docker Swarm,而不是在虚拟机上部署和调配Apache Storm集群。文章系国内 ITOM 管理平台 OneAPM 编译呈现。
如何在 Docker Swarm 上部署并调配Apache Storm集群,这个题目很有意思,Wolfram Wingerath将之描述为“真正有趣”的体验,在Tech上你很少能听见这种话。我好奇地问他是什么让使用容器比使用虚拟机更棒?他回答说:
作为一名Docker和Docker Swarm的新手,我肯定还有很多不知道的事。不过,在我看来,在Docker上部署(及一般操作)比在虚拟机甚至裸机上更有趣,因为Docker剥离了异构性和许多问题。一旦运行了Docker,你就可以用一行声明语句来启动MongoDB或者Redis的服务器等东西。Docker Swarm集群可以帮你做同样的事,而且Docker还会帮你把启动的东西分发给集群中的某个服务器。Docker甚至会帮你下载正确的镜像,如果你本地没有的话。你也不用解决连接问题,因为只要在同一Docker网络中,任一台机器都与所有其他的机器互联互通。正如在本教程中所提到的,只要你使用了overlay网络,分布式安装也能实现。
你在邮件中引用到了我的一些话,当我在写它们的时候,我的脑海深处想起了几个月前,我需要安装和运行一个拥有超过16个节点的Apache Storm集群的事。当时有好几个问题,比如,我对AWS并不太熟悉(以前是用OpenStack的),还有与(Storm使用的)Netty的连接性问题,以及AWS的主机名解析问题。这些问题在我设置OpenStack的时候从没出现过。最终我们花费了数天及数百美元去解决它们。我真心认为,如果你使用Docker,你就不会遇到这些麻烦,因为你的环境始终如一:即Docker。
回到教程上来
Bagend Cloud即将支持查询缓存和连续查询的功能,我们将依靠Apache Storm来处理低延迟的数据。已经有好几个项目都致力于实现在Docker上部署多服务器Storm (例如wurstmeister/storm-docker或viki-org/storm-docker),但是越过服务器数量的限制似乎会使事情变得复杂。既然可扩展性和易操作性是我们部署的关键,我们从一开始就使用Dock Swarm,也很高兴地看到事情进展的如此顺利。我们希望通过这篇教程来分享我们的经历,提升你对即将发布的Baqend实时API的兴趣,最终宣传一下Dock Swarm(因为它真的很牛!):-)
如果你是Swarm新手,请看我们的AWS Meetup Docker幻灯片!
接下来的计划
概述
首先,我们将介绍一个简单的部署范例,并解释其中的每一部分。接着,我们会在重点预告中告诉你所需完成的最简单的准备工作(使用事先准备好的实用脚本程序)。然后,我们会来到本教程的核心部分,一步步向你展示Docker Swarm集群及多节点Apache Storm集群的部署过程。当然,我们也会做一些与Storm(特别是部署和终止远程服务器上的拓扑)以及Swarm(例如重启manager节点和终止整个Storm集群)都涉及到的常规工作。
概述:部署
下图是部署的架构图:
有三台运行Ubuntu Server 14.04的机器,每台都会运行一个Docker守护进程,同时每台都装有几个容器。经过初始设置,你只能访问其中一台机器(Ubuntu 1),很大程度上来说,会觉得只有一个Docker守护进程。
安装Swarm之后,你会创建一个覆盖网络(stormnet),这样不同Swarm节点间的Docker容器就可以相互通信了。最终,你将建立起一个成熟的Storm集群,这个集群使用现有的 ZooKeeper 共同协调,并通过stormnet实现节点间的通信。虽然监管容器将每一台服务器策略分发,Nimbus和UI容器则会安装在manager节点上(Ubuntu 1)。
必须允许对Ubuntu 1机器的公共访问(即分配一个公共IP和开放端口8080!)。否则,你就看不到Storm美丽的UI了。
详细教程
我们给三个Ubuntu机器的域名分别是zk1.cloud、zk2.cloud和zk3.cloud。由于ZooKeeper服务器和manager节点从概念上说是两个不同的角色,我们使用manager.swarm和manager.swarm.baqend.com作为manager节点的私有IP地址和公共IP地址。尽管本教程中,Ubuntu 1实际上是扮演了ZooKeeper 1和管理者两个角色,但你可以在自己部署的时候使用不同两个服务器来完成。在Github上check out这个教程,在readme.me中,根据你自己的域名,查找并替换我们的原有域名,然后你就可以把我们的大部分语句复制粘贴到我们将要使用的外壳程序中了。
重点预告
对于那些急着看结果的人来说,我们也准备了一些脚本!这些是部署Swarm和Storm所需的全部脚本了。但是,为了便于理解,后面还是会有一个详细的步骤描述的。
所以,在讨论细节之前,这有一份快速指南:
1.创建一个Ubuntu 14.04服务器 – 我们称之为Ubuntu 1 – 然后通过SSH连接它。然后执行以下语句check out指南中的脚本来安装Docker:
sudo apt-get install git -y && \
cd /home/ubuntu/ && \
git clone https://github.com/Baqend/tutorial-swarm-storm.git && \
chmod +x tutorial-swarm-storm/scripts/* && \
cd tutorial-swarm-storm/scripts/ && \
sudo bash installDocker.sh && \
sudo usermod -aG docker ubuntu && \
sudo shutdown -h now
2.机器会自动关机。关机的时候,生成快照。
3.启动两台你刚刚快照过的机器(Ubuntu 2和Ubuntu 3),使用一下自定义脚本把它们做成Swarm worker节点:
#!/bin/bash
cd /home/ubuntu/ && rm -rf tutorial-swarm-storm && \
git clone https://github.com/Baqend/tutorial-swarm-storm.git && \
cd tutorial-swarm-storm/scripts/ && \
chmod +x ./* && \
./init.sh zk1.cloud,zk2.cloud,zk3.cloud
注意:你需要把逗号分隔开的主机名替换成你自己的主机名。
4.对域名服务器做如下设置:把列表中的第一台主机zk1.cloud指向Ubuntu1,剩下的zk2.cloud和zk3.cloud分别指向Ubuntu 2和Ubuntu 3。另外要确保manager.swarm.baqend.com和manager.swarm分别被解析为Ubuntu 1的公开IP地址和私有IP地址。
5.确保主机之间可以互相访问:需要打开端口2181、2888、3888 (ZooKeeper)、2375 (Docker Swarm)和6627 (Storm,远程拓扑部署)。为了保证能从外部访问Storm UI,还必须公开manager.swarm.baqend.com:8080。
6.最后,启动Ubuntu 1同时运行下列代码,配置ZooKeeper ensemble、Swarm和Storm:
cd /home/ubuntu/tutorial-swarm-storm/scripts/ && \
ZOOKEEPER=zk1.cloud,zk2.cloud,zk3.cloud && \
sudo bash init.sh $ZOOKEEPER manager && \
. swarm.sh $ZOOKEEPER && \
. storm.sh $ZOOKEEPER 3
再次提醒:记得把其中的主机名替换为你自己的。
你现在应该可以访问http://manager.swarm.baqend.com:8080下的Storm UI了。
另外,当你在manager节点上输入docker info
时,你将会看见UI和Nimbus容器在同一台机器上运行,而Swarm管理器和监控容器则在不同的机器上运行。
再做一次:准备一个镜像
好,现在让我们来看一遍详细的步骤。为了避免重复的步骤,我们只在一台机器上进行这些准备工作,然后关机并快照。接着我们通过这个快照创建其它机器。
让我们开始吧:
1.创建Ubuntu 1,作为Ubuntu 14.04服务器,然后通过SSH连接它,执行下列语句安装Docker:
sudo apt-get update && sudo apt-get install apt-transport-https ca-certificates && sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D \
&& echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | sudo tee -a /etc/apt/sources.list.d/docker.list \
&& sudo apt-get update && sudo apt-get purge lxc-docker && sudo apt-cache policy docker-engine \
&& sudo apt-get update -y && sudo apt-get install -y linux-image-extra-$(uname -r) apparmor docker-engine git make \
&& sudo usermod -aG docker $(whoami)
(关于Docker安装的细则可以看这里)
由于Docker是通过一个key文件去识别不同的docker守护进程的,因此在快照之前,我们要停止docker守护进程,删掉这个key文件(重启Docker后会生成一个新的Key文件),关机之前记得快照。
sudo service docker stop \
&& sudo rm /etc/docker/key.json
注意:如果你不在快照之前删掉这个Key文件,则所有根据这个镜像生成的机器都会拥有同样的识别符,最终你的Swarm集群一片狼藉。
3.最后,我们只 需要用同一个方法准备一个机器,这个机器在下次boot的时候会成为Swarm worker。为此,我们用文本编辑器,例如nano,创建一个文件 /etc/init.sh。
sudo nano /etc/init.sh
接着,我们复制下列代码,并保存:
#!/bin/bash
# first script argument: the servers in the ZooKeeper ensemble:
ZOOKEEPER_SERVERS=$1
# second script argument: the role of this node:
# ("manager" for the Swarm manager node; leave empty else)
ROLE=$2
# the IP address of this machine:
PRIVATE_IP=$(/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}')
# define label for the manager node:
if [[ $ROLE == "manager" ]];then LABELS="--label server=manager";else LABELS="";fi
# define default options for Docker Swarm:
echo "DOCKER_OPTS=\"-H tcp://0.0.0.0:2375 \
-H unix:///var/run/docker.sock \
--cluster-advertise eth0:2375 \
$LABELS \
--cluster-store \
zk://$ZOOKEEPER_SERVERS\"" \
| sudo tee /etc/default/docker
# restart the service to apply new options:
sudo service docker restart
echo "let's wait a little..."
sleep 30
# make this machine join the Docker Swarm cluster:
docker run -d --restart=always swarm join --advertise=$PRIVATE_IP:2375 zk://$ZOOKEEPER_SERVERS
4.现在,我们要关机了。
sudo shutdown -h now
接着快照一下。
5.现在,通过快照的镜像,启动另外两台机器(Ubuntu 2和Ubuntu 3)。使用下面的语句作为初始/自定义脚本:
#!/bin/bash
/bin/bash /etc/init.sh \
zk1.cloud,zk2.cloud,zk3.cloud
注意:如果你使用的是OpenStack,上述脚本可以加为自定义脚本。但如果是AWS,则应加为用户数据。
6.重启已经快照过的机器(Ubuntu 1),连接机器,接着执行以下代码:
/bin/bash /etc/init.sh \
zk1.cloud,zk2.cloud,zk3.cloud \
manager
这会在机器上建立一个Swarm worker,并标之为Swarm管理器。
7.对域名服务器做如下设置:将列表中的第一个域名(zk1…)指向Ubuntu1上的管理器,剩下的两个域名(zk2…和zk3…)指向另外两台刚刚启动的机器,即Ubuntu 2和Ubuntu 3。另外要确保manager.swarm.baqend.com和manager.swarm分别被解析为Ubuntu的公开IP地址和私有IP地址。
8.最后,完成安全设置,使端口2181、2888、3888 (ZooKeeper)、2375 (Docker Swarm)和6627 (Storm, 远程拓扑部署)上的机器可以互相访问。如果你希望可以实现从外部访问Storm UI,那么还需要公开manager.swarm.baqend.com:8080。
见证奇迹的时刻到了!
在本文的第二部分,会手把手地介绍如何创建 Swarm 集群,敬请关注。