A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 不二晨 金牌黑马   /  2018-10-23 09:08  /  732 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

系统环境

操作系统版本

$ cat /etc/issueDebian GNU/Linux 8 \n \l
  • 1
  • 2

内核版本

$ uname -r3.16.0-4-amd64
  • 1
  • 2

Docker版本

docker versionClient: Version:      1.12.1 API version:  1.24 Go version:   go1.6.3 Git commit:   23cf638 Built:        Thu Aug 18 05:02:53 2016 OS/Arch:      linux/amd64Server: Version:      1.12.1 API version:  1.24 Go version:   go1.6.3 Git commit:   23cf638 Built:        Thu Aug 18 05:02:53 2016 OS/Arch:      linux/amd64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
应用栈搭建

我们将搭建一个包含6个节点的Docker应用栈,其中包括一个代理节点、两个Web应用节点、一个主数据库节点及两个从数据库节点。应用栈的具体结构如图所示:

获取应用栈节点所需的镜像

根据应用栈结构,需要从Docker Hub获取HAProxy、Redis和Django的镜像:

# docker pull ubuntu:14.04# docker pull haproxy   # docker pull redis# docker pull django# docker imagesREPOSITORY          TAG                 IMAGE ID            CREATED             SIZEhaproxy             latest              65599e2ea3f2        2 weeks ago         139.1 MBredis               latest              0d1cbfaa41da        2 weeks ago         185 MBubuntu              14.04               4a725d3b3b1c        3 weeks ago         188 MBdjango              latest              79d802ec2b6c        4 weeks ago         437.4 MB
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
应用栈节点启动

启动应用栈节点之前先整理应用栈节点的连接过程:

  • 启动redis-master容器节点;
  • 两个redis-slave容器节点启动时连接到redis-master;
  • 两个APP容器节点启动时连接到redis-master;
  • HAProxy容器节点启动时连接到两个APP节点。

此外,为了能够从外网访问应用栈,并通过HAproxy节点访问应用栈中的APP,在启动HAProxy节点时使用-p参数将端口暴露给主机。

启动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
  • 1
  • 2
  • 3

启动Gjango容器

# 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
  • 1
  • 2

启动HAproxy容器

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

说明:启动每个容器时都需分配一个终端。

容器启动信息查看:

# docker psCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMESab25650701f0        haproxy             "/docker-entrypoint.s"   3 hours ago         Up 3 hours          0.0.0.0:6301->6301/tcp   HAProxyace790044e06        django              "/bin/bash"              3 hours ago         Up 3 hours                                   APP264963af16131        django              "/bin/bash"              3 hours ago         Up 3 hours                                   APP1aa77330aee2a        redis               "docker-entrypoint.sh"   3 hours ago         Up 3 hours          6379/tcp                 redis-slave21fd72289d4f2        redis               "docker-entrypoint.sh"   3 hours ago         Up 3 hours          6379/tcp                 redis-slave1518b41200dab        redis               "docker-entrypoint.sh"   3 hours ago         Up 3 hours          6379/tcp                 redis-master
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
应用栈容器节点配置Redis Master主数据库容器节点配置

我们知道通过volume可以在宿主机和容器之间共享数据,因此可在宿主机上创建和编辑Redis的启动配置文件。使用docker inpect命令查看volume挂载情况:

# docker inspect -f '{{ .Mounts }}' redis-master[{5920a23b5e230a449230bbd4807912793bbc3bab0a05ae085ff95423301f0d6c /var/lib/docker/volumes/5920a23b5e230a449230bbd4807912793bbc3bab0a05ae085ff95423301f0d6c/_data /data local  true }]
  • 1
  • 2

可以看出,redis-master的volume在宿主机上为目录/var/lib/docker/volumes/5920a23b5e230a449230bbd4807912793bbc3bab0a05ae085ff95423301f0d6c/_data,在容器中为/data。
执行如下命令创建Redis的启动配置文件redis.conf:

