💕

文章封面来自殘夜 ZANYA-🌟

What is traefik?

引用官方的一句话:

Traefik is an open-source Edge Router that makes publishing your services a fun and easy experience. It receives requests on behalf of your system and finds out which components are responsible for handling them.

简单来说Traefik就是一个"路由器",一个"网关",将所有指定的请求分发到对应的后端服务中,与nginx相似

官方网站:https://doc.traefik.io/traefik/

本站也是使用traefik进行路由转发,下文主要根据笔者自己的实践来介绍traefik和treafik在kubernetes中的的相关使用,由于我的traefik是机器上kubernetes集群(K3S)默认安装的,这里具体就不介绍相关安装的方法,安装方案可以参考官网

What’s Happening to the Requests?

首先引用几张官方架构图,来介绍一下treafik的一些细节

Architecture

参考上图,traefik接收请求首先需要ENTRYPOINTS,通过"入口"接收所有的请求,entrypoints一般有两类,web(80)和websecure(443)分别对应http的所有请求和https的所有请求

在经过"入口"之后,请求会到ROUTERS阶段,这里主要就是执行用户定义一些路由规则,将符合用户定义的路由规则的请求最后转到到SERVICES中,这里SERVICE就是我们实际的提供服务的地址了

举个例子,当访问 http://blog.lkarrie.com (前提域名dns指向你的服务器)时,由于他是http经过80端口,所以它通过我们所定义的web entrypoints到routers,在router中存在规则,当请求host地址匹配 blog.lkarrie.com时,将请求转发至 1.2.3.4:1111,通过规则匹配,最终我们外部域名的请求会访问到我们实际后端提供服务的地址 1.2.3.4:1111(在kubernetes中,traefik配置时的service即对应kubernetes的service资源)

想了解官方对这部分的介绍可以参考:https://doc.traefik.io/traefik/routing/overview/

Overview

在ROUTER阶段,除了有规则匹配之外,还有MIDDLEWARE资源对请求进行一些自定义的处理,当我们有一些需求单纯进行路由匹配无法满足的时候,就会用到这个“filter”

