BenjaminYang In solitude, where we are least alone

容器互联,单机伪集群搭建

1.集群示意图

2.从docker hub上获取响应的镜像

docker pull redis

docker pull django

docker pull haproxy

docker pull ubuntu

 

 3.应用栈的启动顺序

启动redis-master容器节点

两个redis-salve容器节点连接到redis-master节点上

两 app节点启动时要连接到redis-master节点上

Hapoxy节点要连接到两个app节点上

综上所述启动顺序为:

redis-master----》redis-slave------》App -------》Haproxy

注意:为了外网能访问应用栈主机 ,并通过haproxy访问应用栈中app,在启动haproxy时需要-p 选项暴露一个端口给主机,即可以通过主机ip加暴露的端口从外网访问应用栈的app主机

 

4.启动相应节点的容器

分别启动redis容器

#启动redis-master节点

docker run -it --name redis-master redis /bin/bash

172.17.0.2对应的是redis-master节点

#将redis-slave1 链接到redis-master

docker run -it --name redis-salve1 --link redis-master:master redis /bin/bash

172.17.0.3对应的是redis-salve1节点

#将redis-slave2 链接到redis-master

docker run -it --name redis-salve2 --link redis-master:master redis /bin/bash

 

172.17.0.4对应的是redis-salve2节点

 

启动app节点

 docker run -it --name APP1 --link redis-master:db -v ~/Projects/Django/App1:/usr/src/app django /bin/bash
 docker run -it --name APP2 --link redis-master:db -v ~/Projects/Django/APP2:/usr/src/app django /bin/bash

172.17.0.5 对应APP1   172,17.0.6对应APP2 他都是与redis-master进行容器互联

#通过 -v选项 容器的/usr/src/app与挂载到宿主机的  ~/Projects/Django/App1 目录上,这样在宿主机的   ~/Projects/Django/App1 目录下操作等同于在容器、/usr/src/app 目录下操作。

 

启动haproxy容器

docker run -it --name HAProxy --link APP1: --link APP2:APP2 -p 6301:6301 -v ~/Projects/HAProxy:/tmp haproxy /bin/bash

分别于 app1 和 app2 进行容器互联,其中172,.17.0.7就是haproxy容器的ip

 

查看所有容器节点

 

 5.应用栈容器的配置

Redis Master 主节点容器的配置

查看master节点映射在宿主机中文件目录

对容器做映射操作

 docker inspect --format "{{ .Config.Volumes }}" 8cb6

 查看映射到宿主机的目录

cd /var/lib/docker/volumes/1cbd4af8df10700281d44b3a3906bc0bf6c2f29ee44ee154170154f51ba41727/_data

在你的宿主机 安装redis

yum install -y redis

由于容器中没有编辑器 不能使用vi 等命令,所以需要将redis的配置文件复制过去放在挂载的宿主机目录下,并做如下更改

主要更改 redis的启动方式,将redis默认的前台启动方式改为后台运行的方式    

daemonized yes   #默认是no

bind   0.0.0.0

 

 在redis-master容器中操作

[root@jump _data]# docker exec -it 8cb6 /bin/bash

  root@8cb697b83074:/data# ls
redis.conf

将redis的配置文件放到 redis的启动目录下

cp  redis.conf /usr/local/bin

启动redis-master

redis-server redis.conf

 redis-slave1  从数据库的配置

[root@jump ~]# cd /var/lib/docker/volumes/32fbcb333d80bf2d9c4deb3c34721b5eaafae56be5d2e149e495473a64078d19/_data
[root@jump _data]# cp /etc/redis.conf ./

更改 配置 

[root@jump _data]# vi redis.conf 

daemonize yes

pidfile /var/run/redis.pid

slaveof master 6379

复制配置文件到redis启动目录下

root@b52dc49fd81a:/data# cp redis.conf /usr/local/bin 
root@b52dc49fd81a:/data# cd /usr/local/bin 
root@b52dc49fd81a:/usr/local/bin# redis-server redis.conf 

*** FATAL CONFIG FILE ERROR ***
Reading the configuration file, at line 163
>>> 'logfile /var/log/redis/redis.log'
Can't open the log file: No such file or directory
root@b52dc49fd81a:/usr/local/bin# mkdir /var/log/redis
root@b52dc49fd81a:/usr/local/bin# redis-server redis.conf 
root@b52dc49fd81a:/usr/local/bin# 

