介绍

在现代应用部署中,容器化技术已成为标准实践。Docker Compose 作为 Docker 官方的容器编排工具,允许我们通过一个简单的 YAML 文件来定义和运行多容器应用。本文将带领你完成一个完整的实战项目:使用 Docker Compose 编排一个包含三个 Web 服务容器和一个 HAProxy 负载均衡器的应用栈。

知识点

  1. 构建自定义的 Web 服务镜像:基于 CentOS 7 创建一个运行 Apache HTTP 服务器的 Docker 镜像。
  2. 配置 HAProxy 负载均衡器:编写 HAProxy 配置文件,实现请求在多个后端 Web 容器间的轮询分发。
  3. 使用 Docker Compose 定义服务:编写 docker-compose.yaml 文件,一键启动所有服务并建立正确的网络连接。
  4. 验证与监控:测试负载均衡是否生效,并通过 HAProxy 的内置监控页面查看运行状态。

技术栈

  • Docker:容器运行时
  • Docker Compose:多容器编排
  • HAProxy:高性能 TCP/HTTP 负载均衡器
  • Apache HTTP Server (httpd):Web 服务器

整体架构

本项目将部署一个由四个容器组成的应用栈:

  1. 三个 Web 服务容器 (weba, webb, webc):运行相同的自定义 CentOS + Apache 镜像,提供简单的网页服务。
  2. 一个 HAProxy 容器:作为反向代理和负载均衡器,接收外部 HTTP 请求,并将其轮询分发到后端的三个 Web 容器。

所有服务通过 Docker Compose 定义,共享同一个网络,确保容器间可以通过服务名直接通信。


环境准备与项目初始化

首先,我们需要创建项目目录并拉取所需的 HAProxy 镜像。

  1. 创建项目目录

    在终端中执行以下命令,创建一个名为 dockercompose 的目录,并进入其中。

mkdir dockercompose
cd dockercompose
  1. 创建 HAProxy 配置目录

    接着,创建一个专门用于存放 HAProxy 配置的子目录。

mkdir 001haproxy
cd 001haproxy/
  1. 拉取 HAProxy 镜像

    从 Docker Hub 拉取指定版本的 HAProxy 镜像。

docker pull haproxy:2.0.29-alpine

第一步:构建自定义 Web 服务镜像

我们将基于 CentOS 7 构建一个包含 Apache (httpd) 服务的自定义镜像。

  1. 创建 Dockerfile
    在 001haproxy 目录下,使用 vim 或其他编辑器创建一个名为 Dockerfile 的文件,并将以下内容粘贴进去。
FROM centos:7.7.1908
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
RUN curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
RUN yum clean all
RUN yum -y install httpd
ADD run-httpd.sh /run-httpd.sh
RUN chmod -v +x /run-httpd.sh
ADD index.html /var/www/html/
EXPOSE 80
WORKDIR /
CMD ["/bin/bash","/run-httpd.sh"]
  1. 创建启动脚本 run-httpd.sh
    在同一目录下,创建 run-httpd.sh 文件,内容如下。这个脚本用于在容器启动时运行 httpd 服务。
cat > run-httpd.sh << 'EOF'
#!/bin/bash
/usr/sbin/httpd -D FOREGROUND
EOF
  1. 创建默认网页 index.html
    创建一个简单的 index.html 文件作为网页的默认内容。
cat > index.html << EOF
test httpd !!!
EOF
  1. 构建镜像
    执行以下命令,根据 Dockerfile 构建一个名为 centos-httpd:v1 的镜像。
docker build -t centos-httpd:v1 .

第二步:配置 HAProxy 负载均衡

接下来,我们需要创建 HAProxy 的配置文件,定义负载均衡规则。

  1. 创建 haproxy.cfg 配置文件
    在 001haproxy 目录下,创建 haproxy.cfg 文件,并填入以下内容。
# 全局配置段
global
    # 日志输出到标准输出,适配docker容器
    log stdout format raw local0 info
    maxconn 4096
    user haproxy
    group haproxy

