【完全揭秘】Traefik云原生网关——助力你的业务破万QPS

荔枝岛岛主
发布于 2023-10-7 11:07
浏览
0收藏

Traefik 是一款开源的反向代理和负载均衡软件,可以自动地为多个微服务实例进行负载均衡,并提供 HTTP/HTTPS/TCP/UDP 等协议支持。

Traefik 具有简单易用、自动发现服务、动态配置、可插拔的中间件等特点,被广泛应用于云原生和容器化场景中,介绍中也是表明自己是一个云原生网关。

Traefik 支持多种后端服务,包括 Kubernetes、Docker Swarm、Mesos、Consul、Etcd、Zookeeper、Redis 等,同时也提供了丰富的 API 和 Dashboard 等管理工具,使得用户能够方便地对反向代理和负载均衡进行配置和监控。

基本概念

Traefik 有 4 个基本概念,EntryPoints、Routers、Middlewares、Services。(官方图已经很清晰明了了,就不多画图了)

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

EntryPoints

网络入口点,配置端口、协议,包括 HTTP、HTTPS、TCP 和 UDP,每个入口点都有一个唯一标识符,并可以配置不同的访问规则和路由策略。

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

针对http、https 和 udp 不同的配置方式:

## Static configuration
entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"
  streaming:
    address: ":1704/udp"

Routers

路由,负责将传入的请求连接到可以处理它们的服务,在这个过程中,路由可以使用一些中间件来修改请求的一些信息。

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

配置​​/foo​​开始的请求路由到的后端服务。

## Dynamic configuration
http:
  routers:
    my-router:
      rule: "Path(`/foo`)"
      service: service-foo

路由可以配置不同的的规则,比如针对请求 host 和请求路径进行匹配。

rule = "Host(`example.com`) || (Host(`example.org`) && Path(`/traefik`))"

规则

描述

Headers(​​key​​​, ​​value​​)

请求头校验规则

HeadersRegexp(​​key​​​, ​​regexp​​)

请求头校验规则,value 正则匹配

Host(​​example.com​​, ...)

请求域名校验规则

HostRegexp(​​example.com​​​, ​​{subdomain:[a-z]+}.example.com​​, ...)

请求域名正则匹配规则

Method(​​GET​​, ...)

请求方法校验规则,支持GET\POST\PUT\DELETE\PATCH\HEAD

Path(​​/path​​​, ​​/articles/{cat:[a-z]+}/{id:[0-9]+}​​, ...)

请求路径匹配规则,精确匹配,支持正则

PathPrefix(​​/products/​​​, ​​/articles/{cat:[a-z]+}/{id:[0-9]+}​​)

请求路径前缀匹配规则,支持正则

Query(​​foo=bar​​​, ​​bar=baz​​)

请求参数匹配规则

ClientIP(​​10.0.0.0/16​​​, ​​::1​​)

请求 IP 匹配规则

Middlewares

中间件,用于对请求进行处理和转换,类似过滤器、拦截器,有些人可能把他理解成很多网关中的插件,但是其实在 Traefik 里面也有插件的概念,并且可以发布分享,可以参考 https://plugins.traefik.io/create。

Traefik 提供了多种内置的中间件,比如日志记录、重定向、身份验证和限流等第,此外,也可以根据需要自定义中间件。

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

配置方式:

# As a Docker Label
whoami:
  #  A container that exposes an API to show its IP address
  image: traefik/whoami
  labels:
    #  `foo-add-prefix` 中间件
    - "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo"
    - "traefik.http.routers.router1.middlewares=foo-add-prefix@docker"

列出一些 HTTP 中间件列表,其实很多一看名字基本就知道是干嘛用的,基本上基础的网关鉴权、熔断、限流都有默认的插件。

中间件

描述

AddPrefix

路径添前缀

BasicAuth

鉴权

Buffering

缓冲

Chain

中间件链,可以定义可重用的中间件组合

CircuitBreaker

熔断

Compress

压缩

Headers

请求头操作,可以添加、删除请求头

IPWhiteList

IP 白名单

RateLimit

限流

Retry

重试

Services

服务指的是 Traefik 服务,每个服务都有一个唯一标识符,并可以配置不同的负载均衡规则和健康检查策略。

需要注意的是这里的服务指的是 Traefik 自身的 service,并非是我们自己的服务。

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

配置示例:

## Dynamic configuration
http:
  services:
    my-service:
      loadBalancer:
        servers:
        - url: "http://<private-ip-server-1>:<private-port-server-1>/"
        - url: "http://<private-ip-server-2>:<private-port-server-2>/"

