前
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 的配置中的 高级选项。
实践
使用这次的实践内容配置
- 开放traefik的 dashboard对内部提供访问
- 自定义我们的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 提供了更多的功能
- Weighted Round Robin
- Mirroring
后
Traefik 的功能强大不必言说,现在只是对其细小的工具进行一步步研究。