《容器与容器云》学习--搭建第一个Docker应用栈
docker的设计理念是希望用户能够保证一个容器只运行一个进程,即只提供一种服务。然而对于用户而言,大多数时候单一容器是无法满足需求的;通常来说,需要利用多个容器,分别提供不同的服务,并在不同的容器间互连通信,以形成一个docker集群,来完成特定的功能需求。
应用栈结构
HAproxy是负载均衡代理节点;redis的非关系型数据库,这里由一个主数据库节点和两个从数据库节点组成;APP1和APP2是应用节点,本例中是使用python语言和Django架构设计的访问数据库的基础Web应用。
获取应用栈中各节点所需镜像
sudo docker pull django sudo docker pull haproxy sudo docker pull redis
各容器节点启动
注意节点的启动顺序为:
redis-master -> redis-slave -> APP -> HAProxy
# 启动redis容器 # --link选项能够进行容器间安全的交互通信,使用格式是name:alias(名字:别名),该参数可多次使用 # 来表示启动的当前容器要连接到哪个容器上 sudo docker run -it --name redis-master redis /bin/bash sudo docker run -it --name redis-slave1 --link redis-master:master redis /bin/bash sudo docker run -it --name redis-slave2 --link redis-master:master redis /bin/bash # 启动django容器,~/Projects/Django/App1 # -v 参数用作目录挂载 宿主机目录(若不存在则自动创建):容器目录 sudo docker run -it --name APP1 --link redis-master:db -v ~/Projects/Django/App1:/usr/src/app django /bin/bash sudo docker run -it --name APP2 --link redis-master:db -v ~/Projects/Django/App2:/usr/src/app django /bin/bash # 启动haproxy容器 sudo docker run -it --name HAProxy --link APP1:APP1 --link APP2:APP2 -p 6301:6301 -v ~/Projects/HAProxy:/tmp haproxy /bin/bash
查看容器启动情况(一个代理容器,两个应用容器,三个数据库容器)
各节点配置
主数据库节点配置
redis-master主数据库容器节点配置
先查看容器所挂载volume的情况
docker inspect --format "{{.Mounts}}" [CONTAINER ID]
有如下样例输出:
可得知容器redis-master挂载在宿主机/var/lib/docker/volumes/7a50ae084ffe07409b5a3f4a97c097c87b9c1ba58c6ff4c8dcde961304d5c057/_data目录下,容器中的目录是/data
使用docker inspect [container id]可查看容器的详细信息
注意:若主机未安装相应版本redis。通过上一步docker inspect命令可以看到redis镜像的redis版本为6.0.5,因此先下载与其兼容的redis(对应的大版本即可),已安装的忽略此步骤
wget http://download.redis.io/releases/redis-6.0.5.tar.gz tar xzvf redis-6.0.5.tar.gz cd redis-6.0.5
进入主机volume目录,利用启动配置文件模板来创建主数据库的启动配置文件
cd /var/lib/docker/volumes/7a50ae084ffe07409b5a3f4a97c097c87b9c1ba58c6ff4c8dcde961304d5c057/_data cp <your-own-redis-dir>/redis.conf redis.conf vim redis.conf
redis-master的配置要修改以下几处:
bind 0.0.0.0 # 配置主redis可被搜索 daemonize yes # 是否进入后台 protected-mode no # 非保护模式,若为保护模式则只允许本地访问 pidfile /var/run/redis.pid
进入容器volume目录,并复制启动配置文件到redis的执行工作目录,然后启动redis服务器,执行过程如下:
cp redis.conf /usr/local/bin cd /usr/local/bin redis-server redis.conf
服务成功启动如下图所示。
从数据库节点配置
与redis-master类似,只不过在redis.conf目录中做一点不同的修改:
slaveof master 6379 # 表明是从数据库 bind 0.0.0.0 daemonize yes pidfile /var/run/redis.pid
配置完成后,主节点和两个从节点/usr/local/bin目录下都应该有以下文件
redis 数据库容器节点的测试
redis-cli 进入到redis的命令,使用set和get对其设置值和取值。
主数据库中:
从数据库取值测试:
说明主从数据库配置成功。
应用节点Django配置
以APP1容器为例。
1.进入到容器中,安装redis包。2.启动APP
安装redis
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 >>>
在容器的volume目录/usr/src/app/下 创建APP,执行以下:
cd /usr/src/app mkdir dockerweb cd dockerweb cd dockerweb django-admin.py startproject redisweb cd redisweb python manage.py startapp helloworld
再切换至主机volume目录
cd ~/Projects/Django/App1 ls # 此时应可见dockerweb
接下来编辑相应的配置文件:views、setting、urls
cd dockerweb/redisweb/helloworld/ vim views.py
views.py文件修改为:
from django.shortcuts import render # Create your views here. from django.http import HttpResponse 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)
注意这里在连接数据库时使用了–link参数创建db来代替具体的IP地址;同理对于APP2,也是使用相应的db进行连接即可。
接下来修改 redisweb目录下的setting.py
# 允许外来访问,这样才能够在其他主机访问我们的入口,否则只能进行本机测试 ALLOWED_HOSTS = ['*'] # 添加helloworld项目 # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'helloworld', ]
再是修改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), ]
在主机修改完这几个文件后,需要再次进入容器中,完成项目的生成。
cd /usr/src/app/dockerweb/redisweb/
执行以下命令 完成helloworld项目编译
python manage.py makemigrations python manage.py migrate python manage.py createsuperuser # 设置后台管理的用户名和密码 邮箱随便设置
启动项目,令APP1使用8001端口
python manage.py runserver 0.0.0.0:8001
容器APP2的配置与APP1类似,启动应用时将端口设置为8002即可。
HAProxy容器节点配置
HAProxy是负载均衡代理的容器节点,所有对应用栈的访问将通过它来实现负载均衡。
首先,启动容器,利用容器启动时挂载的volume,将HAProxy的启动配置文件复制进容器中,在~/Projects/HAProxy中,执行:
cd ~/Projects/HAProxy vim haproxy.cfg
配置文件的内容为:
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 # {tcp|http|health} 设定启动实例的协议类型 option dontlognull option redispatch retries 2 # 重试两次连接失败就认为服务器不可用 maxconn 2000 # 最大连接数 balance roundrobin # 有两个可用选项,roundrobin和source。前者表示轮询,后者表示将来自某个IP的请求转发给一个固定IP的后端 timeout connect 5000ms # 连接超时时间 timeout client 50000ms # 客户端连接超时时间 timeout server 50000ms # 服务器端连接超时时间 listen redis_proxy bind 0.0.0.0:6301 # 绑定6301端口 bind-process 2 # 设置跑在两个CPU上 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
进入容器的/tmp目录 将HAProxy启动配置文件复制到HAProxy的工作目录中,启动HAProxy
cd /tmp cp haproxy.cfg /usr/local/sbin cd /usr/local/sbin haproxy -f haproxy.cfg
本地测试
测试其他主机访问应用(10.249.45.54是部署应用栈的机器的IP)
测试成功。Docker应用栈搭建完毕。
参考资料:
- Docker入门学习(2)----Docker安装和第一个hello-world
- 个人学习笔记--MyBatis-的搭建及第一个程序
- django 第一个项目-学习搭建博客 (二、Django模型)
- SSH与SSM学习之Struts201——介绍与环境搭建和第一个例子
- Docker入门学习(4)----Dockerfile制作第一个镜像和容器中的第一个javaweb应用
- Ubuntu14.04 学习二: C/C++环境搭建,执行第一个hello world
- springboot学习: 初识Spring Boot框架,搭建第一个项目!
- android系统学习:第一讲:开发环境搭建及第一个android应用程序
- Docker学习第一章---学习环境和运行第一个容器
- Docker学习之——Node.js+MongoDB+Nginx环境搭建(一)
- [maven学习笔记]第一节,认识maven,搭建maven开发环境,写第一个HelloWorld
- Docker学习笔记 — Docker私有仓库搭建
- ESP8266学习一Arduino开发环境搭建及第一个Wifi点灯开发例子
- Java入门学习-理解什么是JRE和JDK,然后搭建JAVA开发环境,用eclipse写出第一个helloworld程序
- [maven学习笔记]第一节,认识maven,搭建maven开发环境,写第一个HelloWorld
- Docker 学习 (三)—— 持续集成环境搭建
- Docker学习笔记之一,搭建一个JAVA Tomcat运行环境
- django 第一个项目-学习搭建博客 (四、Django url 和视图)
- Docker学习记录3: 搭建 Private Registry
- Cocos2d-x学习(二) 在Cocos2d-x2.2.6搭建你第一个项目