本篇博客,主要是了解一下docker-compose的使用,docker-compose是官方给出的同时部署多个容器的解决方案;当你需要多个容器同时运行作为你的解决方案时:比如构建一个网站,需要php + apache + postgrel ,这里面的每一个组件(web server,数据库等)都是一个容器,如果自己一个一个建立,并且还要维护容器之间的互联关系的话,是一件复杂的事情;docker-compose就是来帮助我们来做这个事情的;
本文从一个简单的例子开始来介绍一下docker-compose的使用方法,本文章涉及的工程代码放在了附件中 https://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;