跳转至

docker 反向代理和负载均衡

准备工作

检查 TCP 80 端口是否空闲

在 docker 主机执行下面的命令,检查 TCP 80 端口是否空闲:

ss -tln | grep ':80\b'

没有任何输出表示端口空闲。如果有如下输出表示端口已经被占用,需要停掉相关服务以释放端口,或者使用其他空闲的端口进行实验。

LISTEN    0         128                      *:80                     *:*       

创建 traefik 网络

traefik 与被代理的服务需要网络互联,我们创建一个专用的 docker 网络:

sudo docker network create traefik-bridge

部署 traefik

mkdir -p ~/my-compose/traefik && cd ~/my-compose/traefik

创建 docker-compose.yml 文件,内容如下:

version: "3.4"

services:

  traefik:
    image: "traefik:v2.1"
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "9901:8080"
    networks:
      - traefik-bridge
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

networks:
  traefik-bridge:
    external: true

然后启动项目:

sudo docker-compose up -d

部署站点

mkdir -p ~/my-compose/whoami && cd ~/my-compose/whoami

创建 docker-compose.yml 文件,内容如下:

version: "3.4"

services:

  whoami:
    image: "containous/whoami"
    networks:
      - traefik-bridge
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
      - "traefik.http.services.whoami.loadbalancer.server.port=80"

networks:
  traefik-bridge:
    external: true

然后启动项目:

sudo docker-compose up -d --scale whoami=3

上面我们启动了 3 个 whoami 容器,用来演示负载均衡的效果。启动完成后使用 curl --resolve 模拟访问 http://whoami.example.com

curl --resolve 'whoami.example.com:80:127.0.0.1' http://whoami.example.com

多次执行我们将得到不同容器的响应,如下所示:

$  curl --resolve 'whoami.example.com:80:127.0.0.1' http://whoami.example.com
Hostname: 1c5d68c07e11

$  curl --resolve 'whoami.example.com:80:127.0.0.1' http://whoami.example.com
Hostname: 534749b49fa5

$  curl --resolve 'whoami.example.com:80:127.0.0.1' http://whoami.example.com
Hostname: c5cad68fd97b

$  curl --resolve 'whoami.example.com:80:127.0.0.1' http://whoami.example.com
Hostname: 1c5d68c07e11

traefik 与 dokcer 集成后,可自动发现 docker 容器并配置负载均衡,部署 docker 容器时只需添加 label 即可。

部署 WordPress:

部署 WordPress,使用 wordpress.example.com 域名进行反向代理,Compose file 如下:

version: "3.4"

services:

  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress:
    depends_on:
      - db
    image: wordpress
    networks:
      - default
      - traefik-bridge
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wordpress.rule=Host(`wordpress.example.com`)"
      - "traefik.http.services.wordpress.loadbalancer.server.port=80"

volumes:
  db_data: {}

networks:
  traefik-bridge:
    external: true