根据以上的概念,实际上在 Traefik 中一个请求的流程:

• 当客户端发送请求时,请求首先会被协议处理器接收并解析。

• 然后,请求会被路由器匹配到相应的路由规则,并根据规则将请求转发给相应的中间件链。

• 中间件链会按照顺序执行各个中间件,并根据需要对请求进行处理和转换。

• 处理完请求后,请求会被转发给相应的后端服务器。

• 后端服务器将处理完请求后的响应返回给 Traefik。

• 最后,Traefik 将响应返回给客户端。

负载均衡

Traefik 的负载均衡功能通过负载均衡器来实现,支持多种负载均衡策略,包括轮询、随机、加权轮询和加权随机等。

当 Traefik 接收到请求时,根据路由规则将请求转发给相应的后端服务器。如果后端服务器有多个,Traefik 就需要使用负载均衡算法来选择一个服务器处理请求。具体流程如下:

1. Traefik 会先根据配置的路由规则,将请求匹配到对应的前端入口点

2. 针对该入口点,Traefik 会获取所有与之关联的后端服务列表

3. 根据负载均衡策略,在可用的后端服务器中选择一个服务

4. 将请求转发给所选择的后端服务

5. 如果后端服务出现故障或者不可用,Traefik 会将其从服务器列表中移除,并选择另外一个可用的服务器来处理请求。

目前来说,官方支持轮询和加权轮询策略。

加权轮询

比如配置 v1 版本权重为3,v2版本权重为1,可用于灰度流量,配置方式如下。

## Dynamic configuration
http:
  services:
    app:
      weighted:
        services:
        - name: appv1
          weight: 3
        - name: appv2
          weight: 1

    appv1:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-1/"

    appv2:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-2/"

流量复制

另外还有一个比较特殊的是镜像请求,镜像能够将发送到一个服务的请求镜像到其他服务,或者我们叫做流量复制更好。

比如针对 appv1的请求,配置 percent 10,那么 10% 的流量就会被打到 appv2 服务上,配置方式如下:

## Dynamic configuration
http:
  services:
    mirrored-api:
      mirroring:
        service: appv1
        # maxBodySize is the maximum size allowed for the body of the request.
        # If the body is larger, the request is not mirrored.
        # Default value is -1, which means unlimited size.
        maxBodySize: 1024
        mirrors:
        - name: appv2
          percent: 10

    appv1:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-1/"

    appv2:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-2/"

健康检查&故障转移

Traefik 要做负载均衡同样是需要健康检查的机制,健康检查需要配置健康检查的路径、请求频率(默认30秒)、超时时间(默认5秒),但是 K8S 有自己的健康检查机制,会移除失效的 pod,所以这里的健康检查对 K8S CRD 和 K8SIngress 无效。

故障转移只是依赖健康检查做正常的负载均衡而已,配置方式如下:

## Dynamic configuration
http:
  services:
    app:
      failover:
        service: main
        fallback: backup

    main:
      loadBalancer:
        healthCheck:
          path: /status
          interval: 10s
          timeout: 3s
        servers:
        - url: "http://private-ip-server-1/"

    backup:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-2/"

部署

接下来通过 Docker 和 K8S 方式了解一下基本的使用。

Docker

首先下载镜:

docker run -d -p 8080:8080 -p 80:80 -v $PWD/traefik.yml:/etc/traefik/traefik.yml traefik:v2.10

创建配置文件:

version: '3'

services:
  whoami:
    # A container that exposes an API to show its IP address
    image: traefik/whoami
    labels:
      - "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)"
  reverse-proxy:
    # The official v2 Traefik docker image
    image: traefik:v2.10
    # Enables the web UI and tells Traefik to listen to docker
    command: --api.insecure=true --providers.docker
    ports:
      # The HTTP port
      - "80:80"
      # The Web UI (enabled by --api.insecure=true)
      - "8080:8080"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock

启动:

docker-compose up -d reverse-proxy
docker-compose up -d whoami

服务创建成功,自动服务发现 ​​whoami​​,并且存在规则,请求头带 Host 请求可以访问到 whoami 的服务。

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

测试请求​​http://localhost​​可以得到响应

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

同时,可以使用命令扩容:

docker-compose up -d --scale whoami=2

发现启动了两个 ​​whoami​​ 的实例

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

