本篇博客,主要是了解一下docker-compose的使用,docker-compose是官方給出的同時部署多個容器的解決方案;當你需要多個容器同時運行作為你的解決方案時:比如構建一個網站,需要php + apache + postgrel ,這里面的每一個組件(web server,數據庫等)都是一個容器,如果自己一個一個建立,並且還要維護容器之間的互聯關系的話,是一件復雜的事情;docker-compose就是來幫助我們來做這個事情的;
本文從一個簡單的例子開始來介紹一下docker-compose的使用方法,本文章涉及的工程代碼放在了附件中 http://files.cnblogs.com/files/yuhan-TB/docker-compose-test.tar.gz 可以下載;;
場景如下:
ngnix在最前端做負載均衡;nginx之后是三個flask web server容器,用來處理實際用戶的請求;redis用來存儲一些數據,flask app與redis相連來獲取數據,然后根據實際情況來輸出相應的消息;
我的系統是mac os,
(1) 首先安裝docker toolbox工具箱,toolbox工具箱集成了很多工具,docker-compose,docker-machine,docker-client, virtualBox等等;
為啥需要virtualBox呢,因為docker是不支持mac 和 windows 的,所以要想在這兩個OS上運行的話,做法是安裝一個虛擬機,然后在虛擬機上啟動docker,然后安裝docker-client,docker-client與虛擬機中的docker engine連接;
之前mac 或 windows下的安裝都是使用boot2docker,原理也是采用虛擬機實現的。從docker官方發布docker toolBox之后,就不建議使用boot2docker了。
(2) 用docker machine 建立一個虛擬機,docker-machine的作用是在本機或在雲端環境建立一個docker的運行環境;以下是建立命令;
docker-machine create --driver virtualbox hehe-dev 這里面我起的虛擬機的名字是hehe-dev 呵呵~
docker-machine ls 建立好之后,可以通過ls命令來查看自己建立的虛擬機是否已經起來;
docker-machine env hehe-dev, 接下來,通過env命令可以查看 hehe-dev 虛擬機的環境變量,對這些環境變量(就是彈出的一些export,這些export 要自己在終端中設置一下)要進行設置一下,好讓docker client可以找到 docker engine的地址;
docker version,然后 docker version一下,看看docker-machine是否安裝成功;
(3)接下來就是docker-compose了。
mkdir docker-compse-test 首先建立一個docker-compose的文件夾,這里我起名叫做docker-compose-test;
touch docker-compose.yml 在文件夾下建立一個yml文件;docker-compose是通過yml文件來對各個容器進行配置的;下面將我的配置貼出來:
flask_a:
restart: always
build: ./flask_a
ports:
- "5002:5000"
links:
- redis:redis
flask_b:
restart: always
build: ./flask_b
ports:
- "5003:5000"
links:
- redis:redis
flask_c:
restart: always
build: ./flask_c
ports:
- "5004:5000"
links:
- redis:redis
nginx:
restart: always
build: ./nginx
ports:
- "5001:80"
links:
- flask_a:flask_a
- flask_b:flask_b
- flask_c:flask_c
redis:
restart: always
build: ./redis
ports:
- "6379:6379"
首先是三個flask_server的實例,分別連上redis,將flask的5000端口與docker-machine虛擬機的端口進行映射,由於有三個flask實例:flask_a, flask_b,flask_c,所以分別映射端口 5002,5003,5004;
然后是nginx,nginx由於要做負載均衡,需要與三個flask server都link起來;nginx映射的虛擬機的端口是 5001;
這里在docker-compose-test文件夾下,分別建立flask_a, flask_b, flask_c, nginx, redis的文件夾,在里面分別創建Dockerfile;
為了了解一下簡要的邏輯,將flask中的app代碼這里列出來:
from flask import Flask,request
import os
import redis
app = Flask(__name__)
@app.route('/index', methods=['POST','GET'])
def hello_world():
request_args = {}
if request.method == 'POST':
request_args = request.form
elif request.method == 'GET':
request_args = request.args
username = request_args.get('username','')
r = redis.Redis(host=os.environ['REDIS_1_PORT_6379_TCP_ADDR'], port=6379, db=0)
if r.get(username):
return 'flask instance a: %s exists' % (username,)
else:
return 'flask instance a: %s not exists' % (username,)
if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0')
就是接受用戶請求的參數,去redis中去查一下用戶是否存在,存在打印exists信息,不存在打印not exists信息,並且打印instance a、b或者c的消息,這個主要來判斷負載均衡是不是起作用了。
dockeer-compose在build的過程中,可能會遇到兩個問題:
(a)當build flask的時候的可能會遇到:
Retrying (Retry(total=4, connect=None, read=None, redirect=None)) after connection broken by 'ReadTimeoutError("HTTPSConnectionPool(host='pypi.python.org', port=443): Read timed out. (read timeout=15)",)': /simple/flask/
這個是dns的問題。解決方法是修改宿主機的 /etc/resolv.conf 在里面添加google的 nameserver
nameserver 8.8.8.8
nameserver 8.8.4.4
然后重啟docker-machine docker-machine stop && docker-machine start
(b)第二個問題是,由於初次build,有些需要鏡像需要從官方下載,官方的鏡像有時下載很慢,這里可以使用daocloud 的官方加速工具;這里也給daocloud 打一個廣告;
做法是 docker-machine ssh hehe-dev,登陸到虛擬機中,運行: curl -sSL https://get.daocloud.io/daomonit/install.sh | sh -s db634a0ee990daaf2843cdecbf843907f63825e0
這樣就可以在虛擬機中,運用命令 "dao pull 鏡像名:tag" 來下載鏡像了,這樣會很快;
(3)上面已經將整個工程啟動起來了,由於flask需要訪問redis,但是redis中還沒有數據,需要在redis中加入要訪問的數據;從上面的yml文件可以知道。redis的端口是6379;我的做法是在宿主機下載redis程序;
然后使用redis-cli 連接虛擬機上的redis,虛擬機的ip 通過 docker-machine ip hehe-dev獲得,然后用redis-cli -h 虛擬機ip -p 6379連接到redis server;接着插入兩條數據:
set tom 100
set harry 100
(4)最后一步就是去驗證flask 是否已經起作用,通過瀏覽器訪問 http://虛擬機ip:5001/index?username=tom ,連續訪問三次,可以看到負載均衡起作用了。tom exists
然后連續訪問三次 http://虛擬機ip:5001/index?username=jerry,可以看到負載均衡也起作用了。jerry not exists;
