Traefik

traefik是一个http反向代理、负载均衡工具.

traefik支持较多的后端协议(http[s]、Websocket、TCP)

traefik支持多种容器框架(docker compose、Swarm、k8s、Mesos), 能识别API后台热更新配置.

Traefik作为cf集群的负载均衡器

首先, 我们使用一份最简单的docker-compose文件启动traefik.

记住: 我们需要将docker.sock挂在到traefik的内部, 这样才能让traefik访问docker api.

  1. # version: "2"
  2. # services:
  3. WebProxy:
  4. image: traefik
  5. command: --api --docker # Enables the web UI and tells Traefik to listen to docker
  6. ports:
  7. - "80:80" # The HTTP port
  8. - "8080:8080" # The Web UI (enabled by --api)
  9. volumes:
  10. - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
  11. networks:
  12. - local

然后, 我们启动cfweb容器.

下面的labels中定义相关行为会被traefik容器动态感知。

  1. 1. traefik.port用于置顶当前容器需要代理的端口.
  2. 2. traefik.backen为容器service名称.
  3. 3. domainrule则根据实际情况的域名进行指定. 本地调试可以使用`localhost`.

(更多label请查看这里)

  1. # version: "2"
  2. # services:
  3. WebApp:
  4. image: candymi/cfweb:latest
  5. labels:
  6. - "traefik.port=8080"
  7. - "traefik.backend=WebApp"
  8. - "traefik.enable=true"
  9. - "traefik.domain=localhost"
  10. - "traefik.frontend.rule=Host:localhost"
  11. volumes:
  12. - ./script:/app/script
  13. networks:
  14. - local

Traefik与需要代理的容器之间必须网络互通. 否则会出现gateway timeout的错误提示.

  1. # version: "2"
  2. # services:
  3. networks:
  4. local:
  5. driver: bridge

Traefik与cf结合的动态扩容.

1. 启动Traefik + cf.

让我们进入cf的docker文件夹下. 这里已有了一份完整的docker-compose-with-traefik.yaml文件.

然后我们使用docker-compose -f docker-compose-with-traefik.yaml up -d启动我们的应用程序.

  1. [candy@MacBookPro:~/Documents/core_framework/docker] $ docker-compose -f docker-compose-with-traefik.yaml up -d
  2. Creating network "docker_local" with driver "bridge"
  3. Creating docker_WebProxy_1 ... done
  4. Creating docker_WebApp_1 ... done
  5. [candy@MacBookPro:~/Documents/core_framework/docker] $ ps
  6. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  7. 8803daa412f7 candymi/cfweb:latest "./cfadmin" 53 seconds ago Up 51 seconds docker_WebApp_1
  8. 021af162cdb4 traefik "/traefik --api --do…" 53 seconds ago Up 51 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp docker_WebProxy_1
  9. [candy@MacBookPro:~/Documents/core_framework/docker] $

使用我们使用浏览器打开localhost:/api/login或者使用curl -i localhost:/api/login可以看到请求返回.

这时候, 我们使用命令查看集群日志输出docker-compose -f docker-compose-with-traefik.yaml logs

  1. [candy@MacBookPro:~/Documents/core_framework/docker] $ docker-compose -f docker-compose-with-traefik.yaml logs
  2. Attaching to docker_WebApp_1, docker_WebProxy_1
  3. WebApp_1 | [2019/04/26 10:33:59] - 172.31.0.2 - 172.31.0.1 - /api/login - GET - 200 - req_time: 0.000324/Sec
  4. [candy@MacBookPro:~/Documents/core_framework/docker] $

可以看到, 集群已经正常启动了.

2. Traefik + cf的集群动态扩容

前面介绍过, traefik可以动态更新配置进行扩容(收缩). 那么在哪可以体现呢?

我们知道docker有scale可以动态添加与收缩container数量. 我们前面启动

现在, 我们还是使用docker-compose -f docker-compose-with-traefik.yaml启动cf实例.(前面启动过后就不用执行)

然后使用docker-compose -f docker-compose-with-traefik.yaml —scale WebApp=3命令将WebAppcontainer扩展为3个.

  1. [candy@MacBookPro:~/Documents/core_framework/docker] $ docker-compose -f docker-compose-with-traefik.yaml --scale WebApp=3
  2. Starting docker_WebApp_1 ... done
  3. Creating docker_WebApp_2 ... done
  4. Creating docker_WebApp_3 ... done
  5. [candy@MacBookPro:~/Documents/core_framework/docker] $

使用docker ps查看容器启动情况:

  1. [candy@MacBookPro:~/Documents/core_framework/docker] $ clear
  2. [candy@MacBookPro:~/Documents/core_framework/docker] $ docker ps
  3. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  4. cb53cb7c5892 candymi/cfweb:latest "./cfadmin" About a minute ago Up About a minute docker_WebApp_2
  5. 86ec0f97be0d candymi/cfweb:latest "./cfadmin" About a minute ago Up About a minute docker_WebApp_3
  6. 8803daa412f7 candymi/cfweb:latest "./cfadmin" 21 minutes ago Up 2 minutes docker_WebApp_1
  7. 021af162cdb4 traefik "/traefik --api --do…" 21 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp docker_WebProxy_1
  8. [candy@MacBookPro:~/Documents/core_framework/docker] $

由此可以看出WebApp扩容已经完成. 现在可以在http://localhost:8080/dashboard/看到, backend-WebApp的Server数量已经有3个了.

3. 测试Traefik + cf负载均衡.

traefik默认使用rr算法对后端服务进行负载均衡代理.

cfweb容器对每个http请求都会有记录日志打印, Docker也会在stdout日志输出加入前缀. 这样我们就知道请求分发到哪个容器内部了.

这里我们使用3次命令curl localhost:api/login来测试, docker 日志输出如下:

  1. Attaching to docker_WebApp_2, docker_WebApp_3, docker_WebApp_1, docker_WebProxy_1
  2. WebApp_3 | [2019/04/26 11:00:23] - 192.168.16.4 - 192.168.16.1 - /api/login - GET - 200 - req_time: 0.000534/Sec
  3. WebApp_1 | [2019/04/26 11:00:24] - 192.168.16.4 - 192.168.16.1 - /api/login - GET - 200 - req_time: 0.000247/Sec
  4. WebApp_2 | [2019/04/26 11:00:24] - 192.168.16.4 - 192.168.16.1 - /api/login - GET - 200 - req_time: 0.000297/Sec

可以看到. 容器对请求确实是进行轮训负载.

最后

  • Websocket不需要进行额外配置.

  • 如有特殊Header pass要求, 请自行查阅Traefik文档.