Docker教程
Docker —— 从入门到实践 简介 什么是 Docker 为什么要使用 Docker? 基本概念 Docker 镜像 Docker 容器 Docker 仓库 安装 Ubuntu 系列安装 Docker CentOS 系列安装 Docker Docker 镜像 获取镜像 列出本地镜像 创建镜像 存出和载入镜像 移除本地镜像 镜像的实现原理 Docker 容器 启动容器 后台(background)运行 终止容器 进入容器 导出和导入容器 删除容器 仓库 Docker Hub 私有仓库 仓库配置文件 Docker 数据管理 数据卷 数据卷容器 利用数据卷容器来备份、恢复、迁移数据卷 Docker 中的网络功能介绍 外部访问容器 容器互联 高级网络配置 快速配置指南 配置 DNS 容器访问控制 映射容器端口到宿主主机的实现 配置 docker0 网桥 自定义网桥 工具和示例 编辑网络配置文件 示例:创建一个点到点连接 实战案例 使用 Supervisor 来管理进程 创建 tomcat/weblogic 集群 多台物理主机之间的容器互联(暴露容器到真实网络中) 标准化开发测试和生产环境 安全 内核名字空间 控制组 Docker服务端的防护 内核能力机制 其它安全特性 总结 Dockerfile 基本结构 指令 创建镜像 底层实现 基本架构 名字空间 控制组 联合文件系统 容器格式 Docker 网络实现 Docker Compose 项目 简介 安装 使用 Compose 命令说明 YAML 模板文件 Docker Machine 项目 简介 安装 使用 Docker Swarm 项目 简介 安装 使用 swarm 调度策略 Swarm 过滤器 etcd 什么是 etcd 安装 使用 etcdctl Fig 快速搭建基于 Docker 的隔离开发环境 安装 Fig Fig客户端参考 fig.yml 参考 环境变量参考 使用 Django 入门 Fig 使用 Rail 入门 Fig 使用 Wordpress 入门 Fig CoreOS CoreOS介绍 Kubernetes 项目简介 快速上手 基本概念 kubectl 使用 基本架构 Mesos 项目 简介 Mesos + Marathon 安装与使用 Mesos 基本原理与架构 Mesos 配置项解析 Mesos 常见框架 附录一 Docker命令查询 附录二 常见仓库介绍 Ubuntu CentOS MySQL MongoDB Redis Nginx WordPress Node.js 附录三 资源链接

发布于 2015-09-22 15:37:30 | 358 次阅读 | 评论: 0 | 来源: 网络整理

术语

首先介绍几个术语。

  • 服务(service):一个应用容器,实际上可以运行多个相同镜像的实例。
  • 项目(project):由一组关联的应用容器组成的一个完整业务单元。

可见,一个项目可以由多个服务(容器)关联而成,Compose 面向项目进行管理。

场景

下面,我们创建一个经典的 Web 项目:一个 Haproxy,挂载三个 Web 容器。

创建一个 compose-haproxy-web 目录,作为项目工作目录,并在其中分别创建两个子目录:haproxyweb

Web 子目录

这里用 Python 程序来提供一个简单的 HTTP 服务,打印出访问者的 IP 和 实际的本地 IP。

index.py

编写一个 index.py 作为服务器文件,代码为

#!/usr/bin/python
#authors: yeasy.github.com
#date: 2013-07-05

import sys
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
import socket
import fcntl
import struct
import pickle
from datetime import datetime
from collections import OrderedDict

