本文是对《docker容器与容器云》第二章“搭建你的第一个Docker应用栈“的整理和总结,接下来打算把它在swarm和compose上分别实现一次。
环境:172.16.71.43 centos7 ,docker version 1.8
将要搭建的应用栈包含六个节点,一个代理节点,两个web应用节点,一个主数据库节点和两个从数据库节点.
HAProxy负责负载均衡,redis担任数据存储服务,Django负责构建web服务,web服务将访问数据库,并提供http接口供用户访问。
整个项目搭建在一台单机上。
从docker hub上下载镜像
$ docker pull ubuntu
$ docker pull redis
$ docker pull django
$ docker pull haproxy
因为容器之间有相互依赖的关系,注意启动顺序
首先启动redis
$ docker run -it --name redis-master redis /bin/bash
$ docker run -it --name redis-slave1 --link redis-master:master redis /bin/bash
$ docker run -it --name redis-slave2 --link redis-master:master redis /bin/bash
再启动django
$ docker run -it --name APP1 -v ~/Projects/Django/APP1:/usr/src/app --link redis-master:db django /bin/bash
$ docker run -it --name APP2 -v ~/Projects/Django/APP2:/usr/src/app --link redis-master:db django /bin/bash
最后启动haproxy
$ docker run -it --name haproxy --link APP1:app1 --link APP2:app2 -p:6301:6301 -v ~/Projects/HAProxy:/tmp haproxy /bin/bash
启动完成之后我们用ps命令检查下容器是否都正常运行了
一切正常
为了保持容器的轻量级设计,我们不打算在容器中安装文本编辑等工具,修改配置文件的工作打算在主机的挂载文件中完成。
接下来开始配置这些应用,先从redis-master开始。
先来看一下容器redis-master的挂载目录
$ docker inspect --format '{{json .Mount}}'
daemonize yes
pidfile /var/run/redis.pid
进入redis-master容器,启动redis服务
$ docker attach redis-master
$ cd /data
$ cp redis.conf /usr/local/bin
$ cd /usr/local/bin
$ redis-server redis.conf
redis-slave的redis.conf修改一下参数
daemonize yes
pidfile /var/run/redis.conf
slaveof master 6379
(注意,这里slaveof master 6379中的master,是容器依赖时起的别名(连接名),对应于docker run –link redis-master:master。
docker run时会把master : ip写入容器的/etc/hosts,当实际IP变化时,容器会自动读取host信息,将连接名转化为实际IP地址)
修改完配置就可以启动redis了,操作步骤同上。
到这里redis集群就跑起来了,让我们来测试下
进入redis-master容器
$ docker attach redis-master
$ redis-cli
$ set master hi
$ get master
进入redis-slaver1容器
$ docker attach redis-slave1
$ redis-cli
$ get master
如果输出 ’hi‘说明redis集群搭建成功
现在开始配置app容器django
以APP1为例(APP2配置过程完全相同)。
首先进入容器APP1
$ docker attach APP1
在容器环境安装python语言支持的redis包
$ pip install redis
检查一下是否装好
$ python
>>> import redis
>>> print(redis.__file__)
如果没有报错,说明安装成功
现在开始创建web服务
以下命令在容器APP1中执行
$ cd /usr/src/app
$ mkdir dockerweb
$ cd /dockerweb
$ cd dockerweb
$ django-admin.py startproject redisweb
$ cd redisweb
$ python manager.py startapp helloworld
因为在启动时挂载了容器卷~/Projects/Django/APP1:/usr/src/app,我们可以在~/Projects/Django/APP1修改编辑
以下命令在主机中执行
$ cd ~/Projects/Django/App1
$ cd dockerweb/redisweb/helloworld
# 利用root权限修改views.py
$ sudo su
$ vim views.py
我们将输出redis数据库的信息到网页
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
import redis
def hello(requst):
str=redis.__file__
str+="
"
r = redis.Redis(host='db',port=6379,db=0)
info = r.info()
str+=("Set Hi
")
r.set('Hi',"HelloWorld-APP2")
str+=("Get Hi: %s
" % r.get('Hi'))
str+=("Redis info:
")
str+=("key:info value")
for key in info:
str+=("%s:%s
" % (key, info[key]))
return HttpResponse(str)
接下来修改setting.py
$ cd ../redisweb/
$ vim setting.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'helloworld'
]
最后修改urls.py
vim urls.py
from django.conf.urls import url
from django.contrib import admin
from helloworld.views import hello
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^helloworld$',hello),
]
修改完这三个文件,再次进入容器,在目录/usr/src/app/dockerweb/redisweb下完成下面操作
$ python manage.py makemigration
$ python manage.py migrate --run-syncdb
$ python manage.py runserver 0.0.0.0:8001
至此完成了APP1的配置和启动,APP2操作同上(启动时用 python manage.py runserver 0.0.0.0:8002)。
在主机的挂载容器卷下编辑配置文件
$ cd ~/Projects/HAProxy
$ vim haproxy.cfg
global
maxconn 20480 #默认最大连接数
log 127.0.0.1 local0 #[err warning info debug]
chroot /usr/local/sbin #chroot运行的路径
daemon #以后台形式运行haproxy
nbproc 4 #进程数量(可以设置多个进程提高性能)
pidfile /var/run/haproxy.pid #haproxy的pid存放路径,启动进程的用户必须有权限访问此文件
defaults
log 127.0.0.1 local3
mode http #所处理的类别 (#7层 http;4层tcp )
maxconn 20480 #最大连接数
option dontlognull #不记录健康检查的日志信息
option redispatch #serverId对应的服务器挂掉后,强制定向到其他健康的服务器
stats refresh 30 #统计页面刷新间隔
retries 3 #3次连接失败就认为服务不可用,也可以通过后面设置
balance roundrobin #默认的负载均衡的方式,轮询方式
#balance source #默认的负载均衡的方式,类似nginx的ip_hash
#balance leastconn #默认的负载均衡的方式,最小连接
contimeout 5000 #连接超时
clitimeout 50000 #客户端超时
srvtimeout 50000 #服务器超时
timeout check 2000 #心跳检测超时
listen redis_porxy
bind 0.0.0.0:6301
stats enable
stats uri /haproxy-stats
server APP1 APP1:8001 check inter 2000 rise 2 fall 5
server APP2 APP2:8002 check inter 2000 rise 2 fall 5
然后进入容器haproxy容器,执行以下命令
$ cp /tmp/haproxy.cfg /usr/local/sbin
$ cd /usr/local/sbin
$ haproxy -f haproxy.cfg
haproxy启动成功的话,我们来测试下整个服务是否能正常工作
在浏览器上输入 http://172.16.71.43:6301/helloworld
看网页上能不能显示redis信息
刷新几次看看能不能haproxy有没有负载到APP1和APP2
enjoy!