Traefik--云原生下的Nginx替代品

7,734 阅读4分钟

不可否认,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"]

可观测到如下面板

image.png

六、其它问题

如何解决CORS跨域问题: doc.traefik.io/traefik/mid… 如何使用HTTPS: doc.traefik.io/traefik/htt…

更多配置、更多用法请自行查询相关文档!