Docker Compose项目一

本文详细介绍如何使用Docker Compose搭建HAProxy负载均衡器与三个Web容器的环境,通过Python编写简易HTTP服务,实现访问者IP记录与展示,同时配置HAProxy进行流量分配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

案例场景
下面,我们创建一个经典的 Web 项目:一个 Haproxy,挂载三个 Web 容器。
创建一个 compose-haproxy-web 目录,作为项目工作目录,并在其中分别创建两个子目录: haproxy 和 web 。

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

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

root@node5 web]# vi 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 更新。

[root@node5 web]# touch index.html

编写 Dockerfile 文件,内容为

[root@node5 web]# vi Dockerfile
FROM python:2.7
WORKDIR /code
ADD . /code
EXPOSE 80
CMD python index.py

haproxy 目录
编写 haproxy.cfg 文件,内容为

[root@node5 haproxy]# vi 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
  bind 0.0.0.0: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 容器。

[root@node5 compose-haproxy-web]# vi docker-compose.yml
version: "3"
services:
    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
      ports:
          - "80:80"
          - "70:70"
      expose:
          - "80"
          - "70"

运行 compose 项目
现在 compose-haproxy-web 目录结构如下:

[root@node5 compose-haproxy-web]# tree 
.
├── docker-compose.yml
├── haproxy
│   └── haproxy.cfg
└── web
    ├── Dockerfile
    ├── index.html
    └── index.py

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

[root@node5 compose-haproxy-web]# 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_web
a_1, composehaproxyweb_haproxy_1

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值