鍍金池/ 教程/ Linux/ 使用
利用數(shù)據(jù)卷容器來備份、恢復、遷移數(shù)據(jù)卷
Docker 網(wǎng)絡(luò)實現(xiàn)
實戰(zhàn) Django
YAML 模板文件
名字空間
控制組
編輯網(wǎng)絡(luò)配置文件
列出
進入容器
Compose 命令說明
創(chuàng)建 Tomcat/Weblogic 集群
守護態(tài)運行
快速配置指南
其它安全特性
示例:創(chuàng)建一個點到點連接
CentOS 系列安裝 Docker
數(shù)據(jù)卷容器
鏡像
指令
創(chuàng)建鏡像
Docker 容器
創(chuàng)建鏡像
常用倉庫
總結(jié)
什么是 Docker
存出和載入鏡像
使用
獲取鏡像
容器互聯(lián)
為什么要使用 Docker?
使用 Wordpress 入門 Fig
啟動
容器訪問控制
私有倉庫
使用
基本架構(gòu)
自定義網(wǎng)橋
環(huán)境變量參考
實戰(zhàn) Rail
服務(wù)端的防護
刪除
鏡像的實現(xiàn)原理
多臺物理主機之間的容器互聯(lián)
Docker 倉庫
簡介
數(shù)據(jù)卷
命令參考
使用 Supervisor 來管理進程
移除
基本結(jié)構(gòu)
命令查詢
終止容器
聯(lián)合文件系統(tǒng)
安裝
簡介
配置 DNS
內(nèi)核能力機制
導出和導入容器
配置 docker0 網(wǎng)橋
倉庫配置文件
內(nèi)核名字空間
標準化開發(fā)測試和生產(chǎn)環(huán)境
外部訪問容器
fig.yml 參考
Ubuntu 系列安裝 Docker
有用資源
安裝
端口映射實現(xiàn)
安裝 Fig
工具和示例
簡介
控制組
容器格式
Docker Hub

使用

術(shù)語

首先介紹幾個術(shù)語。

  • 服務(wù)(service):一個應用容器,實際上可以運行多個相同鏡像的實例。
  • 項目(project):由一組關(guān)聯(lián)的應用容器組成的一個完整業(yè)務(wù)單元。

可見,一個項目可以由多個服務(wù)(容器)關(guān)聯(lián)而成,Compose 面向項目進行管理。

場景

下面,我們創(chuàng)建一個經(jīng)典的 Web 項目:一個 Haproxy,掛載三個 Web 容器。

創(chuàng)建一個 compose-haproxy-web 目錄,作為項目工作目錄,并在其中分別創(chuàng)建兩個子目錄:haproxyweb

Web 子目錄

這里用 Python 程序來提供一個簡單的 HTTP 服務(wù),打印出訪問者的 IP 和 實際的本地 IP。

index.py

編寫一個 index.py 作為服務(wù)器文件,代碼為

#!/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 文件,其內(nèi)容會被 index.py 更新。

$ touch index.html

Dockerfile

生成一個 Dockerfile,內(nèi)容為

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

haproxy 目錄

在其中生成一個 haproxy.cfg 文件,內(nèi)容為

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 使用的主模板文件。內(nèi)容十分簡單,指定 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 項目

現(xiàn)在 compose-haproxy-web 目錄長成下面的樣子。

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

在該目錄下執(zhí)行 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 端口,會經(jīng)過 haproxy 自動轉(zhuǎn)發(fā)到后端的某個 web 容器上,刷新頁面,可以觀察到訪問的容器地址的變化。

訪問本地 70 端口,可以查看到 haproxy 的統(tǒng)計信息。

當然,還可以使用 consul、etcd 等實現(xiàn)服務(wù)發(fā)現(xiàn),這樣就可以避免手動指定后端的 web 容器了,更為靈活。

上一篇:使用 Wordpress 入門 Fig下一篇:簡介