class HandlerClass(SimpleHTTPRequestHandler):
    def get_ip_address(self,ifname):
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        return socket.inet_ntoa(fcntl.ioctl(
            s.fileno(),
            0x8915,  # SIOCGIFADDR
            struct.pack('256s', ifname[:15])
        )[20:24])
    def log_message(self, format, *args):
        if len(args) < 3 or "200" not in args[1]:
            return
        try:
            request = pickle.load(open("pickle_data.txt","r"))
        except:
            request=OrderedDict()
        time_now = datetime.now()
        ts = time_now.strftime('%Y-%m-%d %H:%M:%S')
        server = self.get_ip_address('eth0')
        host=self.address_string()
        addr_pair = (host,server)
        if addr_pair not in request:
            request[addr_pair]=[1,ts]
        else:
            num = request[addr_pair][0]+1
            del request[addr_pair]
            request[addr_pair]=[num,ts]
        file=open("index.html", "w")
        file.write("<!DOCTYPE html> <html> <body><center><h1><font color=\"blue\" face=\"Georgia, Arial\" size=8><em>HA</em></font> Webpage Visit Results</h1></center>");
        for pair in request:
            if pair[0] == host:
                guest = "LOCAL: "+pair[0]
            else:
                guest = pair[0]
            if (time_now-datetime.strptime(request[pair][1],'%Y-%m-%d %H:%M:%S')).seconds < 3:
                file.write("<p style=\"font-size:150%\" >#"+ str(request[pair][1]) +": <font color=\"red\">"+str(request[pair][0])+ "</font> requests " + "from &lt<font color=\"blue\">"+guest+"</font>&gt to WebServer &lt<font color=\"blue\">"+pair[1]+"</font>&gt</p>")
            else:
                file.write("<p style=\"font-size:150%\" >#"+ str(request[pair][1]) +": <font color=\"maroon\">"+str(request[pair][0])+ "</font> requests " + "from &lt<font color=\"navy\">"+guest+"</font>&gt to WebServer &lt<font color=\"navy\">"+pair[1]+"</font>&gt</p>")
        file.write("</body> </html>");
        file.close()
        pickle.dump(request,open("pickle_data.txt","w"))

if __name__ == '__main__':
    try:
        ServerClass  = BaseHTTPServer.HTTPServer
        Protocol     = "HTTP/1.0"
        addr = len(sys.argv) < 2 and "0.0.0.0" or sys.argv[1]
        port = len(sys.argv) < 3 and 80 or int(sys.argv[2])
        HandlerClass.protocol_version = Protocol
        httpd = ServerClass((addr, port), HandlerClass)
        sa = httpd.socket.getsockname()
        print "Serving HTTP on", sa[0], "port", sa[1], "..."
        httpd.serve_forever()
    except:
        exit()

index.html

生成一个临时的 index.html 文件,其内容会被 index.py 更新。

$ touch index.html

Dockerfile

生成一个 Dockerfile,内容为

FROM python:2.7
WORKDIR /code
ADD . /code
EXPOSE 80
CMD python index.py

haproxy 目录

在其中生成一个 haproxy.cfg 文件,内容为

global
  log 127.0.0.1 local0
  log 127.0.0.1 local1 notice

defaults
  log global
  mode http
  option httplog
  option dontlognull
  timeout connect 5000ms
  timeout client 50000ms
  timeout server 50000ms

listen stats :70
    stats enable
    stats uri /

frontend balancer
    bind 0.0.0.0:80
    mode http
    default_backend web_backends

backend web_backends
    mode http
    option forwardfor
    balance roundrobin
    server weba weba:80 check
    server webb webb:80 check
    server webc webc:80 check
    option httpchk GET /
    http-check expect status 200

docker-compose.yml

编写 docker-compose.yml 文件,这个是 Compose 使用的主模板文件。内容十分简单,指定 3 个 web 容器,以及 1 个 haproxy 容器。

weba:
    build: ./web
    expose:
        - 80

webb:
    build: ./web
    expose:
        - 80

webc:
    build: ./web
    expose:
        - 80

haproxy:
    image: haproxy:latest
    volumes:
        - haproxy:/haproxy-override
        - haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
    links:
        - weba
        - webb
        - webc
    ports:
        - "80:80"
        - "70:70"
    expose:
        - "80"
        - "70"

运行 compose 项目

现在 compose-haproxy-web 目录长成下面的样子。

compose-haproxy-web
├── docker-compose.yml
├── haproxy
│   └── haproxy.cfg
└── web
    ├── Dockerfile
    ├── index.html
    └── index.py

在该目录下执行 docker-compose up 命令,会整合输出所有容器的输出。

$sudo docker-compose up
Recreating composehaproxyweb_webb_1...
Recreating composehaproxyweb_webc_1...
Recreating composehaproxyweb_weba_1...
Recreating composehaproxyweb_haproxy_1...
Attaching to composehaproxyweb_webb_1, composehaproxyweb_webc_1, composehaproxyweb_weba_1, composehaproxyweb_haproxy_1

此时访问本地的 80 端口,会经过 haproxy 自动转发到后端的某个 web 容器上,刷新页面,可以观察到访问的容器地址的变化。

访问本地 70 端口,可以查看到 haproxy 的统计信息。

当然,还可以使用 consul、etcd 等实现服务发现,这样就可以避免手动指定后端的 web 容器了,更为灵活。

最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务