云原生之API网关Traefik

1. 前言

        说到web服务的开源网关,我首先想到的是Nginx,最早使用的就是它,现在都还在使用它。系统上线了Docker Swarm集群之后,不继续使用Nginx直接做Docker服务的网关,是因为Nginx毕竟比Docker Swarm出现的早,其集成度还是不高。

        我们经过技术调研对比后,选择了Traefik作为微服务API网关,也是因为Traefik和Docker集成比较好,通过在各个应用程序的docker-compose.yml里设置labels,把Traefik声明清楚,服务能够被Traefik自动接管,用不着我们在nginx.conf里那样手工进行配置,这大大简化了我们的配置工作。   

        当然nginx ingress controller和k8s的搭配,我并没有亲自搭建过,虽然有几台AI服务器是采用这样的部署方式,都是厂家预安装好的。

2. 简介            

        Traefik是一个高性能、易用的API网关,支持多种后端服务,如Docker、Kubernetes等,它采用Go语言开发。

        Traefik官网文档地址是:Traefik Proxy Documentation - Traefik

        Traefik基于EntryPoints入口点、Routers路由器、Middlewares 中间件和Services服务的概念。它主要功能包括动态配置、自动服务发现以及对多个后端和协议的支持。

  1. EntryPoints: EntryPoints对Traefit是一个网络入口点,它定义了接收数据包的端口port, 包括TCP和UDP。

  2. Routers: 路由器负责将传入的请求连接到可以处理这些请求的服务。

  3. Middlewares: 中间件附着于路由器上,它能够修改经过路由器的请求包和应答包。

  4. Services: 服务组件负责配置请求怎样达到实际的后端服务。

 

 

3. 安装

        各种安装方法说明参见官网:Traefik Installation Documentation - Traefik, 这里仅仅贴一下Docker Swarm集群里的安装方式,主要是docker-compose.yml编排:

version: "3.2"

services:
  gateway:
    image: traefik:v2.3.2
    command:
      - "--log.level=INFO"
      - "--api=true"
      - "--api.dashboard=true"
      - "--api.insecure=true"
      # 启用swarm模式支持
      - "--providers.docker.swarmMode=true"
      # 默认不公开容器
      - "--providers.docker.exposedbydefault=false"
      # 为traefik-net网络启用代理
      - "--providers.docker.network=gateway"
      # 开发环境:创建名为`web-dev`的入口点,并为其暴露于80端口。该入口点会指示其它容器在哪个端口公开
      - "--entrypoints.web-dev.address=:80"
      # 测试环境:创建名为`web-test`的入口点,并为其暴露于81端口。该入口点会指示其它容器在哪个端口公开      
      - "--entrypoints.web-test.address=:81"
      # 预发布环境:创建名为`web-staging`的入口点,并为其暴露于82端口。该入口点会指示其它容器在哪个端口公开
      - "--entrypoints.web-stagin.address=:82"      
    ports:
      - 2080:80
      - 2081:81
      - 2082:82
      - 1080:8080
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - gateway
    deploy:
      placement:
        constraints:
          - node.labels.traefik == true

networks:
  gateway:
    external: true

        安装的操作不外乎在docker-compose.yml所在目录执行:

docker-compose up -d 

docker ps | grep traefik

docker service ls | grep traefik

        如果安装成功,则管理web地址是:http://127.0.0.1:1080/dashboard/#/,肯定不是127.0.0.1,换上实际IP地址即可。

4. EntryPoints 

        

        上图说明了EntryPoints可以支持多个端口,它向外部网络提供服务访问的入口点,架构上和功能细节上不用去细分析,那么配置上体现在哪里,我们怎么配置多个EntryPoint。

      - "--entrypoints.web-dev.address=:80"
      # 测试环境:创建名为`web-test`的入口点,并为其暴露于81端口。该入口点会指示其它容器在哪个端口公开      
      - "--entrypoints.web-test.address=:81"
      # 预发布环境:创建名为`web-staging`的入口点,并为其暴露于82端口。该入口点会指示其它容器在哪个端口公开
      - "--entrypoints.web-stagin.address=:82"      
    ports:
      - 2080:80
      - 2081:81
      - 2082:82

        就是上面这几行,我们有3个环境,那可以配置3个EntryPoint,Traefik也是一个docker服务,也是以容器运行,所以它的内部端口是80,81,82,暴露给外部的是2080,2081,2082, 我们想怎么做端口规划就怎么配置。 

 

         我们的3个EntryPoint配置应该在traefik dashboard界面上看得见,上图我的实际配置稍有不同而涂抹掉了,方法是一样的。

