Docker怎么搭建简单的应用栈与容器HelloWorld访问

本篇内容介绍了“Docker怎么搭建简单的应用栈与容器Hello World访问”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

成都创新互联公司是一家集网站建设,德城企业网站建设,德城品牌网站建设,网站定制,德城网站建设报价,网络营销,网络优化,德城网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

系统环境

操作系统版本

$ cat /etc/issue
debian gnu/linux 8 \n \l

内核版本

$ uname -r
3.16.0-4-amd64

docker版本

 docker version
client:
 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

server:
 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

应用栈搭建

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

Docker怎么搭建简单的应用栈与容器Hello World访问

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

根据应用栈结构,需要从docker hub获取haproxy、redis和django的镜像:

# docker pull ubuntu:14.04
# docker pull haproxy
# docker pull redis
# docker pull django
# docker images
repository     tag         image id      created       size
haproxy       latest       65599e2ea3f2    2 weeks ago     139.1 mb
redis        latest       0d1cbfaa41da    2 weeks ago     185 mb
ubuntu       14.04        4a725d3b3b1c    3 weeks ago     188 mb
django       latest       79d802ec2b6c    4 weeks ago     437.4 mb

应用栈容器节点互联

docker run --link redis:redis --name console ubuntu bash

此处将在ubuntu镜像上启动一个容器,并命名为console,同时将新启动的console容器连接到名为redis的容器上。docker run 命令的 --link选项用于添加连接到一个容器。这里还使用了 --name选项为容器指定名称。

关于docker link用法可参考本站《docker如何使用link建立容器之间的连接》

应用栈节点启动

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

  • 启动redis-master容器节点;

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

  • 两个app容器节点启动时连接到redis-master;

  • haproxy容器节点启动时连接到两个app节点。

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

综上,容器启动顺序为:

redis-master -》redis slave -》app -》haproxy

启动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

启动django容器

# 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

启动haproxy容器

# docker run -it --name haproxy --link app1:app1 --link app2:app2 -p 6301:6301 -v ~/projects/haproxy:tmp haproxy /bin/bash

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

容器启动信息查看:

# docker ps
container id    image        command         created       status       ports          names
ab25650701f0    haproxy       "/docker-entrypoint.s"  3 hours ago     up 3 hours     0.0.0.0:6301->6301/tcp  haproxy
ace790044e06    django       "/bin/bash"       3 hours ago     up 3 hours                  app2
64963af16131    django       "/bin/bash"       3 hours ago     up 3 hours                  app1
aa77330aee2a    redis        "docker-entrypoint.sh"  3 hours ago     up 3 hours     6379/tcp         redis-slave2
1fd72289d4f2    redis        "docker-entrypoint.sh"  3 hours ago     up 3 hours     6379/tcp         redis-slave1
518b41200dab    redis        "docker-entrypoint.sh"  3 hours ago     up 3 hours     6379/tcp         redis-master

应用栈容器节点配置

redis master主数据库容器节点配置

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

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

可以看出,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

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

daemonize yes
pidfile /var/run/redis.pid

redis.conf模板下载:

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

# cd /data
# cp redis.conf /usr/local/bin
# cd /usr/local/bin
# redis-server redis.conf

redis slave从数据库容器节点配置

与redis master容器节点类似,在启动redis slave容器节点之后,需要查看vloume信息,并创建启动配置文件。

对于redis从数据库,需要修改如下几个参数:

daemonize yes
pidfile /var/run/redis.pid
slaveof master 6379

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

# cd /data
# cp redis.conf /usr/local/bin
# cd /usr/local/bin
# redis-server redis.conf

redis数据库容器节点测试

在redis master和redis slave容器节点的配置和服务启动后,可以通过启动redis的客户端程序来测试数据库。

首先,在redis master容器内,启动redis的客户端程,并存储一个数据:

# redis-cli
127.0.0.1:6379> set master 518b
ok
127.0.0.1:6379> get master
"518b"

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

# redis-cli
127.0.0.1:6379> get master
"518b"

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

app容器节点(django)的配置

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

# pip install redis

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

# python
python 3.4.5 (default, aug 22 2016, 20:55:07)
[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

如上面的输出,则表示现在可以使用pythob语言调用redis数据库了。接下来创建web程序。以app1为例,进入宿主机的volume目录对新建app进行编辑。

在容器的volume目录下/usr/src/app下,开始创建app:

# cd /usr/src/app
# mkdir dockerweb
# cd dockerweb
# django-admin.py startproject redisweb
# ls
redisweb
# cd redisweb
# ls
manage.py redisweb
# python manager.py startapp helloworld
# ls
helloworld manage.py redisweb

在容器中创建app后,切换到宿主机的volume目录~/projects/django/app1下:

# cd ~/projects/django/app1
# ls
dockerweb

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

# cd dockerweb/redisweb/helloworld
# ls
admin.py __init__.py migrations models.py tests.py views.py
# vim views.py

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

from django.shortcuts import render
from django.http import httpresponse
# create your views here.
import redis
def hello(requset):
  str=redis.__file__
  str+="
"   r = redis.redis(host='db', port=6379, db=0)   info = r.info()   str+=("set hi 
")   r.set('hi', 'helloworld-app1')   str+=("get hi: %s 
" % r.get('hi'))   str+=("redis info: 
")   str+=("key: info value")   for key in info:     str+=("%s: %s
" % (key, info[key]))   return httpresponse(str)

注意,连接redis数据库时,使用–link参数创建db连接来代替具体的ip地址;同理,对于app2,使用想要的db连接即可。

接下来,修改redisweb项目的配置文件setiing.py,添加新建的helloworld应用:

# cd ../redisweb
# ls
__init__.py __pycache__ settings.py urls.py wsgi.py

在setting.py文件中的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',
]

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

# vim urls.py

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

from django.conf.urls import *
from django.contrib import admin
admin.autodiscover()
from helloworld.views import hello
urlpatterns = [
  url(r'^admin/', include(admin.site.urls)),
  url(r'^helloworld$', hello),
]

以上修改完成后,再次进入容器,在目录/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:
 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

至此,所有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:8001
performing system checks...

system check identified no issues (0 silenced).
september 20, 2016 - 23:16:44
django version 1.10, using settings 'redisweb.settings'
starting development server at http://0.0.0.0:8001/
quit the server with control-c.

haproxy容器节点配置

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

# cd ~/projects/haproxy/
# vim haproxy.cfg

修改后的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
  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

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

# cd /tmp
# cp haproxy.cfg /usr/local/sbin
# cd /usr/local/sbin
# ls
haproxy haproxy-systemd-wrapper haproxy.cfg

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

# haproxy -f haproxy.cfg

应用栈访问测试

在浏览器中访问http://172.17.0.7:6301/helloworld,可以看到app1或app2的页面(本地主机访问应用栈):

Docker怎么搭建简单的应用栈与容器Hello World访问

说明:172.17.0.7是haproxy容器的地址。

本地测试通过后,尝试在其他主机上通过应用栈入口地址的ip地址和6301端口访问应用栈app,即http://192.168.1.104:6301/helloworld,如下图所示(外网其他主机访问应用栈):

Docker怎么搭建简单的应用栈与容器Hello World访问

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

“Docker怎么搭建简单的应用栈与容器Hello World访问”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!


本文标题:Docker怎么搭建简单的应用栈与容器HelloWorld访问
网站链接:http://hbruida.cn/article/jihjpo.html