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文档.