redis-slave2的配置同上面一样 

 

6.redis测试

首先进入Redis Master 容器

[root@jump _data]# docker ps  |grep redis-master     
8cb697b83074        redis               "docker-entrypoint..."   3 hours ago         Up 3 hours          6379/tcp                 redis-master
[root@jump _data]# docker exec -it 8cb6 /bin/bash
root@8cb697b83074:/data# 

启动服务端和客户端 并插入测试数据

root@8cb697b83074:/usr/local/bin# redis-server redis.conf       
root@8cb697b83074:/usr/local/bin# redis-cli 
127.0.0.1:6379> set master 8cb6
OK
127.0.0.1:6379> get master
"8cb6"
127.0.0.1:6379> 

然后在两个从节点上分别启动server 和 cli 查看数据是否已经同步

[root@jump _data]# docker ps |grep redis-salve2
b52dc49fd81a        redis               "docker-entrypoint..."   5 hours ago         Up 22 minutes       6379/tcp                 redis-salve2
[root@jump _data]# docker exec -it b52d /bin/bash
root@b52dc49fd81a:/data# cd /usr/local/bin/
root@b52dc49fd81a:/usr/local/bin# redis-server redis.conf
root@b52dc49fd81a:/usr/local/bin# redis-cli
127.0.0.1:6379> get master
"8cb6"
127.0.0.1:6379> 
[root@jump _data]# docker ps |grep salve1         
3c7d833d1bad        redis               "docker-entrypoint..."   5 hours ago         Up 3 minutes        6379/tcp                 redis-salve1
[root@jump _data]# docker exec -it 3c7d /bin/bash
root@3c7d833d1bad:/data# cd /usr/local/bin/      
root@3c7d833d1bad:/usr/local/bin# redis-server redis.conf 
root@3c7d833d1bad:/usr/local/bin# redis-cli 
127.0.0.1:6379> get master
"8cb6"

通过上面测试发现redis主节点的数据均已经同步到从节点数据库中。

 

7.APP节点(django)配置

#为了使得python支持redis,需要下载python下的redis第三方包

如果没有报错则安装成功,__file__ 是双底杠。python的内置方法。

退出python 命令行,容器的volumn 目录是 /usr/src/app ,在该目录下创建APP,执行过程如下

>>> exit()
root@17ef7fd98225:/# cd /usr/src/app/
root@17ef7fd98225:/usr/src/app# mkdir dockerweb
root@17ef7fd98225:/usr/src/app# cd dockerweb/
root@17ef7fd98225:/usr/src/app/dockerweb# django-admin.py startproject redisweb
root@17ef7fd98225:/usr/src/app/dockerweb# ls
redisweb
root@17ef7fd98225:/usr/src/app/dockerweb# cd redisweb/
root@17ef7fd98225:/usr/src/app/dockerweb/redisweb# ls
manage.py  redisweb
root@17ef7fd98225:/usr/src/app/dockerweb/redisweb# python manage.py startapp helloworld
lroot@17ef7fd98225:/usr/src/app/dockerweb/redisweb# ls
helloworld  manage.py  redisweb

host 的volume 目录是  ~/Projects/Django/App1/

dockerweb
[root@jump App1]# cd ~/Projects/Django/App1/
[root@jump App1]# ls
dockerweb

编辑App1的 视图文件

[root@jump App1]# cd dockerweb/redisweb/helloworld/
[root@jump helloworld]# ls
admin.py  apps.py  __init__.py  migrations  models.py  tests.py  views.py
[root@jump helloworld]# vim views.py 
[root@jump helloworld]# cat views.py 
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
import redis

def hello(request):
    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-APP1')
    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)
View Code

接下来修改setting.py文件

[root@jump redisweb]# ls
__init__.py  __pycache__  settings.py  urls.py  wsgi.py
[root@jump redisweb]# vi settings.py 

 

 

将你的helloworld项目注册一下

 

配置url.py  django的路由文件

 

 

 这些文件修改保存后,需要进入app容器中

