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.
# version: "2"
# services:
WebProxy:
image: traefik
command: --api --docker # Enables the web UI and tells Traefik to listen to docker
ports:
- "80:80" # The HTTP port
- "8080:8080" # The Web UI (enabled by --api)
volumes:
- /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
networks:
- local
然后, 我们启动cfweb容器.
下面的labels中定义相关行为会被traefik容器动态感知。
1. traefik.port用于置顶当前容器需要代理的端口.
2. traefik.backen为容器service名称.
3. domain与rule则根据实际情况的域名进行指定. 本地调试可以使用`localhost`.
(更多label请查看这里)
# version: "2"
# services:
WebApp:
image: candymi/cfweb:latest
labels:
- "traefik.port=8080"
- "traefik.backend=WebApp"
- "traefik.enable=true"
- "traefik.domain=localhost"
- "traefik.frontend.rule=Host:localhost"
volumes:
- ./script:/app/script
networks:
- local
Traefik与需要代理的容器之间必须网络互通. 否则会出现gateway timeout
的错误提示.
# version: "2"
# services:
networks:
local:
driver: bridge
Traefik与cf结合的动态扩容.
1. 启动Traefik + cf.
让我们进入cf的docker文件夹下. 这里已有了一份完整的docker-compose-with-traefik.yaml
文件.
然后我们使用docker-compose -f docker-compose-with-traefik.yaml up -d
启动我们的应用程序.
[candy@MacBookPro:~/Documents/core_framework/docker] $ docker-compose -f docker-compose-with-traefik.yaml up -d
Creating network "docker_local" with driver "bridge"
Creating docker_WebProxy_1 ... done
Creating docker_WebApp_1 ... done
[candy@MacBookPro:~/Documents/core_framework/docker] $ ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8803daa412f7 candymi/cfweb:latest "./cfadmin" 53 seconds ago Up 51 seconds docker_WebApp_1
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
[candy@MacBookPro:~/Documents/core_framework/docker] $
使用我们使用浏览器打开localhost:/api/login
或者使用curl -i localhost:/api/login
可以看到请求返回.
这时候, 我们使用命令查看集群日志输出docker-compose -f docker-compose-with-traefik.yaml logs
[candy@MacBookPro:~/Documents/core_framework/docker] $ docker-compose -f docker-compose-with-traefik.yaml logs
Attaching to docker_WebApp_1, docker_WebProxy_1
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
[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
命令将WebApp
container扩展为3个.
[candy@MacBookPro:~/Documents/core_framework/docker] $ docker-compose -f docker-compose-with-traefik.yaml --scale WebApp=3
Starting docker_WebApp_1 ... done
Creating docker_WebApp_2 ... done
Creating docker_WebApp_3 ... done
[candy@MacBookPro:~/Documents/core_framework/docker] $
使用docker ps
查看容器启动情况:
[candy@MacBookPro:~/Documents/core_framework/docker] $ clear
[candy@MacBookPro:~/Documents/core_framework/docker] $ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb53cb7c5892 candymi/cfweb:latest "./cfadmin" About a minute ago Up About a minute docker_WebApp_2
86ec0f97be0d candymi/cfweb:latest "./cfadmin" About a minute ago Up About a minute docker_WebApp_3
8803daa412f7 candymi/cfweb:latest "./cfadmin" 21 minutes ago Up 2 minutes docker_WebApp_1
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
[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 日志输出如下:
Attaching to docker_WebApp_2, docker_WebApp_3, docker_WebApp_1, docker_WebProxy_1
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
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
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文档.