使用到middleware的场景还是挺多的,本站就用,比如http跳转https,www跳转到非www(https://www.lkarrie.com跳转到 https://lkarrie.com )等等

所有middleware的类型都是trarfik为我们提供好的,例如http跳转到https的类型的middleware的类型被规定为属于 redirectscheme,处理 www跳转到无www域名的middleware属于 redirectregex

所有middleware的类型和功能列表如下:

Available HTTP Middlewares

Middleware Purpose Area
AddPrefix Adds a Path Prefix Path Modifier
BasicAuth Adds Basic Authentication Security, Authentication
Buffering Buffers the request/response Request Lifecycle
Chain Combines multiple pieces of middleware Misc
CircuitBreaker Prevents calling unhealthy services Request Lifecycle
Compress Compresses the response Content Modifier
ContentType Handles Content-Type auto-detection Misc
DigestAuth Adds Digest Authentication Security, Authentication
Errors Defines custom error pages Request Lifecycle
ForwardAuth Delegates Authentication Security, Authentication
Headers Adds / Updates headers Security
IPWhiteList Limits the allowed client IPs Security, Request lifecycle
InFlightReq Limits the number of simultaneous connections Security, Request lifecycle
PassTLSClientCert Adds Client Certificates in a Header Security
RateLimit Limits the call frequency Security, Request lifecycle
RedirectScheme Redirects based on scheme Request lifecycle
RedirectRegex Redirects based on regex Request lifecycle
ReplacePath Changes the path of the request Path Modifier
ReplacePathRegex Changes the path of the request Path Modifier
Retry Automatically retries in case of error Request lifecycle
StripPrefix Changes the path of the request Path Modifier
StripPrefixRegex Changes the path of the request Path Modifier

Available TCP Middlewares

Middleware Purpose Area
InFlightConn Limits the number of simultaneous connections. Security, Request lifecycle
IPWhiteList Limit the allowed client IPs. Security, Request lifecycle

在K3s、Rancher中使用Treafik的正确姿势

下面就主要就是本站相关的traefik使用,由于我是服务器使用的是K3S,treafik作为了默认的ingress解决方案这里就不做安装的介绍了、除此以外Rancher 自然也少不了,Rancher中的均衡负载功能其实就是创建traefik的相关路由、但我个人并不推荐从页面上直接创建均衡负载、因为页面上创建均衡负载没有办法对路由条件进行 add 或者 or的并列运算、或者添加创建middleware对路由进行自定义的调整(官方的介绍可以在页面上通过注解标签的形式做到灵活配置,可惜在我测试过程中并不能生效),所以这里还是推荐直接通过yaml的形式直接创建相关资源

首先暴露traefik web端口,通过暴露dashboard查看我们的traefik资源情况

访问地址:http://ip:nodeport/dashboard/#/

image-20220301231508153

image-20220301231907844

下面就是编写yaml的过程了,这里拿本站相关的yaml配置举例

HTTP

web-blog.yaml

创建名为blog的IngressRoute,entryPoints指定为http请求对应80端口的 web entryPoint,

路由配置规则为 满足 blog.lkarrie.com 或 www.blog.lkarrie.com 的host地址

匹配相关规则后,请求转发到名为myblog的service资源,端口指定为1111(由于我的后台服务并不是直接使用工作负载跑在的集群中,而是在集群外部使用docker运行的,所以这里创建外部IP和端口的service连接到blog服务)

最后指定了链路中需要使用的两个middleware分别名为redirect-https-middleware、blog-redirectregex

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: blog
spec:
  entryPoints:
  - web
  routes:
  - match: Host(`blog.lkarrie.com`) || Host(`www.blog.lkarrie.com`)
    kind: Rule
    services:
      - name: myblog
        port: 1111
    middlewares:
    - name: redirect-https-middleware
    - name: blog-redirectregex

image-20220301233837990

redirect-https-middleware.yaml

通过这个中间件强制使http的请求跳转为https

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: redirect-https-middleware
spec:
  redirectScheme:
    scheme: https
    permanent: true

http-blog-redirectregex.yaml

通过这个中间件修改http带有www的请求地址,跳转到http非www的地址中

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: blog-redirectregex
spec:
  redirectRegex:
    regex: ^http://www.blog.lkarrie.com/(.*)
    replacement: http://blog.lkarrie.com/${1}

HTTPS

websecure-blog.yaml

创建名为httpsblog的IngressRoute,entryPoints指定为https请求对应443端口的 websecure entryPoint,

路由配置规则为 满足 blog.lkarrie.com 的host地址

匹配相关规则后,请求转发到名为myblog的service资源,端口指定为1111

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: httpsblog
  namespace: default
spec:
  entryPoints:
  - websecure
  routes:
  - match: Host(`blog.lkarrie.com`)
    kind: Rule
    services:
      - name: myblog
        port: 1111
  tls:
    secretName: blog

websecure-wwwblog.yaml

创建名为httpswwwblog的IngressRoute,entryPoints指定为https请求对应443端口的 websecure entryPoint,

路由配置规则为 满足 www.blog.lkarrie.com 的host地址

匹配相关规则后,请求转发到名为myblog的service资源,端口指定为1111

指定了链路中需要使用的名为https-blog-redirectregex的middleware

最后指定了https访问需要的证书(这里证书就是密文属于K8S的资源,可以在系统中添加后直接被引用,注意有命名空间的要求,证书需要在所属的命名空间下

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: httpswwwblog
  namespace: default
spec:
  entryPoints:
  - websecure
  routes:
  - match: Host(`www.blog.lkarrie.com`)
    kind: Rule
    services:
      - name: myblog
        port: 1111
    middlewares: 
    - name: https-blog-redirectregex
  tls:
    secretName: wwwblog

如果你是 泛域名SSL证书 就没必要像我一样 由于我是单域名证书(免费的)所以需要逐个上传

image-20220301234225463

https-blog-redirectregex.yaml

通过这个中间件修改https请求带有www的请求地址,跳转到https非www的地址中

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: https-blog-redirectregex
spec:
  redirectRegex:
    regex: ^https://www.blog.lkarrie.com/(.*)
    replacement: https://blog.lkarrie.com/${1}
    permanent: true

至此一个完成的域名转发配置基本实现了

创建完之后可以在你的trarfik dashboard中查看你创建的资源(由于我还创建了一些别的网站转发规则,比如根域名和图床的地址转发,所以截图中比较多,创建的方法类似于上述的yaml就不再详细贴上相关yaml了)

用起来之后确实感觉比ng方便许多,真不戳 :D

image-20220301234859474

image-20220301234937493

image-20220301235001195