本篇博客,主要是瞭解一下docker-compose的使用,docker-compose是官方給出的同時部署多個容器的解決方案;當你須要多個容器同時運行做爲你的解決方案時:好比構建一個網站,須要php + apache + postgrel ,這裏面的每個組件(web server,數據庫等)都是一個容器,若是本身一個一個創建,而且還要維護容器之間的互聯關係的話,是一件複雜的事情;docker-compose就是來幫助咱們來作這個事情的;php
本文從一個簡單的例子開始來介紹一下docker-compose的使用方法,本文章涉及的工程代碼放在了附件中 http://files.cnblogs.com/files/yuhan-TB/docker-compose-test.tar.gz 能夠下載;;前端
場景以下:python
ngnix在最前端作負載均衡;nginx以後是三個flask web server容器,用來處理實際用戶的請求;redis用來存儲一些數據,flask app與redis相連來獲取數據,而後根據實際狀況來輸出相應的消息;nginx
個人系統是mac os,web
(1) 首先安裝docker toolbox工具箱,toolbox工具箱集成了不少工具,docker-compose,docker-machine,docker-client, virtualBox等等;redis
爲啥須要virtualBox呢,由於docker是不支持mac 和 windows 的,因此要想在這兩個OS上運行的話,作法是安裝一個虛擬機,而後在虛擬機上啓動docker,而後安裝docker-client,docker-client與虛擬機中的docker engine鏈接;docker
以前mac 或 windows下的安裝都是使用boot2docker,原理也是採用虛擬機實現的。從docker官方發佈docker toolBox以後,就不建議使用boot2docker了。數據庫
(2) 用docker machine 創建一個虛擬機,docker-machine的做用是在本機或在雲端環境創建一個docker的運行環境;如下是創建命令;apache
docker-machine create --driver virtualbox hehe-dev 這裏面我起的虛擬機的名字是hehe-dev 呵呵~ flask
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;