5. Routers

      

        路由器在EntryPoint和Service之间,自然是路由分发的作用, 同理,我们不要去纠结它的架构和功能细节,主要在使用上怎么配置让路由正确生效。

        这里不需要在Traefik的docker-compose.yml里配置,而是在各个Docker Swarm上部署的应用程序docker-compose.yml里配置,Traefik会自动扫描发现并让路由配置生效,这个方式非常好,也是一种自动注册与发现。例如我在用户中心管理系统的docker-compose.yml里这样配置:

      labels:
        - "traefik.enable=true"
        # 路由规则
        - "traefik.http.routers.usercenter-${SCOPE}.rule=PathPrefix(`/uc`)"
        # 中间件引用
        - "traefik.http.routers.usercenter-${SCOPE}.middlewares=auth-${SCOPE}"
        # 入口点
        - "traefik.http.routers.usercenter-${SCOPE}.entrypoints=web-${SCOPE}"
        # 服务负载均衡
        - "traefik.http.services.usercenter-${SCOPE}.loadbalancer.server.port=80"
        # 中间件定义:委派认证中间件(此处定义,其他服务直接引用,不能重复定义)
        - "traefik.http.middlewares.auth-${SCOPE}.forwardauth.address=http://usercenter-${SCOPE}_authservice/auth/"
        - "traefik.http.middlewares.auth-${SCOPE}.forwardauth.authResponseHeaders=user_id,user_name"
        - "traefik.http.middlewares.auth-${SCOPE}.forwardauth.trustForwardHeader=true"

        Routers和其它三个模块都有交互,处在中心位置,所以它的配置涉及了入口点EntryPoint、路由规则rule、中间件Middlewares和服务services负载均衡的配置,每个应用程序服务配置只需前面5行,下面的中间件定义,下面再讲。 

        我们在traefik dashboard上可以看到路由器的生效配置:

 

6. Middlewares 

        

        Middleware中间件附着于路由器上,它能够修改经过路由器的请求包和应答包,而且可以配置很多个。有两类中间件:HTTP和TCP,官网文档:Traefik Proxy Middleware Overview - Traefik

         

 

 

        例如,我利用ForwardAuth中间件来做认证鉴权,上面docker-compose.yml的中间件定义就是如此:

        # 中间件定义:委派认证中间件(此处定义,其他服务直接引用,不能重复定义)
        - "traefik.http.middlewares.auth-${SCOPE}.forwardauth.address=http://usercenter-${SCOPE}_authservice/auth/"
        - "traefik.http.middlewares.auth-${SCOPE}.forwardauth.authResponseHeaders=user_id,user_name"
        - "traefik.http.middlewares.auth-${SCOPE}.forwardauth.trustForwardHeader=true"

        中间件定义只要在用户认证中心的系统里定义一次就可以了,具体你在哪个服务里定义随你的便,但是要符合架构定义。

        在其它业务系统里如果需要进行用户认证鉴权,就在docker-compose.yml加入一行引用即可。例如:

# 中间件引用
        - "traefik.http.routers.usercenter-${SCOPE}.middlewares=auth-${SCOPE}"

        也就是我的usercentor服务引用了auth中间件,外部进来的HTTP请求会被Router先发往http://usercenter-${SCOPE}_authservice/auth/,

        auth组件返回200才前传给后面的service组件,不然就会返回认证失败,如401、403错误码。  

        我们在traefik dashboard上可以看到中间件的生效配置:

        

 7. Services

         

         这里的服务是Traefik的服务组件,负责把请求分发到后端实际的服务组件去,同时做好负载均衡,具体参见官方文档:Traefik Services Documentation - Traefik

        # 容器内的入口点,treafik无法获知你的服务的访问入口点,所以你必须以此告诉Traefik
        # Traefik同时会在此对横向拓展的容器建立负载均衡
        # 更多见https://docs.traefik.io/routing/services/
        - "traefik.http.services.demo-service-${SCOPE}.loadbalancer.server.port=80"

        同样,在traefik dashboard界面上可以看到服务的配置:

8. 云原生部署架构

        Traefik的功能细节有很多,具体不再累述,那么云原生知识点讲的网关这里,基本的环境部署技术点也算出来了,对一个小型云原生应用系统基本可以运作了。例如我们可能有这样一个部署架构:

        我们的系统已经容器化、集群化、支持服务编排、具有服务注册和发现机制、具有负载均衡能力、对外提供API网关能力,使用的技术也比较简单,小团队都可以hold得住。

9. 总结

        Traefik是一个采用Go语言开发的高性能、易用的微服务API网关,支持多种后端服务,如Docker、Kubernetes等,它有4个主要组件EntryPoints、Routers、Middlewares和Services, 提供路由、服务发现、负载均衡和大量好用的中间件功能。

        

 

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>