不可否认,Nginx作为老牌的负载软件经久不衰,依然是绝大多数情况下的不二选择,但是在云原生时代,Nginx却显得力有不逮。
由于微服务架构以及Docker技术和K8s编排工具最近几年才开始逐渐流行,所以一开始的反向代理服务器比如Nginx、Apache等并未提供其支持。所以才会出现Ingress Controller这种东西来做k8s和Nginx之间的衔接。而Traefik天生就提供了Docker、k8s的支持,也就是说traefik本身就能跟k8s api交互感知后端变化,因此在使用traefik时,Ingress controller和nginx这类工具就失去了存在的意义。
在目前我们使用Docker-Compose编排所有微服务的阶段,Traefik能够依赖自身的特性,自动发现服务的变更,动态调整自身的负载均衡配置。
一、示例
下面我们通过一个示例,来展现traefik在容器化时代的过人之处。
version: "3.8"
services:
traefik:
image: traefik:v2.4.8
ports:
- 18181:80
- 18182:8080
volumes:
- "/var/run/docker.sock:/var/run/docker.sock" # trafik通过docker.sock监控后端变化
command:
- "--api.insecure=true" # 开启不安全接口方便本地调试
- "--api.dashboard=true" # 开启Dashboard便于调式,生产环境建议关闭
- "--accesslog=true" # 开启日志
- "--providers.docker=true" # 后端使用Docker作为工作模式
- "--entrypoints.testapi.address=:80" # 新建一个名为 testapi 的入口监听80端口
whoami:
image: containous/whoami
labels:
- "traefik.http.routers.app.rule=Host(`192.168.1.178`)" # 用户使用 localhost 访问时,此服务进行响应
- "traefik.http.routers.app.entrypoints=testapi" # 入口为 testapi
docker-compoes启动 docker-compose up --scale whoami=3
后,使用 curl 进行访问 curl http://192.168.1.178:18181/
, 得到的响应如下:
Hostname: 21274e83b339
IP: 127.0.0.1
IP: 172.30.0.2
RemoteAddr: 172.30.0.3:56066
GET / HTTP/1.1
Host: 192.168.1.178:18181
User-Agent: curl/7.64.1
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.100.1.7
X-Forwarded-Host: 192.168.1.178:18181
X-Forwarded-Port: 18181
X-Forwarded-Proto: http
X-Forwarded-Server: 89a1ed50d8e4
X-Real-Ip: 10.100.1.7
多次访问,每次响应的Hostname都是不同的,说明traefik实现了请求在多个whoami
容器之间进行负载。
如果使用多级路径进行路由判断可以添加如下配置
- "traefik.http.routers.app.rule=Path(`/test`)" # 指定/test路径才响应
此时我们需要使用 http://192.168.1.178:18181/test
才能获得正确响应。
二、跨 docker-compose 负载演示
上面的内容都是基础性的配置演示,下面简单介绍一下在docker-compose中更有意思的配置。
我们在另一个 docker-compose 中启动一个新的 whoami
服务
version: "3.8"
services:
whoami2:
image: containous/whoami
labels:
- "traefik.http.routers.1.rule=Host(`192.168.1.178`)" # 用户使用 localhost 访问时,此服务进行响应
- "traefik.http.routers.1.rule=Path(`/test2`)"
- "traefik.http.routers.1.entrypoints=testapi" # 入口为 testapi
当我们使用 http://192.168.1.178:18181/test
访问时响应的是第一个docker-compse中的服务,使用http://192.168.1.178:18181/test2
访问时,响应的则是第二个docker-compose中的服务。
三、负载均衡演示
那么如果想通过 /test
路径实现跨docker-compose中的两个服务之间的负载呢?
version: "3.8"
services:
traefik:
image: traefik:v2.4.8
ports:
- 18181:80
- 18182:8080
volumes:
- "/var/run/docker.sock:/var/run/docker.sock" # trafik通过docker.sock监控后端变化
command:
- "--api.insecure=true" # 开启不安全接口方便本地调试
- "--api.dashboard=true" # 开启Dashboard便于调式,生产环境建议关闭
- "--accesslog=true" # 开启日志
- "--providers.docker=true" # 后端使用Docker作为工作模式
- "--entrypoints.testapi.address=:80" # 新建一个名为 testapi 的入口监听80端口
whoami:
image: containous/whoami
labels:
- "traefik.http.routers.app.entrypoints=testapi" # 入口为 testapi
- "traefik.http.routers.app.rule=Host(`192.168.1.178`)" # 用户使用 localhost 访问时,此服务进行响应
- "traefik.http.routers.app.rule=Path(`/test`)"
- "traefik.http.services.whoami.loadbalancer.server.scheme=http"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
whoami_2:
image: containous/whoami
labels:
- "traefik.http.services.whoami.loadbalancer.server.scheme=http"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
此时使用curl http://192.168.1.178:18181/test
会有2个容器分别进行负载响应,从此以后,容器内的服务变更都不在需要更新nginx配置文件了
五、可观测性
在Traefik-2.x的生态里,将可观测性分成了如下几部分
- 服务日志: Traefik 进程本身相关的操作日志
- 访问日志: 由Traefik接管的代理服务的访问日志
- Metrics: Traefik 提供的自身详细的metrics数据
- Tracing: Traefik也提供了链路追踪相关接口,可用来可视化分布式或微服务中的调用情况
我们主要说明Metrics
中的监控能力,首先开启Promethus数据
- "--metrics.prometheus=true"
- "--metrics.prometheus.buckets=0.100000, 0.300000, 1.200000, 5.000000"
配置prometheus的监控任务
# 监控面板: 11462
- job_name: "Traefik"
static_configs:
- targets: ["192.168.1.178:18182"]
可观测到如下面板
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iePewpEG-1624432821951)(./1619509537326.png)]
六、其它问题
如何解决CORS跨域问题: https://doc.traefik.io/traefik/middlewares/headers/
如何使用HTTPS: https://doc.traefik.io/traefik/https/overview/
更多配置、更多用法请自行查询相关文档!