[Workshops] Traefik之ingressroute与middleware

Traefik 不仅仅是作为ingress 这么简单,它在实现了标准的 Ingress API 的同时。所带来CRD才是最重要的功能。

我们通过 kubectl api-resources 可以看到当前的API资源,其中可以看到 Traefik 提供的有:

ingressroutes                                             traefik.containo.us/v1alpha1           true         IngressRoute
ingressroutetcps                                          traefik.containo.us/v1alpha1           true         IngressRouteTCP
ingressrouteudps                                          traefik.containo.us/v1alpha1           true         IngressRouteUDP
middlewares                                               traefik.containo.us/v1alpha1           true         Middleware
middlewaretcps                                            traefik.containo.us/v1alpha1           true         MiddlewareTCP
serverstransports                                         traefik.containo.us/v1alpha1           true         ServersTransport
tlsoptions                                                traefik.containo.us/v1alpha1           true         TLSOption
tlsstores                                                 traefik.containo.us/v1alpha1           true         TLSStore
traefikservices                                           traefik.containo.us/v1alpha1           true         TraefikService

所以这里我们使用Traefik 提供的CRD来实现对于ingress 的高级应用。

概念

这里选取这次要使用的 CRD来进行简单的讲解

ingressroutes

IngressRoute 和 k8s 本身的 ingress 对比,给我们提供了更强大的功能,这里把配置文件贴出来就可以直接的看到区别。简单的理解一个是进一步控制 Traefik 的功能,一个是单纯的配置 ingress 的转发。CRD多了更多的选项 :

  • middlewares
  • entryPoints
  • TraefikService
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  namespace: kube-system
  name: user-traefik-dashboard
spec:
  entryPoints:
    - web
  routes:
    - kind: Rule
      match: Host(`traefik-ui2.k3.net`)
      services:
        - kind: TraefikService
          name: api@internal
      middlewares:
        - name: basic-auth
          namespace: kube-system
------
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: registry-ingress-k8s-gcr
  namespace: container-basis
  annotations:
    kubernetes.io/ingress.class: "traefik"
spec:
  rules:
  - host: k8s-gcr-k3s.io
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service: 
            name: k8s-gcr-registry-svc
            port:
              number: 5000

middlewares

这里指的是 HTTP层面的 中间件,用于实现用户对HTTP流量自定义操作,可以提供的操作包括不限于,压缩,熔断,认证,头部处理,缓存等等。

对比经典的 Nginx 这一层相当于用CRD 的模式实现了nginx 的配置中的 高级选项。

Overview

实践

使用这次的实践内容配置

  1. 开放traefik的 dashboard对内部提供访问
  2. 自定义我们的echoserver服务,添加自定义用户头等等。

开放dashboard并添加baseauth

创建IngressRoute资源

我们可以在 Traefik-IngressRoute 查询到 CRD 的模板。修改模板完成 资源的定义。在这里加上了 middlewares,用于登陆面板的认证。

这里的 services 就不是系统层面的了。 traefik 在这里做了区分。分为下面两种

  • TraefikService
  • Service

前者是 tfk提供的CRD,后者是经典的系统 Service。需要指定,name /namespace/port等否则会有error

traefik 的Error debug 可以 在 deploy 的Log 中查看

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  namespace: kube-system
  name: user-traefik-dashboard
spec:
  entryPoints:
    - web
  routes:
    - kind: Rule
      match: Host(`traefik-ui2.k3.net`)
      services:
        - kind: TraefikService
          name: api@internal
      middlewares:
        - name: basic-auth
          namespace: kube-system

使用 ingress 来实现

这个是补充部分,我们可以使用 CRD来使用 中间件,也可以直接在 ingress 中通过annotations,来实现对与 其他资源的引用。这样也可以实现中间件的功能。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: traefik-ingress
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: traefik
    traefik.ingress.kubernetes.io/router.middlewares: default-my-basic-auth@kubernetescrd
spec:
  rules:
    - host: traefik.${DOMAIN}
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: traefik-dashboard
                port:
                  number: 9000

创建basic-auth 中间件

Basic-auth 是web中比较常见的功能,traefik中也提供了可以直接使用的。通过下面的内容完成CRD 的定义。

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: basic-auth
  namespace: kube-system
spec:
  basicAuth:
    secret: basic-auth-traefik-dashboard

因为认证需要的密钥我们通过新的 secret 来进行创建,这里的 users 格式是,htpasswd 的通用格式。

apiVersion: v1
kind: Secret
metadata:
  name: basic-auth-traefik-dashboard
  namespace: kube-system
type: Opaque
data:
  users: YWRtaW46JGFwcjEkb255d2lQbmokVmpWUEdIczNKNzgwNHFIaEp1LkRSLwo=

通过上述步骤,既就可以创建一个 traefik-ui2.k3.net 的host指向 traefik 的dashboard,并且加上了 basicauth 的认证。

转发到echo并且添加header

这里使用 Header 的中间价来实现,文档见下

内容大同小异,直接全部贴出来。

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  namespace: default
  name: echo-ingress
spec:
  entryPoints:
    - web
  routes:
    - kind: Rule
      match: Host(`traefik-ui3.k3.net`)
      services:
        - kind: Service
          name: echo-test
          namespace: default
          port: 80
      middlewares:
        - name: basic-auth
          namespace: kube-system
        - name: echo-header
          namespace: default
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: echo-header
  namespace: default
spec:
  headers:
    customRequestHeaders:
      X-Script-Name: "test"
    customResponseHeaders:
      X-Custom-Response-Header: "value"

访问 traefik-ui3.k3.net 时候,我们可以看到,我们的加上的 request header 已经成功添加。

Hostname: echo-85799bbb44-zr9l8

Pod Information:
    -no pod information available-

Server values:
    server_version=nginx: 1.13.3 - lua: 10008

Request Information:
    client_address=10.42.1.119
    method=GET
    real path=/
    query=
    request_version=1.1
    request_scheme=http
    request_uri=http://traefik-ui3.k3.net:8080/

Request Headers:
    accept=text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
    accept-encoding=gzip, deflate
    accept-language=zh,zh-CN;q=0.9
    authorization=Basic YWRtaW46YWRtaW4=
    cache-control=max-age=0
    dnt=1
    host=traefik-ui3.k3.net
    upgrade-insecure-requests=1
    user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
    x-forwarded-for=10.42.0.0
    x-forwarded-host=traefik-ui3.k3.net
    x-forwarded-port=80
    x-forwarded-proto=http
    x-forwarded-server=traefik-7896558d9c-w9k4t
    x-real-ip=10.42.0.0
    x-script-name=test

Request Body:
    -no body in request-

其他

关于traefik 将流量转发到 NS 之外的 svc

traefik helm 安装时,默认没有启用 allowCrossNamespace,所以直接使用上面的配置会导致报错Error。

参考:K3s Traefik MiddleWare 报错-Failed to create middleware keys

想要添加 helm的ValueConfig,在 /var/lib/rancher/k3s/server/manifests/traefik-config.yaml

apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: traefik
  namespace: kube-system
spec:
  valuesContent: |-
    globalArguments:
    - "--providers.kubernetescrd.allowcrossnamespace=true"

这样可以在 其启动参数上加上 跨NS 支持。

TraefikService与Service

Tfk的Service 提供了更多的功能

  1. Weighted Round Robin
  2. Mirroring

Traefik 的功能强大不必言说,现在只是对其细小的工具进行一步步研究。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注