# cd /var/lib/docker/volumes/5920a23b5e230a449230bbd4807912793bbc3bab0a05ae085ff95423301f0d6c/_data# cp /~/redis.conf .# vim redis.conf
  • 1
  • 2
  • 3

对于redis主数据库,修改如下模板文件中的几个参数:

daemonize yespidfile /var/run/redis.pid
  • 1
  • 2

redis.conf模板下载:https://github.com/yhsong-linux/docker-redis/blob/master/redis.conf

在宿主机上创建好启动配置文件后,切换到容器中的/data目录,将redis.conf拷贝到执行工作目录,然后启动redis服务:

# cd /data # cp redis.conf /usr/local/bin# cd /usr/local/bin# redis-server redis.conf
  • 1
  • 2
  • 3
  • 4
Redis Slave从数据库容器节点配置

与Redis Master容器节点类似,在启动Redis Slave容器节点之后,需要查看vloume信息,并创建启动配置文件。
对于Redis从数据库,需要修改如下几个参数:

daemonize yespidfile /var/run/redis.pidslaveof master 6379
  • 1
  • 2
  • 3

在宿主机上创建好启动配置文件后,切换到容器中的/data目录,将redis.conf拷贝到执行工作目录,然后启动redis服务:

# cd /data # cp redis.conf /usr/local/bin# cd /usr/local/bin# redis-server redis.conf
  • 1
  • 2
  • 3
  • 4
Redis数据库容器节点测试

在Redis Master和Redis Slave容器节点的配置和服务启动后,可以通过启动Redis的客户端程序来测试数据库。
首先,在Redis Master容器内,启动Redis的客户端程,并存储一个数据:

# redis-cli127.0.0.1:6379> set master 518bOK127.0.0.1:6379> get master"518b"
  • 1
  • 2
  • 3
  • 4
  • 5

接着,在两个Redis Slave容器内,分别启动Redis的客户端程,查询之前在Master数据库中存储的数据:

# redis-cli127.0.0.1:6379> get master"518b"
  • 1
  • 2
  • 3

根据响应可知,Master数据库中的数据已经同步到Slave数据库中。至此,应用栈的数据库部分搭建完成。

APP容器节点(Django)的配置

Django容器启动后,需要利用Django框架,开发一个简单的Web程序。为了访问数据库,需要在容器中安装Python的Redis支持包:

# pip install redis
  • 1

安装完成后,验证支持包是否安装成功:

# pythonPython 3.4.5 (default, Aug 22 2016, 20:55:07) [GCC 4.9.2] on linuxType "help", "copyright", "credits" or "license" for more information.>>> import redis>>> print(redis.__file__)/usr/local/lib/python3.4/site-packages/redis/__init__.py
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如上面的输出,则表示现在可以使用Pythob语言调用Redis数据库了。接下来创建Web程序。以APP1为例,进入宿主机的volume目录对新建APP进行编辑。
在容器的volume目录下/usr/src/app下,开始创建APP:

# cd /usr/src/app# mkdir dockerweb# cd dockerweb# django-admin.py startproject redisweb# lsredisweb # cd redisweb# lsmanage.py  redisweb# python manager.py startapp helloworld# lshelloworld  manage.py  redisweb
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在容器中创建APP后,切换到宿主机的volume目录~/Projects/Django/App1下:

# cd ~/Projects/Django/App1# lsdockerweb
  • 1
  • 2
  • 3

可以看到,在容器内创建的APP文件在宿主机的volume目录下同样可见。然后修改helloword应用的视图文件views.py:

# cd dockerweb/redisweb/helloworld# lsadmin.py  __init__.py  migrations  models.py  tests.py  views.py# vim views.py
  • 1
  • 2
  • 3
  • 4

修改后的views.py文件如下:

from django.shortcuts import renderfrom django.http import HttpResponse# Create your views here.import redisdef hello(requset):    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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

