大家好,我是乔克。
提到Traefik,有些人可能并不熟悉,但是提到Nginx,应该都耳熟能详。
暂且我们把Traefik当成和Nginx差不多的一类软件,待读完整篇文章,你就会对Traefik有不一样的认识。
本文主要带大家对Traefik有一个全面的认识,我将从下面几个方面作介绍。
本文基于Traefik 2.5.3进行介绍。
什么是Traefik
Traefik是一个开源的边缘路由网关,它简单易用并且功能全面。官方【1】的介绍是:Traefik is an [open-source]
(https://github.com/traefik/traefik) _Edge Router_ that makes publishing your services a fun and easy experience.
Traefik原生支持多种集群,如Kubernetes、Docker、Docker Swarm、AWS、Mesos、Marathon等;并且可以同时处理许多集群。
Traefik的核心概念及能力
Traefik是一个边缘路由器,它会拦截外部的请求并根据逻辑规则选择不同的操作方式,这些规则决定着这些请求到底该如何处理。Traefik提供自动发现能力,会实时检测服务,并自动更新路由规则。
从上图可知,请求首先会连接到entrypoints
,然后分析这些请求是否与定义的rules
匹配,如果匹配,则会通过一系列middlewares
,再到对应的services
上。
这就涉及到以下几个重要的核心组件。
- Providers
- Entrypoints
- Routers
- Services
- Middlewares
Providers
Providers
是基础组件,Traefik的配置发现是通过它来实现的,它可以是协调器,容器引擎,云提供商或者键值存储。
Traefik
通过查询Providers
的API
来查询路由的相关信息,一旦检测到变化,就会动态的更新路由。
Entrypoints
Entrypoints
是Traefik
的网络入口,它定义接收请求的接口,以及是否监听TCP或者UDP。
Routers
Routers
主要用于分析请求,并负责将这些请求连接到对应的服务上去,在这个过程中,Routers还可以使用Middlewares来更新请求,比如在把请求发到服务之前添加一些Headers。
Services
Services
负责配置如何到达最终将处理传入请求的实际服务。
Middlewares
Middlewares
用来修改请求或者根据请求来做出一些判断(authentication, rate limiting, headers, ...),中间件被附件到路由上,是一种在请求发送到你的服务之前(或者在服务的响应发送到客户端之前)调整请求的一种方法。
部署Traefik
Traefik的部署方式有多种,这里主要采用Helm
方式进行部署管理。
Helm部署
环境:kubernetes: 1.22.3 helm: 3.7.1
1、添加traefik helm仓库
$ helm repo add traefik https://helm.traefik.io/traefik $ helm repo update
2、将traefik包下载到本地进行管理
$ helm search repo traefik NAME CHART VERSION APP VERSION DESCRIPTION traefik/traefik 10.6.0 2.5.3 A Traefik based Kubernetes ingress controller $ helm pull traefik/traefik
3、部署Traefik
默认的value.yaml
[2]配置文件配置比较多,可能需要花一定的时间去梳理,不过根据相关的注释还是可以很快的理解。
这里自定义一个配置文件my-value.yaml
,如下:
service: type: NodePort ingressRoute: dashboard: enabled: false ports: traefik: port: 9000 expose: true web: port: 8000 expose: true websecure: port: 8443 expose: true persistence: enabled: true name: data accessMode: ReadWriteOnce size: 5G storageClass: "openebs-hostpath" path: /data additionalArguments: - "--serversTransport.insecureSkipVerify=true" - "--api.insecure=true" - "--api.dashboard=true"
进行部署,命令如下:
$ kubectl create ns traefik-ingress $ helm install traefik -n traefik-ingress -f my-value.yaml .
这里不是使用的是默认的value.yaml
[2]配置文件。
然后可以看到部署结果,如下:
# kubectl get all -n traefik-ingress NAME READY STATUS RESTARTS AGE pod/traefik-77ff894bb5-qqszd 1/1 Running 0 6m26s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/traefik NodePort 10.108.170.22 <none> 9000:32271/TCP,80:31728/TCP,443:30358/TCP 6m26s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/traefik 1/1 1 1 6m26s NAME DESIRED CURRENT READY AGE replicaset.apps/traefik-77ff894bb5 1 1 1 6m26s
然后可以通过NodePort
访问Dashboard页面,如下:
使用Traefik
创建第一个路由规则
我们上面访问Dashboard是采用的NodePort
的方式,既然已经把Traefik
部署好了,为什么不使用路由网关的方式呢?
下面我们就来创建第一个路由网关来访问Dashboard
。
Traefik创建路由规则有多种方式,比如:
- 原生Ingress写法
- 使用CRD IngressRoute方式
- 使用GatewayAPI的方式
这里暂时介绍前面两种方式,关于GatewayAPI的方式在后续进行介绍。
原生Ingress路由规则
原生Ingress的路由规则,写法就比较简单,如下。
# cat traefik-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: traefik-dashboard-ingress annotations: kubernetes.io/ingress.class: traefik traefik.ingress.kubernetes.io/router.entrypoints: web spec: rules: - host: traefik-web.coolops.cn http: paths: - pathType: Prefix path: / backend: service: name: traefik port: number: 9000
创建路由规则,命令如下:
# kubectl apply -f traefik-ingress.yaml -n traefik-ingress ingress.networking.k8s.io/traefik-dashboard-ingress created
现在就可以通过域名http://traefik-web.coolops.cn:31728/dashboard/#/ 进行访问了(31728是80端口的映射端口),如下:
使用CRD方式配置路由规则
在早期版本,Traefik仅提供kubernetes ingress方式配置路由规则,社区认为采用开发一个自定义CRD的类型能够更好的提供Kubernetes的访问配置【3】。
IngressRoute
的配置方式也比较简单,如下:
# cat traefik-ingressRoute.yaml apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: traefik-dashboard-route spec: entryPoints: - web routes: - match: Host(`traefik-web2.coolops.cn`) kind: Rule services: - name: traefik port: 9000
部署命令如下:
# kubectl apply -f traefik-ingressRoute.yaml -n traefik-ingress ingressroute.traefik.containo.us/traefik-dashboard-route created
然后就可以通过http://traefik-web2.coolops.cn:31728/dashboard/#/ 进行访问了。
暴露HTTP服务
首先,部署一个简单的whoami
[4]应用,YAML文件如下:
--- apiVersion: v1 kind: Pod metadata: name: whoami labels: app: whoami spec: containers: - name: whoami image: traefik/whoami:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: whoami spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: whoami type: ClusterIP
部署成功后,创建一个路由规则,使外部可以访问。
# cat ingressroute.yaml apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: whoami-route spec: entryPoints: - web routes: - match: Host(`whoami.coolops.cn`) kind: Rule services: - name: whoami port: 80
创建过后,就可以进行访问了,如下:
暴露HTTPS服务
上面的whoami
应用,是通过HTTP
进行访问的,如果要通过HTTPS
进行访问,应该如何配置呢?
Traefik
支持HTTPS和TLS,对于证书可以选择自有证书,也可以使用Let's Encrypt【5】自动生成证书。这里会分别介绍这两种方式。
自有证书配置HTTPS
现在公司基本都会自己购买更安全的证书,那对于自有证书配置HTTPS就会使用更加频繁,这里主要介绍这种配置方式。
1、申请或者购买证书
我这里是在腾讯云申请的免费证书。
然后下载对应的证书,并上传到服务器上。
2、将证书文件保存为Secret
# kubectl create secret tls whoami-tls --cert=1_whoami.coolops.cn_bundle.crt --key=2_whoami.coolops.cn.key
3、创建IngressRoute对象,使其可以通过TLS访问
# cat ingressroutetls.yaml apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: whoami-route-tls spec: entryPoints: - websecure routes: - match: Host(`whoami.coolops.cn`) kind: Rule services: - name: whoami port: 80 tls: secretName: whoami-tls
创建完成后,就可以通过https://whoami.coolops.cn:30358/ 进行访问了(30358是443映射出来的端口)。