本文是对《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容器配置

接下来开始配置这些应用,先从redis-master开始。
先来看一下容器redis-master的挂载目录

$ docker inspect --format '{{json .Mount}}'

这里写图片描述
进入主机目录,修改配置文件redis.conf的参数

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集群搭建成功

django容器配置

现在开始配置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+="<br>"
        r = redis.Redis(host='db',port=6379,db=0)
        info = r.info()
        str+=("Set Hi <br>")
        r.set('Hi',"HelloWorld-APP2")
        str+=("Get Hi: %s <br>" % r.get('Hi'))
        str+=("Redis info:<br>")
        str+=("key:info value")
        for key in info:
                str+=("%s:%s <br>" % (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)。

HAProxy容器配置

在主机的挂载容器卷下编辑配置文件

$ 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!
这里写图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