• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Docker搭建简单的应用栈与容器Hello World访问详解

    本文实例讲述了Docker搭建简单的应用栈与容器Hello World访问。分享给大家供大家参考,具体如下:

    这里参考《Docker容器和容器云》 2.3.2章节应用栈搭建过程,对原书中出现的问题 -镜像不断的更新导致- 做了修改,特此说明。

    系统环境

    操作系统版本

    $ 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 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建立容器之间的连接》

    应用栈节点启动

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

    此外,为了能够从外网访问应用栈,并通过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模板下载: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
    
    

    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+="<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)
    
    

    注意,连接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的页面(本地主机访问应用栈):

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

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

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

    希望本文所述对大家docker容器使用有所帮助。

    上一篇:详解Nginx SSL快速双向认证配置(脚本)
    下一篇:Linux下指定源ip进行ping操作的方法
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯

    时间:9:00-21:00 (节假日不休)

    地址:江苏信息产业基地11号楼四层

    《增值电信业务经营许可证》 苏B2-20120278

    Docker搭建简单的应用栈与容器Hello World访问详解 Docker,搭建,简单,的,应用,