Traefik 企业实战:中间件(Middleware)篇

简介

Traefik Middlewares 是一个处于路由和后端服务之前的中间件,在外部流量进入 Traefik,且路由规则匹配成功后,将流量发送到对应的后端服务前,先将其发给中间件进行一系列处理(类似于过滤器链 Filter,进行一系列处理),例如,添加 Header 头信息、鉴权、流量转发、处理访问路径前缀、IP 白名单等等,经过一个或者多个中间件处理完成后,再发送给后端服务,这个就是中间件的作用。Traefik内置了很多不同功能的Middleware,主要是针对HTTP和TCP,这里挑选几个比较常用的进行演示。

重定向-redirectScheme

定义ingressroute,包含一个自动将 http 跳转到 https 的中间件 接上篇环境,存在于两个ingressroute,一个http,一个https

代码语言:javascript
复制
[root@localhost ~]# kubectl get ingressroute
NAME                     AGE
ingressroute-app         73m
ingressroute-app-https   64m

我们来创建重定向的Middleware ingressroute-redirect-https-middleware.yaml:

代码语言:javascript
复制
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: redirect-https-middleware
spec:
  redirectScheme:
    scheme: https   # 自动跳转到 https

查看部署情况

代码语言:javascript
复制
[root@localhost ~]# kubectl apply -f  ingressroute-redirect-https-middleware.yaml
middleware.traefik.containo.us/redirect-https-middleware created

[root@localhost ~]# kubectl get middleware
NAME AGE
redirect-https-middleware 23s

使用中间件,修改ingressroute-app.yaml

代码语言:javascript
复制
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroute-app
spec:
entryPoints:

  • web
    routes:
  • match: Host(ingressroute.kubesre.lc) # 域名
    kind: Rule
    services:
    • name: ingressroute-app # 与svc的name一致
      port: 80 # 与svc的port name一致
      middlewares:
    • name: redirect-https-middleware # 指定使用中间件,完成http强制跳转至https

部署

代码语言:javascript
复制
[root@localhost ~]# kubectl apply -f  ingressroute-app.yaml
deployment.apps/ingressroute-app unchanged
service/ingressroute-app unchanged
ingressroute.traefik.containo.us/ingressroute-app configured

访问测试 http://ingressroute.kubesre.lc/ ,可以看到,当访问http协议站点的时候,自动302跳转到了https

白名单-IPWhiteList

为提高安全性,通常情况下一些管理员界面会设置 ip 访问白名单,只希望个别用户可以访问。创建Middleware ingressroute-ip-white-list-middleware.yaml:

代码语言:javascript
复制
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: ip-white-list-middleware
spec:
ipWhiteList:
sourceRange:
  • 127.0.0.1/32
  • 查看部署情况

    代码语言:javascript
    复制
    [root@localhost ~]# kubectl apply -f  ingressroute-ip-white-list-middleware.yaml
    middleware.traefik.containo.us/ip-white-list-middleware created

    [root@localhost ~]# kubectl get middleware
    NAME AGE
    ip-white-list-middleware 12s
    redirect-https-middleware 7m27s

    修改ingressroute-app.yaml 使用白名单的中间件

    代码语言:javascript
    复制
    apiVersion: traefik.containo.us/v1alpha1
    kind: IngressRoute
    metadata:
    name: ingressroute-app
    spec:
    entryPoints:

    • web
      routes:
    • match: Host(ingressroute.kubesre.lc) # 域名
      kind: Rule
      services:
      • name: ingressroute-app # 与svc的name一致
        port: 80 # 与svc的port name一致
        middlewares:
      • name: ip-white-list-middleware # 指定使用白名单的中间件

    部署

    代码语言:javascript
    复制
    [root@localhost ~]# kubectl apply -f  ingressroute-app.yaml
    deployment.apps/ingressroute-app unchanged
    service/ingressroute-app unchanged
    ingressroute.traefik.containo.us/ingressroute-app configured

    测试

    代码语言:javascript
    复制
    [root@localhost ~]# curl -I  http://ingressroute.kubesre.lc
    HTTP/1.1 403 Forbidden
    Date: Wed, 23 Aug 2023 00:35:25 GMT
    Content-Length: 9
    Content-Type: text/plain; charset=utf-8

    修改白名单内IP地址:

    代码语言:javascript
    复制
    apiVersion: traefik.containo.us/v1alpha1
    kind: Middleware
    metadata:
    name: ip-white-list-middleware
    spec:
    ipWhiteList:
    sourceRange:
  • 172.16.0.0/16
  • 192.168.0.0/16
  • 172.168.0.0/16
  • 10.0.0.0/8
  • 部署后再次测试

    代码语言:javascript
    复制
    [root@localhost ~]# curl http://ingressroute.kubesre.lc/ -i
    HTTP/1.1 200 OK
    Accept-Ranges: bytes
    Content-Length: 23
    Content-Type: text/html
    Date: Wed, 23 Aug 2023 01:34:08 GMT
    Etag: "64e46cbf-17"
    Last-Modified: Tue, 22 Aug 2023 08:07:27 GMT
    Server: nginx/1.25.2

    Hello ingressroute app

    用户认证-basicAuth

    通常企业安全要求规范除了要对管理员页面限制访问ip外,还需要添加账号密码认证,而 traefik 默认没有提供账号密码认证功能,此时就可以通过BasicAuth 中间件完成用户认证,只有认证通过的授权用户才可以访问页面。安装 htpasswd 工具生成密码文件

    代码语言:javascript
    复制
    [root@localhost ~]# yum install -y httpd
    [root@localhost ~]# htpasswd -bc basic-auth-secret admin admin
    Adding password for user admin
    [root@localhost ~]# kubectl create secret generic basic-auth-secret --from-file=basic-auth-secret
    secret/basic-auth-secret created

    创建Middleware ingressroute-basic-auth-middleware.yaml:

    代码语言:javascript
    复制
    apiVersion: traefik.containo.us/v1alpha1
    kind: Middleware
    metadata:
    name: basic-auth-middleware
    spec:
    basicAuth:
    secret: basic-auth-secret

    查看部署情况

    代码语言:javascript
    复制
    [root@localhost traefik]# kubectl apply -f  ingressroute-basic-auth-middleware.yaml
    middleware.traefik.containo.us/basic-auth-middleware created

    [root@localhost traefik]# kubectl get middleware
    NAME AGE
    basic-auth-middleware 20s

    修改ingressroute-app.yaml 使用白名单的中间件

    代码语言:javascript
    复制
    apiVersion: traefik.containo.us/v1alpha1
    kind: IngressRoute
    metadata:
    name: ingressroute-app
    spec:
    entryPoints:

    • web
      routes:
    • match: Host(ingressroute.kubesre.lc) # 域名
      kind: Rule
      services:
      • name: ingressroute-app # 与svc的name一致
        port: 80 # 与svc的port name一致
        middlewares:
      • name: basic-auth-middleware # 指定使用认证的中间件

    部署

    代码语言:javascript
    复制
    [root@localhost ~]# kubectl apply -f  ingressroute-app.yaml
    deployment.apps/ingressroute-app unchanged
    service/ingressroute-app unchanged
    ingressroute.traefik.containo.us/ingressroute-app configured

    测试

    image.png

    输入admin/admin后访问成功

    image.png

    更多中间件

    更多中间件请参考官网:https://doc.traefik.io/traefik/middlewares/overview/

    • 去除请求路径前缀
    • 修改请求/响应头信息
    • 限流
    • 熔断
    • 自定义错误页
    • 数据压缩
    • ...