搭建一个包含`6`个节点的`Docker`应用栈,其中包括一个负载均衡代理节点、两个`Web`应用节点、一个主数据库节点及两个从数据库节点。
会用到数据卷的知识
- 获取镜像:
获取Django镜像
$ docker pull django
获取HAProxy镜像
$ docker pull haproxy
获取Redis镜像
$ docker pull redis
查看本地镜像列表
$ docker images
- 应用容器节点间的互联,由于我们使用的为同一台宿主机,若为真正的分布式架构集群,还应处理容器的跨主机通信问题,在使用
run
命令创建容器时,添加--link
选项,通过容器名,进行容器间安全的交互通信; - 容器启动顺序:
- 启动
1
个redis-master
容器节点; - 启动
2
个redis-slave
容器节点并连接redis-master
节点; - 启动
2
个Web APP
容器节点并连接redis-master
节点; - 启动
1
个HAProxy
容器节点并连接2个Web APP
节点;
+打开之前创建好的容器
docker start “redis-master”
docker start “redis-slave1”
docker start “redis-slave2”
总共打开宿主机的7个终端, 每个终端连接一个容器
包含宿主机 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020042216114122.png)
启动redis数据库节点
$ docker exec -it redis-master /bin/bash(或docker run -it -h="redis-master" --name redis-master redis /bin/bash) $ docker exec -it redis-slave1 /bin/bash(或$ docker run -it -h="redis-slave1" --name=redis-slave1 --link redis-master:master redis /bin/bash) $ docker exec -it redis-slave2 /bin/bash(或$ docker run -it -h="redis-slave2" --name=redis-slave2 --link redis-master:master redis /bin/bash)
- 启动
启动APP节点(分别在APP1和APP2容器节点中进行)
$ docker run -it -h=“APP1” --name APP1 --link redis-master:db -v ~/Projects/Django/App1:/usr/src/app django /bin/bash
$ docker run -it -h=“APP2” --name APP2 --link redis-master:db -v ~/Projects/Django/App2:/usr/src/app django /bin/bash
启动HAProxy节点
~# docker run -it -h=“HAProxy” --name HAProxy --link APP1:APP1 --link APP2:APP2 -p 6301:6301 -v ~/Projects/HAProxy:/tmp haproxy /bin/bash
查看运行中的容器
$ docker ps
配置redis
数据库:
适用于1.12版本及以上
配置redis
数据库,在宿主机上创建redis
数据库的配置文件(注意目录)
redis-master
配置文件(直接新建即可):
$ vim redis-master.conf
daemonize yes
pidfile /var/run/redis.pid
port 6379
timeout 0
tcp-keepalive 0
databases 1
stop-writes-on-bgsave-error no
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /tmp/
maxmemory 2gb
maxmemory-policy allkeys-lru
appendonly no
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 512mb
hash-max-ziplist-entries 64
hash-max-ziplist-value 128
list-max-ziplist-entries 64
list-max-ziplist-value 128
set-max-intset-entries 64
zset-max-ziplist-entries 64
zset-max-ziplist-value 128
activerehashing yes
redis-slave
配置文件:
$ vim redis-slave.conf
daemonize yes
pidfile /var/run/redis.pid
port 6379
slaveof redis-master 6379
timeout 0
tcp-keepalive 0
databases 1
stop-writes-on-bgsave-error no
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /tmp/
maxmemory 2gb
maxmemory-policy allkeys-lru
appendonly no
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 512mb
hash-max-ziplist-entries 64
hash-max-ziplist-value 128
list-max-ziplist-entries 64
list-max-ziplist-value 128
set-max-intset-entries 64
zset-max-ziplist-entries 64
zset-max-ziplist-value 128
activerehashing yes
获取数据卷的挂载点
$ docker inspect -f ‘{{ .Mounts }}’ redis-master
$ docker inspect -f ‘{{ .Mounts }}’ redis-slave1
$ docker inspect -f ‘{{ .Mounts }}’ redis-slave2
#示例截图
分别记录挂载点
形如:/var/lib/docker/volumes//_data
拷贝配置文件
$ cp redis-master.conf <redis-master的挂载点>
$ cp redis-slave.conf <redis-slave1的挂载点>
$ cp redis-slave.conf <redis-slave2的挂载点>
#示例截图
#将redis-master.conf 和redis-slave.conf 分别copy到容器内部(数据卷知识)
#切换到redis-master 容器中操作
#进入 终端 slave1 中操作
#进入 终端 slave2 中操作
配置Web APP节点
在Web APP节点上
- 安装
redis
模块:
可能会更新安装 pip install --upgrade pip
$ pip install redis
+ 测试操作:
$ python
import redis
print(redis.__file__)
exit()
- 创建
Hello-World
的APP
:
$ cd /usr/src/app
$ mkdir dockerweb
$ cd dockerweb
$ django-admin.py startproject redisweb
$ cd redisweb
$ python manage.py startapp helloworld
示例截图:
进入宿主机
-
切换目录:
docker inspect -f ‘{{ .Mounts }}’ APP1
cd /root/Projects/Django/APP1
cd dockerweb/
cd redisweb
docker inspect -f ‘{{ .Mounts }}’ APP2
cd /root/Projects/Django/APP2
cd dockerweb/
cd redisweb
-
配置视图(
View
):
$ vim helloworld/views.py
from django.shortcuts import render
from django.http import HttpResponse
import redis
def hello(requset):
r = redis.Redis(host='db', port=6379, db=0)
# 在APP2节点修改为HelloWorld-APP2
r.set('app_info', 'HelloWorld-APP1')
app_info = bytes.decode(r.get('app_info'))
stu_num_info = int(4321)
info = "Hello, everyone!<br/>Get Hi: {0}<br/>Get stu_num: {1}<br/>".format(app_info, stu_num_info)
return HttpResponse(info)
- 更改配置文件:
$ vim redisweb/settings.py
# 文件内容
ALLOWED_HOSTS = ['*',]
INSTALLED_APPS = [
...
'helloworld',
]
- 配置
url
:
$ vim redisweb/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),
]
在Web APP
节点上 两个分别都要
- 初始化项目:root@1b787e4ab53b:/usr/src/app/dockerweb/redisweb#
$ python manage.py makemigrations
$ python manage.py migrate
示例截图:
- 启动服务:
APP1:
$ python manage.py runserver 0.0.0.0:8001
APP2:
$ python manage.py runserver 0.0.0.0:8002
示例截图:
配置HAProxy
节点
在宿主机上
- 切换目录:
$ cd ~/Projects/HAProxy/ - 创建配置文件:
$ vim haproxy.cfg
global
log 127.0.0.1 local0
maxconn 4096
chroot /usr/local/sbin
daemon
nbproc 4
pidfile /usr/local/sbin/haproxy.pid
defaults
log 127.0.0.1 local3
mode http
option dontlognull
option redispatch
retries 2
maxconn 2000
balance roundrobin
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
listen redis_proxy
bind 0.0.0.0:6301
stats enable
bind-process 1
stats uri /haproxy-stats
stats auth phil:NRG93012
server APP1 APP1:8001 check inter 2000 rise 2 fall 5
server APP2 APP2:8002 check inter 2000 rise 2 fall 5
示例截图:
在HAProxy
节点
- 切换目录:
$ cd /tmp - 复制配置文件:
$ cp haproxy.cfg /usr/local/sbin - 切换目录:
$ cd /usr/local/sbin - 启动服务:
$ haproxy -f haproxy.cfg
示例截图:
测试操作
- 使用浏览器访问,
http://<宿主机的IP地址>:<6301>/helloworld
示例截图:
- 多次请求代理节点,
HAProxy
节点会自动分发请求,达到负载均衡的目的;