注意,连接Redis数据库时,使用–link参数创建db连接来代替具体的IP地址;同理,对于APP2,使用想要的db连接即可。
接下来,修改redisweb项目的配置文件setiing.py,添加新建的helloworld应用:

# cd ../redisweb# ls__init__.py  __pycache__  settings.py  urls.py  wsgi.py
  • 1
  • 2
  • 3

在setting.py文件中的INSTALLED_APPS选项下添加helloworld:

# Application definitionINSTALLED_APPS = [    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',    'helloworld',]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

最后,修改redisweb项目的URL模板文件urls.py,它将设置访问应用的URL模式,并为URL模式调用的视图函数之间的映射表:

# vim urls.py
  • 1

在url.py文件中,引入helloworld应用的hello视图,并为hello视图添加一个urlpatterns变量。修改后的urls.py文件如下:

from django.conf.urls import * from django.contrib import adminadmin.autodiscover()from helloworld.views import hellourlpatterns = [    url(r'^admin/', include(admin.site.urls)),   url(r'^helloworld$', hello),]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

以上修改完成后,再次进入容器,在目录/usr/src/app/dockerweb/redisweb下生成项目:

# python manage.py makemigrationsNo changes detected# python manage.py migrateOperations to perform:  Apply all migrations: admin, auth, contenttypes, sessionsRunning migrations:  Rendering model states... DONE  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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

至此,所有APP1容器的配置已经完成,APP2容器的配置也是同样的过程。配置完成APP1和APP2的容器后,就完成了应用栈的APP部分的全部配置。
在启动APP容器的Web服务器时,可以指定服务器的端口和IP地址,为了通过HAproxy容器节点接受外网所有的公共IP地址访问,实现负载均衡,需要指定服务器的IP地址和端口。对于APP1使用8001端口,而APP2使用8002端口,同时,都使用0.0.0.0地址。以APP1为例,启动服务器的过程如下:

# python manage.py runserver 0.0.0.0:8001# python manage.py runserver 0.0.0.0:8001Performing system checks...System check identified no issues (0 silenced).September 20, 2016 - 23:16:44Django version 1.10, using settings 'redisweb.settings'Starting development server at http://0.0.0.0:8001/Quit the server with CONTROL-C.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
HAproxy容器节点配置

所有对应用栈的访问均通过HAproxy负载均衡代理容器节点实现负载均衡。
首先,将HAProxy的启动配置我呢间复制到容器中,在宿主机的volumes目录~/Projects/HAProxy/下:

# cd ~/Projects/HAProxy/# vim haproxy.cfg
  • 1
  • 2

修改后的haproxy.cfg文件如下:

global    log 127.0.0.1   local0    maxconn 4096    chroot /usr/local/sbin    daemon    nbproc  4    pidfile /usr/local/sbin/haproxy.piddefaults    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  50000mslisten redis_proxy      bind 0.0.0.0:6301    stats enable    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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

随后,进入容器的volume目录/tmp下,将Haproxy的启动配置文件复制到HAproxy的工作目录:

# cd /tmp# cp haproxy.cfg /usr/local/sbin# cd /usr/local/sbin# lshaproxy  haproxy-systemd-wrapper  haproxy.cfg
  • 1
  • 2
  • 3
  • 4
  • 5

然后,利用配置文件启动HAProxy代理:

# haproxy -f haproxy.cfg
  • 1
应用栈访问测试

在浏览器中访问http://172.17.0.7:6301/helloworld,可以看到APP1或APP2的页面:

说明:172.17.0.7是HAProxy容器的地址。
本地测试通过后,尝试在其他主机上通过应用栈入口地址的IP地址和6301端口访问应用栈APP,即http://192.168.1.104:6301/helloworld,如下图所示:

说明:192.168.1.104是宿主机的IP地址。

【转载】https://blog.csdn.net/u012066426 ... tm_source=blogxgwz4


2 个回复

倒序浏览
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马