再次请求会发现响应的 IP 会发生变化 IP: 172.18.0.4或者 IP: 172.18.0.3,从后台也可以看到两个实例

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

K8S

Traefik 结合 K8S 首先需要 K8S 的环境,Mac 下直接使用 Docker Desktop 还是比较方便的。

Mac K8S 环境搭建

首先,下载 Docker Desktop,下载好之后是自带 K8S 的,我们只要在设置中开启即可。

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

开启之后需要等待一段时间,需要去拉取相关依赖的镜像,国内可能需要自己科学上网,OK 之后可以看到 K8S 已经启动成功。

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

到这里那其实已经就好了,顺便可以安装一下Kubernetes Dashboard,默认情况下不会部署控制台,使用命令部署:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

运行结果:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

namespace/kubernetes-dashboard created
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created

然后,使用 ​​kubectl​​ 命令行工具来启用 Dashboard 访问。

kubectl proxy

启动成功之后访问 http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ ,进入控制台页面,然后需要我们去配置 token,目前只能通过这种方式去访问。

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

按照官网文档:https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md,配置一个账户和集群角色,复制到一个文件就行,不需要做修改,保存文件为 ​​k8s-admin.yaml​

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard

使用命令创建服务:

kubectl create -f k8s-admin.yaml

执行命令,生成 token:

kubectl -n kubernetes-dashboard create token admin-user

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

然后填入 token,就可以正常访问 dashboard 了。

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

Traefik 部署

参考官方文档:https://doc.traefik.io/traefik/getting-started/quick-start-with-kubernetes/

Traefik 使用 Kubernetes API 来做服务发现,为了使用 Kubernetes API,Traefik 需要一些权限,首先是创建角色,创建 ClusterRole 角色:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: traefik-role

rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
      - networking.k8s.io
    resources:
      - ingresses
      - ingressclasses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
      - networking.k8s.io
    resources:
      - ingresses/status
    verbs:
      - update

然后创建用于 traefik 的账户:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-account

然后,在账户上绑定角色以应用权限和规则:

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: traefik-role-binding

roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-role
subjects:
  - kind: ServiceAccount
    name: traefik-account
    namespace: default 

这样角色和账户的配置已经完成了,接下来需要配置 Traefik 的服务信息和 Dashboard 控制台,其中 args 参数是 traefik 的启动静态配置参数。

kind: Deployment
apiVersion: apps/v1
metadata:
  name: traefik-deployment
  labels:
    app: traefik

spec:
  replicas: 1
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-account
      containers:
        - name: traefik
          image: traefik:v2.10
          args:
            - --api.insecure
            - --providers.kubernetesingress
          ports:
            - name: web
              containerPort: 80
            - name: dashboard
              containerPort: 8080

创建 Traefik 的服务资源:

apiVersion: v1
kind: Service
metadata:
  name: traefik-dashboard-service

spec:
  type: LoadBalancer
  ports:
    - port: 8080
      targetPort: dashboard
  selector:
    app: traefik
---
apiVersion: v1
kind: Service
metadata:
  name: traefik-web-service

spec:
  type: LoadBalancer
  ports:
    - targetPort: web
      port: 80
  selector:
    app: traefik

最终,我们可以根据这些配置统一到一个配置文件中,命名为​​k8s-traefik.yaml​​,然后使用命令创建:

kubectl apply -f k8s-traefik.yaml
clusterrole.rbac.authorization.k8s.io/traefik-role created
serviceaccount/traefik-account created
clusterrolebinding.rbac.authorization.k8s.io/traefik-role-binding created
deployment.apps/traefik-deployment created
service/traefik-dashboard-service created
service/traefik-web-service created

这时候,访问控制台​​http://localhost:8080/dashboard/#/​​,可以看到已经成功了。

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

现在服务部署成功,还需要部署一些后台服务来测试一下,使用官方提供的示例应用程序​traefik/whoami​

同样,新建一个文件命名为​​k8s-whoami.yaml​​,使用命令创建服务,这样服务就部署成功了。

kubectl apply -f k8s-whoami.yaml
deployment.apps/whoami created
service/whoami created
ingress.networking.k8s.io/whoami-ingress created

从后台可以看到服务启动成功:

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区

同时,可以访问​​http://localhost​​访问到服务:

【完全揭秘】Traefik云原生网关——助力你的业务破万QPS-鸿蒙开发者社区




文章转载自公众号:艾小仙

分类
标签
已于2023-10-7 11:07:09修改
收藏
回复
举报
回复
    相关推荐