Traefik路由规则及中间件配置
一、简介
什么是Traefik
Traefik 是一款开源的边缘路由器,可以作为整个平台的入口(网关),根据逻辑规则,处理并路由整个传入的请求。
当部署完后启动 Traefik 时,定义了入口点(端口号和对应的端口名称),然后 Kubernetes 集群外部就可以通过访问 Traefik 服务器地址和配置的入口点对 Traefik 服务进行访问,在访问时一般会带上 “域名” + “入口点端口”, Traefik 会根据域名和入口点端口在 Traefik 路由规则表中进行匹配,如果匹配成功,则将流量发送到 Kubernetes 内部应用中与外界进行交互。这里面的域名与入口点与对应后台服务关联的规则,即是 Traefik 路由规则。
核心概念
Entrypoint
作为外部访问入口,定义了接收请求的端口(HTTP或TCP),启动时进行配置,之后使用关键字
entrypoints
使用定义入口名
Providers
用来自动发现平台上的服务,可以是编排工具、容器引擎或者 key-value 存储等,比如 Docker、Kubernetes、File。
Router
分析请求(host,path,headers,SSL,…),负责将传入请求连接到可以处理这些请求的服务上去。
Services
将请求转发到后端应用(load balancing),负责配置如何获取最终将处理传入请求的实际服务。
Middlewares
是一个处于路由和后端服务之前的中间件,在外部流量进入Traefik且路由规则匹配成功后,将流量发送到对应的后端服务前,先发送给中间件进行一系列处理(类似过滤器链 Filter),例如添加 Header头信息、授权、流量转发、处理访问路径前缀、IP白名单等等,经过一个或多个中间件处理完成后,在发送给后端服务
二、配置Traefik路由规则
kubernetes上配置
在 Kubernetes 中 Traefik 支持 CRD 和 Ingress 两种方式进行路由规则配置
使用 Traefik CRD配置
基于 HTTP 路由规则
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-route
spec:
entryPoints:
- web # web为部署Traefik时指定的进入点,端口为80
routes:
- match: Host(`www.domain.com`)
kind: Rule
services:
- name: traefik
port: 8080
基于 HTTPS 路由规则
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: kubernetes-dashboard-route
spec:
entryPoints:
- websecure
tls:
secretName: my-tls
routes:
- match: Host(`tls.domain.com`)
kind: Rule
services:
- name: kubernetes-dashboard
port: 443
使用 Kubernetes Ingress 配置
基于 HTTP 路由规则
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-dashboard-ingress
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: web ##指定 Traefik 中进入点
spec:
rules:
- host: www.domain.com
http:
paths:
- path: /
pathTyep: Prefix
backend:
service:
name: traefik
port:
number: 8080
基于 HTTPS 路由规则
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kubernetes-dashboard-ingress
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.tls: "true" ##指定使用 tls 证书方式
traefik.ingress.kubernetes.io/router.entrypoints: websecure ##指定 Traefik 中进入点
spec:
tls:
- secretName: my-tls
rules:
- host: tls.domain.com
http:
paths:
- path: /
pathTyep: Prefix
backend:
service:
name: kubernetes-dashboard
port:
number: 443
三、配置中间件(Middlewares)
Traefik Middlewares 中间件被附件到路由上,是一种在请求发送到服务之前对该请求进行加工的操作,它支持:
- 重试、压缩、缓冲、断路器
- header 管理、错误页、中间件链
- 服务限流、同一主机并发请求限制
- 基本认证、IP 白名单、摘要认证、转发鉴权验证
- regex 请求重定向、scheme 请求重定向、请求 URL 替换、regex 请求 URL 替换、删除 URL 前缀、regex 删除 URL 前缀、添加 URL 前缀
1、去除请求路径前缀
例如,有一个路由规则中配置的域名路径为 “/api”,traefik 进行路由规则进行流量转发时,也会带上这个前缀作为相对路径发送到后端服务中,而对后端服务来说,一般都是以 “/” 根路径作为相对路径的,如果带上这个路径到后端服务中,那么后端服务则变成以 “/api” 作为相对路径,显然,这样会导致状态码 404 错误。所以,很多时候我们需要去掉这个前缀。
使用去除前缀中间件去除前缀,方便配置一个域名多个二级路径这种需求,中间件写法如下:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-stripprefix
spec:
stripPrefix:
prefixes: # 设置去除的 url 前缀
- /api
2、正则表达式匹配去除请求路径前缀
很多时候我们有这样一个需求,就是通过一个域名访问多个服务,这样易于统一服务的入口,而 traefik 中也提供了这种批量匹配去除前缀的功能,就是通过正则表达式方式批量匹配对应路径的前缀,然后去除,即 stripPrefixRegex 中间件。
使用正则表达式,只要正则表达式匹配成功就能将前缀去除,这样的好处就是可以多个路由规则使用该中间件进行去除前缀,方便配置通用的一个域名多个的二级路径这种需求,中间件写法如下:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-stripprefixregex
spec:
stripPrefixRegex:
regex:
- "/app1/[a-z0-9]+/[0-9]+/"
四、路由规则中使用 Traefik Middleware
使用正则表达式去除前缀中间件
CRD 方式
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test-route
namespace: test
spec:
entryPoints:
- web
routes:
- match: Host(`www.domain.com`) && PathPrefix(`/app1`)
kind: Rule
services:
- name: test-service
port: 80
middlewares:
- name: test-stripprefixregex ##指定使用的中间件
#- name: new-middle 使用多个写多行
Ingress 方式:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
namespace: test
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: web
##指定使用的 Middleware,规则是 {namespace名称}-{middleware名称}@{资源类型},如果使用多个中间件,则逗号隔开
traefik.ingress.kubernetes.io/router.middlewares: default-test-stripprefixregex@kubernetescrd
spec:
rules:
- host: my.domain.com
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: nginx-test
port:
number: 80