[root@jump redisweb]# docker ps |grep APP1
17ef7fd98225        django              "/bin/bash"              6 hours ago         Up 32 seconds                                APP1
[root@jump redisweb]# docker exec -it 17ef /bin/bash
root@17ef7fd98225:/# 

 

 在容器中的  /usr/src/app/dockerweb/redisweb/ 目录下完成项目的生成。

root@17ef7fd98225:/# cd /usr/src/app/dockerweb/redisweb/

 

root@17ef7fd98225:/usr/src/app/dockerweb/redisweb# python manage.py makemigrations
No changes detected

创建超级用户admin,密码设置过短会不通过。

 

app2也是同app1一样的设置

 

 

分别在 app1 和 app2容器中指定端口运行项目,app1 对应8001 端口,app2对应8002端口

app1

root@17ef7fd98225:/usr/src/app/dockerweb/redisweb# python manage.py runserver 0.0.0.0:8001
Performing system checks...

System check identified no issues (0 silenced).
August 13, 2018 - 08:27:14
Django version 1.10.4, using settings 'redisweb.settings'
Starting development server at http://0.0.0.0:8001/
Quit the server with CONTROL-C.

app2

root@9ed901754f54:/usr/src/app/dockerweb/redisweb# python manage.py runserver 0.0.0.0:8002
Performing system checks...

System check identified no issues (0 silenced).
August 13, 2018 - 08:28:05
Django version 1.10.4, using settings 'redisweb.settings'
Starting development server at http://0.0.0.0:8002/
Quit the server with CONTROL-C.

 

8.HaProxy容器节点配置

进入 被haproxy容器挂载的目录

[root@jump ~]# cd ~/Projects/HAProxy/
[root@jump HAProxy]# vi haproxy.cfg

由于docker容器中没有vi命令,所以需要在 host的 volume 中提前对配置文件完成配置

global
    log 127.0.0.1 local0  #日志输出配置,所有日志都记录在本机,通过local0输出
    maxconn 4096        #最大连接数
    chroot /usr/local/sbin  #改变当前工作目录
    daemon      #以后台形式运行HAProxy
    nbproc  4   #启动4个HAProxy实例
    pidfile /usr/local/sbin/haproxy.pid   #pid文件位置

defaults
    log 127.0.0.1  local3  # 日志文件的输出定向
    mode http   #设定启动实例的协议类型
    option dontlognull  #保证HAProxy不记录上级负载均衡发送过来的用于检测状态没有数据的心跳包
    option redispatch   #当serverId对应的服务器挂掉后,强制定向到其他健康的服务器
    retries 2           #重试两次连接失败就认为服务器不可用,主要通过后面的check检查
    maxconn 2000        #最大连接数
    balance roundrobin  #balance 有两个可用选项:roundrobin和source,其中roundrobin表示
                        #轮询,而source表示HAproxy不采用轮询的策略,而是把来自某个IP的请求转发
                        #给一个固定IP的后端
bind-process 2 #默认跑在两颗cpu上 timeout connect 5000ms #连接超时时间 timeout client 50000ms #客户端连接超时时间 timeout server 50000ms #服务器端连接超时时间 listen redis_proxy

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容器的volume

[root@jump HAProxy]# docker start HAProxy
HAProxy
[root@jump HAProxy]# docker ps|grep HA
005d0ccc7c54        haproxy             "/docker-entrypoin..."   5 hours ago         Up 8 seconds        0.0.0.0:6301->6301/tcp   HAProxy
[root@jump HAProxy]# docker exec -it 005d /bin/bash
root@005d0ccc7c54:/# 
root@005d0ccc7c54:/# cd /tmp/
root@005d0ccc7c54:/tmp# cp haproxy.cfg /usr/local/sbin/
root@005d0ccc7c54:/tmp# cd /usr/local/sbin/    
root@005d0ccc7c54:/usr/local/sbin# haproxy -f haproxy.cfg 

 

通過宿主机的ip 访问django项目

 

 通过访问haproxy容器的ip  访问django项目

 

 到这里基于容器的 单机伪集群就搭建完毕了!

posted @ 2018-08-13 12:29  benjamin杨  阅读(615)  评论(1编辑  收藏  举报