# 默认参数段,所有前端后端继承
defaults
    mode http
    # 七层http负载均衡
    log global
    option httplog
    option dontlognull
    timeout connect 5s
    timeout client 30s
    timeout server 30s

# 前端:监听宿主机80端口
frontend http_front
    bind *:80
    default_backend web_pool

# 后端:三台web服务(容器名weba/webb/webc,links互通直接写容器名:端口)
backend web_pool
    balance roundrobin # 轮询负载均衡
    # check:健康检查,自动剔除故障web节点
    server weba weba:80 check inter 3s fall 3 rise 2
    server webb webb:80 check inter 3s fall 3 rise 2
    server webc webc:80 check inter 3s fall 3 rise 2

# 可选:监控页面(127.0.0.1:8404 查看负载均衡状态)
listen stats
    bind *:8404
    stats enable
    stats uri /stats
    stats auth admin:123456

配置说明:**

  • balance roundrobin:定义了负载均衡算法为轮询,即请求会依次分发给后端的每个服务器。
  • server weba weba:80 ...:定义了后端服务器池 web_pool 中的三个节点,分别是 weba、webb、webc。check 参数启用了健康检查。
  • listen stats: 配置了一个监控页面,可以通过 http://<你的IP>:8404/stats 访问,用户名 admin,密码 123456。

第三步:编写 Docker-Compose 文件并启动服务

这是最后一步,我们将使用 docker-compose.yaml 文件来定义和启动整个应用栈。

  1. 创建 docker-compose.yaml 文件
    在 001haproxy 目录下,创建 docker-compose.yaml 文件,内容如下:
services:
  weba:
    image: centos-httpd:v1
  webb:
    image: centos-httpd:v1
  webc:
    image: centos-httpd:v1
  haproxy:
    image: haproxy:2.0.29-alpine
    volumes:
      - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
    links:
      - weba
      - webb
      - webc
    expose:
      - "80"
      - "8404"
    ports:
      - "80:80"
      - "8404:8404"

文件说明:**

  • weba, webb, webc: 定义了三个 Web 服务,都使用我们刚刚构建的 centos-httpd:v1 镜像。

  • haproxy:定义了 HAProxy 服务。

  • volumes: 将宿主机的 haproxy.cfg 文件挂载到容器内,实现配置。

  • links: 确保 haproxy 容器能与 weba, webb, webc 容器通过网络通信。

  • ports: 将容器的 80 端口(Web服务)和 8404 端口(监控页面)映射到宿主机。

  1. 启动服务

    在 docker-compose.yaml 文件所在目录执行以下命令,以后台模式启动所有服务。

docker-compose down # 如果之前有运行,先停止并清理
docker-compose up -d

第四步:验证与测试

服务启动后,我们来验证负载均衡是否生效。

  1. 查看容器状态

    执行 docker ps -a,你应该能看到四个正在运行的容器:haproxy, weba, webb, webc。

  2. 为每个 Web 容器设置不同的页面内容

    为了直观地看到请求被分发到了不同的容器,我们需要为它们设置不同的网页内容。

docker exec 001haproxy-weba-1 bash -c "echo 111 > /var/www/html/index.html"
docker exec 001haproxy-webb-1 bash -c "echo 222 > /var/www/html/index.html"
docker exec 001haproxy-webc-1 bash -c "echo 333 > /var/www/html/index.html"
  1. 测试负载均衡

    在你的宿主机上,多次执行 curl 命令访问你的服务器 IP 地址。

curl http://192.168.2.125

(请将 192.168.2.125 替换为你自己服务器的实际 IP 地址)

预期结果: 你应该会看到终端交替输出 111, 222, 333。这证明 HAProxy 正在以轮询的方式将请求分发给后端的三个 Web 容器。

  1. 访问监控页面

    打开浏览器,访问 http://192.168.2.125:8404/stats,使用用户名 admin 和密码 123456 登录,即可查看 HAProxy 的详细运行状态和统计信息。

更多推荐