使用Docker Swarm部署可扩展的Python3应用
Ben Firshman 最近在 Dockercon 做了一个关于使用 Docker 构建无服务应用的演讲,你可以在这里查看详情(还有视频)。之后,我写了一篇关于如何使用 AWS Lambda 构建微服务系统的文章。 今天,我想展示给你的就是如何使用 Docker Swarm 部署一个简单的 Python Falcon REST 应用。这里我不会使用dockerrun 或者是其他无服务特性,你可能会惊讶,使用 Docker Swarm 部署(复制)一个 Python(Java、Go 都一样)应用是如此的简单。 注意:这展示的部分步骤是截取自 Swarm Tutorial,我已经修改了部分内容,并且增加了一个 Vagrant Helper 的仓库来启动一个可以让 Docker Swarm 工作起来的本地测试环境。请确保你使用的是 1.12 或以上版本的 Docker Engine。我写这篇文章的时候,使用的是 1.12RC2 版本。注意的是,这只是一个测试版本,可能还会有修改。 你要做的第一件事,就是如果你想本地运行的话,你要保证 Vagrant 已经正确的安装和运行了。你也可以按如下步骤使用你最喜欢的云服务提供商部署 Docker Swarm 虚拟机系统。 我们将会使用这三台 VM:一个简单的 Docker Swarm 管理平台和两台 worker。 安全注意事项:Vagrantfile 代码中包含了部分位于 Docker 测试服务器上的 shell 脚本。这是一个潜在的安全问题,它会运行你不能控制的脚本,所以请确保你会在运行代码之前审查过这部分的脚本。 $gitclonehttps://github.com/chadlung/vagrant-docker-swarm $cdvagrant-docker-swarm $vagrantplugininstallvagrant-vbguest $vagrantup Vagrant up 命令需要一些时间才能完成。 SSH 登录进入 manager1 虚拟机: $vagrantsshmanager1 在 manager1 的 ssh 终端会话中执行如下命令: $sudodockerswarminit--listen-addr192.168.99.100:2377 现在还没有 worker 注册上来: $sudodockernodels 让我们注册两个新的 worker,请打开两个新的终端会话(保持 manager1 会话继续运行): $vagrantsshworker1 在 worker1 的 ssh 终端会话上执行如下命令: $sudodockerswarmjoin192.168.99.100:2377 在 worker2 的 ssh 终端会话上重复这些命令。 在 manager1 终端上执行如下命令: $dockernodels 你将会看到: 在 manager1 的终端里部署一个简单的服务。 sudodockerservicecreate--replicas1--namepingeralpinepinggoogle.com 这个命令将会部署一个服务,它会从 worker 之一 ping google.com。(或者 manager,manager 也可以运行服务,不过如果你只是想 worker 运行容器的话,也可以禁用这一点)。可以使用如下命令,查看哪些节点正在执行服务: $sudodockerservicetaskspinger 结果会和这个比较类似: 所以,我们知道了服务正跑在 worker1 上。我们可以回到 worker1 的会话里,然后进入正在运行的容器: $sudodockerps 你可以看到容器的 id 是: ae56769b9d4d,在我的例子中,我运行如下的代码: $sudodockerattachae56769b9d4d 你可以按下 CTRL-C 来停止服务。 回到 manager1,然后移除这个 pinger 服务。 $sudodockerservicermpinger 现在,我们将会部署可复制的 Python 应用。注意,为了保持文章的简洁,而且容易复制,所以部署的是一个简单的应用。 你需要做的第一件事就是将镜像放到 Docker Hub上,或者使用我已经上传的一个。这是一个简单的 Python 3 Falcon REST 应用。它有一个简单的入口: /hello 带一个 value 参数。 放在 chadlung/hello-app 上的 Python 代码看起来像这样: importjson fromwsgirefimportsimple_server importfalcon classHelloResource(object): defon_get(self,req,resp): try: value=req.get_param('value') resp.content_type='application/json' resp.status=falcon.HTTP_200 resp.body=json.dumps({'message':str(value)}) exceptExceptionasex: resp.status=falcon.HTTP_500 resp.body=str(ex) if__name__=='__main__': app=falcon.API() hello_resource=HelloResource() app.add_route('/hello',hello_resource) httpd=simple_server.make_server('0.0.0.0',8080,app) httpd.serve_forever() Dockerfile 很简单: FROMpython:3.4.4 RUNpipinstall-Upip RUNpipinstall-Ufalcon EXPOSE8080 COPY./hello-app WORKDIR/hello-app CMD["python","app.py"] 上面表示的意思很简单,如果你想,你可以在本地运行该进行来访问这个入口: http://127.0.0.1:8080/hello?value=Fred 这将返回如下结果: {"message":"Fred"} 在 Docker Hub 上构建和部署这个 hello-app(修改成你自己的 Docker Hub 仓库或者使用这个): $sudodockerbuild.-tchadlung/hello-app:2 $sudodockerpushchadlung/hello-app:2 现在,我们可以将应用部署到之前的 Docker Swarm 了。登录 manager1 的 ssh 终端会话,并且执行: $sudodockerservicecreate-p8080:8080--replicas2--namehello-appchadlung/hello-app:2 $sudodockerserviceinspect--prettyhello-app $sudodockerservicetaskshello-app 现在,我们已经可以测试了。使用任何一个 Swarm 节点的 IP 来访问 /hello 入口。在本例中,我在 manager1 的终端里使用 curl 命令: 注意,Swarm 中的所有的 IP 都可以,不管这个服务是运行在一台还是更多的节点上。 $curl-v-XGET"http://192.168.99.100:8080/hello?value=Chad" $curl-v-XGET"http://192.168.99.101:8080/hello?value=Test" $curl-v-XGET"http://192.168.99.102:8080/hello?value=Docker" 结果: *HostnamewasNOTfoundinDNScache *Trying192.168.99.101... *Connectedto192.168.99.101(192.168.99.101)port8080(#0) >GET/hello?value=ChadHTTP/1.1 >User-Agent:curl/7.35.0 >Host:192.168.99.101:8080 >Accept:*/* > *HTTP1.0,assumecloseafterbody <HTTP/1.0200OK <Date:Tue,28Jun201623:52:55GMT <Server:WSGIServer/0.2CPython/3.4.4 <content-type:application/json <content-length:19 < {"message":"Chad"} 从浏览器中访问其他节点: 如果你想看运行的所有服务,你可以在 manager1 节点上运行如下代码: $sudodockerservicels 如果你想添加可视化控制平台,你可以安装 Docker Swarm Visualizer(这对于展示非常方便)。在 manager1 的终端中执行如下代码: $sudodockerrun-it-d-p5000:5000-eHOST=192.168.99.100-ePORT=5000-v/var/run/docker.sock:/var/run/docker.sockmanomarks/visualizer 打开你的浏览器,并且访问: http://192.168.99.100:5000/ 结果如下(假设已经运行了两个 Docker Swarm 服务): 要停止运行 hello-app(已经在两个节点上运行了),可以在 manager1 上执行这个代码: $sudodockerservicermhello-app 如果想停止 Visualizer, 那么在 manager1 的终端中执行: $sudodockerps 获得容器的 ID,这里是: f71fec0d3ce1,从 manager1 的终端会话中执行这个代码: $sudodockerstopf71fec0d3ce1 祝你成功使用 Docker Swarm。这篇文章主要是以 1.12 版本来进行描述的。 本文作者:Chad Lung 来源:51CTO