使用Docker Swarm部署可擴(kuò)展的Python3應(yīng)用
Ben Firshman 最近在 Dockercon 做了一個關(guān)于使用 Docker 構(gòu)建無服務(wù)應(yīng)用的演講,你可以在這里查看詳情(還有視頻)。之后,我寫了一篇關(guān)于如何使用 AWS Lambda 構(gòu)建微服務(wù)系統(tǒng)的文章。
今天,我想展示給你的就是如何使用 Docker Swarm 部署一個簡單的 Python Falcon REST 應(yīng)用。這里我不會使用dockerrun 或者是其他無服務(wù)特性,你可能會驚訝,使用 Docker Swarm 部署(復(fù)制)一個 Python(Java、Go 都一樣)應(yīng)用是如此的簡單。
注意:這展示的部分步驟是截取自 Swarm Tutorial,我已經(jīng)修改了部分內(nèi)容,并且增加了一個 Vagrant Helper 的倉庫來啟動一個可以讓 Docker Swarm 工作起來的本地測試環(huán)境。請確保你使用的是 1.12 或以上版本的 Docker Engine。我寫這篇文章的時候,使用的是 1.12RC2 版本。注意的是,這只是一個測試版本,可能還會有修改。
你要做的***件事,就是如果你想本地運(yùn)行的話,你要保證 Vagrant 已經(jīng)正確的安裝和運(yùn)行了。你也可以按如下步驟使用你最喜歡的云服務(wù)提供商部署 Docker Swarm 虛擬機(jī)系統(tǒng)。
我們將會使用這三臺 VM:一個簡單的 Docker Swarm 管理平臺和兩臺 worker。
安全注意事項:Vagrantfile 代碼中包含了部分位于 Docker 測試服務(wù)器上的 shell 腳本。這是一個潛在的安全問題,它會運(yùn)行你不能控制的腳本,所以請確保你會在運(yùn)行代碼之前審查過這部分的腳本。
- $ git clone https://github.com/chadlung/vagrant-docker-swarm
- $ cd vagrant-docker-swarm
- $ vagrant plugin install vagrant-vbguest
- $ vagrant up
Vagrant up 命令需要一些時間才能完成。
SSH 登錄進(jìn)入 manager1 虛擬機(jī):
- $ vagrant ssh manager1
在 manager1 的 ssh 終端會話中執(zhí)行如下命令:
- $ sudo docker swarm init --listen-addr 192.168.99.100:2377
現(xiàn)在還沒有 worker 注冊上來:
- $ sudo docker node ls
讓我們注冊兩個新的 worker,請打開兩個新的終端會話(保持 manager1 會話繼續(xù)運(yùn)行):
- $ vagrant ssh worker1
在 worker1 的 ssh 終端會話上執(zhí)行如下命令:
- $ sudo docker swarm join 192.168.99.100:2377
在 worker2 的 ssh 終端會話上重復(fù)這些命令。
在 manager1 終端上執(zhí)行如下命令:
- $ docker node ls
你將會看到:
在 manager1 的終端里部署一個簡單的服務(wù)。
- sudo docker service create --replicas 1 --name pinger alpine ping google.com
這個命令將會部署一個服務(wù),它會從 worker 之一 ping google.com。(或者 manager,manager 也可以運(yùn)行服務(wù),不過如果你只是想 worker 運(yùn)行容器的話,也可以禁用這一點)??梢允褂萌缦旅?,查看哪些節(jié)點正在執(zhí)行服務(wù):
- $ sudo docker service tasks pinger
結(jié)果會和這個比較類似:
所以,我們知道了服務(wù)正跑在 worker1 上。我們可以回到 worker1 的會話里,然后進(jìn)入正在運(yùn)行的容器:
- $ sudo docker ps
你可以看到容器的 id 是: ae56769b9d4d,在我的例子中,我運(yùn)行如下的代碼:
- $ sudo docker attach ae56769b9d4d
你可以按下 CTRL-C 來停止服務(wù)。
回到 manager1,然后移除這個 pinger 服務(wù)。
- $ sudo docker service rm pinger
現(xiàn)在,我們將會部署可復(fù)制的 Python 應(yīng)用。注意,為了保持文章的簡潔,而且容易復(fù)制,所以部署的是一個簡單的應(yīng)用。
你需要做的***件事就是將鏡像放到 Docker Hub上,或者使用我已經(jīng)上傳的一個。這是一個簡單的 Python 3 Falcon REST 應(yīng)用。它有一個簡單的入口: /hello 帶一個 value 參數(shù)。
放在 chadlung/hello-app 上的 Python 代碼看起來像這樣:
- import json
- from wsgiref import simple_server
- import falcon
- class HelloResource(object):
- def on_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)})
- except Exception as ex:
- 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 很簡單:
- FROM python:3.4.4
- RUN pip install -U pip
- RUN pip install -U falcon
- EXPOSE 8080
- COPY . /hello-app
- WORKDIR /hello-app
- CMD ["python", "app.py"]
上面表示的意思很簡單,如果你想,你可以在本地運(yùn)行該進(jìn)行來訪問這個入口: http://127.0.0.1:8080/hello?value=Fred
這將返回如下結(jié)果:
- {"message": "Fred"}
在 Docker Hub 上構(gòu)建和部署這個 hello-app(修改成你自己的 Docker Hub 倉庫或者使用這個):
- $ sudo docker build . -t chadlung/hello-app:2
- $ sudo docker push chadlung/hello-app:2
現(xiàn)在,我們可以將應(yīng)用部署到之前的 Docker Swarm 了。登錄 manager1 的 ssh 終端會話,并且執(zhí)行:
- $ sudo docker service create -p 8080:8080 --replicas 2 --name hello-app chadlung/hello-app:2
- $ sudo docker service inspect --pretty hello-app
- $ sudo docker service tasks hello-app
現(xiàn)在,我們已經(jīng)可以測試了。使用任何一個 Swarm 節(jié)點的 IP 來訪問 /hello 入口。在本例中,我在 manager1 的終端里使用 curl 命令:
注意,Swarm 中的所有的 IP 都可以,不管這個服務(wù)是運(yùn)行在一臺還是更多的節(jié)點上。
- $ curl -v -X GET "http://192.168.99.100:8080/hello?value=Chad"
- $ curl -v -X GET "http://192.168.99.101:8080/hello?value=Test"
- $ curl -v -X GET "http://192.168.99.102:8080/hello?value=Docker"
結(jié)果:
- * Hostname was NOT found in DNS cache
- * Trying 192.168.99.101...
- * Connected to 192.168.99.101 (192.168.99.101) port 8080 (#0)
- > GET /hello?value=Chad HTTP/1.1
- > User-Agent: curl/7.35.0
- > Host: 192.168.99.101:8080
- > Accept: */*
- >
- * HTTP 1.0, assume close after body
- < HTTP/1.0 200 OK
- < Date: Tue, 28 Jun 2016 23:52:55 GMT
- < Server: WSGIServer/0.2 CPython/3.4.4
- < content-type: application/json
- < content-length: 19
- <
- {"message": "Chad"}
從瀏覽器中訪問其他節(jié)點:
如果你想看運(yùn)行的所有服務(wù),你可以在 manager1 節(jié)點上運(yùn)行如下代碼:
- $ sudo docker service ls
如果你想添加可視化控制平臺,你可以安裝 Docker Swarm Visualizer(這對于展示非常方便)。在 manager1 的終端中執(zhí)行如下代碼:
- $ sudo docker run -it -d -p 5000:5000 -e HOST=192.168.99.100 -e PORT=5000 -v /var/run/docker.sock:/var/run/docker.sock manomarks/visualizer
打開你的瀏覽器,并且訪問: http://192.168.99.100:5000/
結(jié)果如下(假設(shè)已經(jīng)運(yùn)行了兩個 Docker Swarm 服務(wù)):
要停止運(yùn)行 hello-app(已經(jīng)在兩個節(jié)點上運(yùn)行了),可以在 manager1 上執(zhí)行這個代碼:
- $ sudo docker service rm hello-app
如果想停止 Visualizer, 那么在 manager1 的終端中執(zhí)行:
- $ sudo docker ps
獲得容器的 ID,這里是: f71fec0d3ce1,從 manager1 的終端會話中執(zhí)行這個代碼:
- $ sudo docker stop f71fec0d3ce1
祝你成功使用 Docker Swarm。這篇文章主要是以 1.12 版本來進(jìn)行描述的。