- 可以使用Vagrant创建的虚拟机,也可以使用CentOS云主机
- 先
yum -y update
- 安装好Docker等基础环境,并熟悉其相关概念及基本操作命令:
使用官方安装脚本自动安装(使用阿里云镜像)(推荐):
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
安装指南(官方版)(英文):https://docs.docker.com/install/linux/docker-ce/centos/
安装指南(阿里云版):https://yq.aliyun.com/articles/110806?spm=5176.8351553.0.0.148d1991DNakM8- 启动Docker服务:
systemctl start docker
操作系统版本
# lsb_release -a
LSB Version: :core-4.1-amd64:core-4.1-noarch
Distributor ID: CentOS
Description: CentOS Linux release 7.5.1804 (Core)
Release: 7.5.1804
Codename: Core
内核版本
# uname -a
Linux izwz9a99qngm2xbbwktcbaz 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Docker版本
# docker version
Client:
Version: 18.09.0
API version: 1.39
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:48:22 2018
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.0
API version: 1.39 (minimum version 1.12)
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:19:08 2018
OS/Arch: linux/amd64
Experimental: false
根据教材流程,搭建包含6个节点的Docker应用栈,其中包括1个代理节点(HAProxy,负载均衡代理节点)、3个Web的应用节点(App1、App2、App3,使用Python语言设计的一个单文件数据库的基础Web应用)、1个注数据库节点(Master-redis)和2个从数据库节点(Slave-redis)。各节点功能解释如下:
Master-redis和Slave-redis(主从模式Redis):
使用一个Redis实例作为主机,其余的作为备份机。主机和备份机的数据完全一致,主机支持数据的写入和读取等各项操作,而从机则只支持与主机数据的同步和读取。也就是说,客户端可以将数据写入到主机,由主机自动将数据的写入操作同步到从机。主从模式很好的解决了数据备份问题,并且由于主从服务数据几乎是一致的,因而可以将写入数据的命令发送给主机执行,而读取数据的命令发送给不同的从机执行,从而达到读写分离的目的。
App1、App2、App3:
使用Python语言设计的一个单文件数据库的基础Web应用
HAProxy:
实现负载均衡
提示:可以不用获取Ubuntu镜像。
# docker pull django
# docker pull haproxy
# docker pull redis
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 415381a6cb81 27 hours ago 94.9MB
haproxy latest d97a2ef984e4 3 weeks ago 69.5MB
django latest eb40dcf64078 23 months ago 436MB
注意:输完一条,不要关闭当前标签,在XShell再开个新的标签页连进去,每个标签页对应一个容器的终端。
# docker run -it --name master-redis redis /bin/bash
# docker run -it --name slave-redis1 --link master-redis:master redis /bin/bash
# docker run -it --name slave-redis2 --link master-redis:master redis /bin/bash
# docker run -it --name App1 --link master-redis:db -v ~/projects/Django/App1:/usr/src/app django /bin/bash
# docker run -it --name App2 --link master-redis:db -v ~/projects/Django/App2:/usr/src/app django /bin/bash
# docker run -it --name App3 --link master-redis:db -v ~/projects/Django/App3:/usr/src/app django /bin/bash
# docker run -it --name HAProxy --link App1:App1 --link App2:App2 --link App3:App3 -p 6301:6301 -v ~/projects/HAProxy:/tmp haproxy /bin/bash
详细操作:
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27b2ef73250d haproxy "/docker-entrypoint.…" 18 minutes ago Up 18 minutes 0.0.0.0:6301->6301/tcp HAProxy
f699945848c3 django "/bin/bash" 18 minutes ago Up 18 minutes App3
d820efa12051 django "/bin/bash" 19 minutes ago Up 19 minutes App2
3472edfd4fa9 django "/bin/bash" 19 minutes ago Up 19 minutes App1
dbf05243db01 redis "docker-entrypoint.s…" 19 minutes ago Up 19 minutes 6379/tcp slave-redis2
726bbba9bd93 redis "docker-entrypoint.s…" 20 minutes ago Up 20 minutes 6379/tcp slave-redis1
1961c45d7715 redis "docker-entrypoint.s…" 30 minutes ago Up 30 minutes 6379/tcp master-redis
回到“主机”标签页,查看3个Redis节点挂载volume的情况:
命令格式:docker inspect <容器名> | grep Mounts -A 10
# docker inspect master-redis | grep Mounts -A 10
# docker inspect slave-redis1 | grep Mounts -A 10
# docker inspect slave-redis2 | grep Mounts -A 10
记下各容器的共享文件夹在主机的位置
# cd
# mkdir /data/redislog
# cp /data/redis.conf /usr/local/bin
# cd /usr/local/bin
# redis-server redis.conf
# redis-cli
127.0.0.1:6379> auth <你设置的master-redis的密码>(如果没有设置密码请跳过这步)
OK
127.0.0.1:6379> set master bc8e
OK
127.0.0.1:6379> get master
"bc8e"
# redis-cli
127.0.0.1:6379> auth <你设置的master-redis的密码>(如果没有设置密码请跳过这步)
OK
127.0.0.1:6379> get master
"bc8e"
由此可以看到,Master数据库中的数据已经自动同步到Slave数据库中。至此,应用栈的数据库部分已搭建完成,并通过测试。
分别切换到App1、App2、App3,执行以下命令:
更新匹配并安装Python语言的Redis支持包:
# pip install --upgrade pip
# pip install redis
安装完成后,进行简单的测试来验证支持包是否安装成功:
# python
Python 3.4.5 (default, Dec 14 2016, 18:54:20)
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import redis
>>> print(redis.__file__)
/usr/local/lib/python3.4/site-packages/redis/__init__.py
>>> exit()
# cd /usr/src/app
# mkdir dockerweb
# cd dockerweb
# django-admin.py startproject redisweb
# cd redisweb
# python manage.py startapp helloworld
# ls
helloworld manage.py redisweb
# cd ~/projects/Django/App1/dockerweb/redisweb/helloworld
# vim views.py
将代码换成如下内容,完成后保存并退出:
# -*- coding: utf-8 -*-
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
import redis
def hello(request):
red = 'APP1
Redis数据库记录:
'
# 如果设置过Redis密码请在参数中加上password='你的密码',
pool = redis.ConnectionPool(host='db', port=6379, db=0)
r = redis.StrictRedis(connection_pool=pool)
pipe = r.pipeline()
pipe_size = 100000
len = 0
key_list = []
print (r.pipeline())
keys = r.keys()
for key in keys:
key_list.append(key)
pipe.get(key)
if len < pipe_size:
len += 1
else:
for (k, v) in zip(key_list, pipe.execute()):
print (k, v, '')
len = 0
key_list = []
for (k, v) in zip(key_list, pipe.execute()):
red = red + '%s %s ' % (k.decode(), v.decode())
red = red + '
'
return HttpResponse(red)
# cd ~/projects/Django/App1/dockerweb/redisweb/redisweb
# vim settings.py
将ALLOWED_HOSTS = []
改成ALLOWED_HOSTS = ['*']
在INSTALLED_APPS选项下添加helloworld:
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'helloworld'
]
# vim urls.py
from django.conf.urls import include, url
from django.contrib import admin
from helloworld.views import hello
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^helloworld$', hello),
]
# cd /usr/src/app/dockerweb/redisweb
# python manage.py makemigrations
No changes detected
# python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying sessions.0001_initial... OK
# python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
No migrations to apply.
至此,所有App1容器配置已经完成,另外App2和App3容器配置也是同样的道理,只需要稍作修改即可。配置完App1和App2、App3容器后,就完成了应用栈的App部分的全部配置。
在启动App的Web服务器时,可以指定服务器的端口和IP地址。为了通过HAProxy容器节点接受外网所有的公共IP地址访问,实现均衡负载,需要指定服务器的IP地址和端口。对App1使用8001端口,App2使用8002端口,App3则使用8003端口,同时,都是用0.0.0.0地址。
以App1为例,启动服务器的过程如下:
切换到App1选项卡,执行如下步骤:
python manage.py runserver 0.0.0.0:8001
切换到App2选项卡,执行如下步骤:
python manage.py runserver 0.0.0.0:8002
切换到App3选项卡,执行如下步骤:
python manage.py runserver 0.0.0.0:8003
# 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 3
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
server APP3 APP3:8003 check inter 2000 rise 2 fall 5
# cd /tmp
# cp haproxy.cfg /usr/local/sbin
# cd /usr/local/sbin
# haproxy -f haproxy.cfg
打开浏览器,输入IP地址:6301/helloworld
即可看到App的views。
访问IP地址:6301/haproxy-stats
可以查看HAProxy当前状态。
原文件:https://github.com/antirez/redis/blob/5.0/redis.conf
master-redis的redis.conf需进行如下修改:
bind 127.0.0.1
前添加#
(注释掉)(不绑定到特定IP地址)protected-mode yes
改为protected-mode no
(关闭保护模式)requirepass
处设置一个连接密码,但在配置slave-redis和views.py时都要填入该密码。设置方式:将# requirepass foobared
改为requirepass 你的密码
daemonize no
改为daemonize yes
(开启守护进程)pidfile /var/run/redis_6379.pid
改为pidfile /var/run/redis.pid
logfile ""
改为logfile "/data/redislog/redis.log"
(将redis的日志单独保存到文件中)slave-redis的redis.conf除进行以上修改外,还需进行如下修改:
# replicaof
改为replicaof master 6379
# masterauth
改为masterauth 你的master-redis的密码
如果修改了HAProxy配置文件的内容,则需要先结束所有的HAProxy进程,并重新启动代理。可以使用killall命令来结束进程,如果进程中没有安装该命令,则需要先安装psmisc包,执行命令如下:
apt-get update
apt-get install psmisc
完成后直接执行killall haproxy
命令即可结束HAProxy进程
不小心关了一个docker终端的话可以使用docker exec
命令再次显示终端,格式如下:
docker exec -it <容器名> /bin/bash