traefik
支持多种匹配器,
本次来探究一下traefik
中route
部分的匹配器
如下
测试环境
准备kubernetes
集群
部署好traefik
准备2个后端服务以及对应的svc
环境准备可参考前一个traefik
系列文档,链接如下
高级用法
基于Host
的匹配
ingressroute
的yaml
文件如下
[root@a file-yaml]$ cat busybox-ingressroute-host.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: busybox-httpd-ingressroute
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host("httpd-v1.a.b", "test.a.b")
### Host匹配器支持多个域名同时匹配
kind: Rule
services:
- name: busybox-httpd-v1
port: 80
- match: HostRegexp("v2.a.b", "{subdomain:[xyz]}.a.b")
### HostRegexp匹配器同样支持多个域名匹配,但是更加强大,同时支持正则表达式域名的匹配
kind: Rule
services:
- name: busybox-httpd-v2
port: 80
增加/etc/hosts/
文件中域名解析
[root@a file-yaml]$ cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost6 localhost6.localdomain6 localhost6.localdomain
192.168.1.8 httpd-v1.a.b
192.168.1.8 v2.a.b
192.168.1.8 test.a.b
192.168.1.8 x.a.b
192.168.1.8 y.a.b
192.168.1.8 z.a.b
使用kubectl apply -f busybox-ingressroute-host.yaml
创建后,
使用curl
访问后端服务
如下
可以看到基于不同的域名,可访问到不同的后端
基于Headers
的匹配
ingressroute
的yaml
文件如下
[root@a file-yaml]$ cat busybox-ingressroute-headers.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: busybox-httpd-ingressroute
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host("httpd.a.b") && PathPrefix("/") && Headers("version", "v1")
kind: Rule
services:
- name: busybox-httpd-v1
port: 80
- match: Host("httpd.a.b") && PathPrefix("/") && Headers("version", "v2")
kind: Rule
services:
- name: busybox-httpd-v2
port: 80
注意go
中使用的双引号包裹字符串,而不是单引号
使用kubectl apply -f busybox-ingressroute-headers.yaml
创建后,
使用curl -H "Version: v1" -v http://httpd.a.b/30080
访问后端服务
其中-H
为添加访问时的Headers
如下
可以看到使用不同的Headers
时,访问了不同的后端服务
基于Method
的匹配
ingressroute
的yaml
文件如下
[root@a file-yaml]$ cat busybox-ingressroute-method.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: busybox-httpd-ingressroute
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host("httpd.a.b") && Method("GET")
kind: Rule
services:
- name: busybox-httpd-v1
port: 80
- match: Host("httpd.a.b")
kind: Rule
services:
- name: busybox-httpd-v2
port: 80
由于后端服务使用的是busybox
中的httpd
,其中仅仅只有1个index.html
,没有设置其他的接口,因此PUT
,DELETE
,POST
,PATCH
均无法完成,提示501 Not Implemented
,仅仅只能测试GET
的方法
使用kubectl apply -f busybox-ingressroute-method.yaml
创建后,
使用curl -X GET http://httpd.a.b:20080/
访问,
如下
显示访问到busybox-httpd-v1
的服务,与配置中的ingressroute
一致
匹配符号与(&&
)和或(||
)
ingressroute
的yaml
文件如下
[root@a file-yaml]$ cat busybox-ingressroute-and-or.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: busybox-httpd-ingressroute
namespace: default
spec:
entryPoints:
- web
routes:
- match: (Host("httpd.a.b") && Headers("version", "is_v1")) || (Host("httpd.a.b") && Headers("version", "not_v2"))
### host匹配httpd.a.b并且headers中有version=is_v1的请求或者host匹配http.a.b并且headers中有version=not_v2的请求,转发到服务busybox-httpd-v1上
kind: Rule
services:
- name: busybox-httpd-v1
port: 80
- match: Host("httpd.a.b")
### host匹配httpd.a.b的请求转发到服务busybox-httpd-v2上
kind: Rule
services:
- name: busybox-httpd-v2
port: 80
使用kubectl apply -f busybox-ingressroute-and-or.yaml
创建后,
使用curl
访问后端服务
如下
可以看到访问到了不同的结果,测试正常
使用 AND(&&
)和 OR(||
)运算符来结合多个匹配器,也可以使用括号
报错记录
在yaml
文件中使用了'
(单引号),导致traefik
出现日志,提示非法字符
time="2020-11-18T09:20:52Z" level=error msg="error while parsing rule Host(`httpd.a.b`) && PathPrefix(`/`) && Head('version'): 1:46: illegal rune literal" entryPointName=web routerName=default-busybox-httpd-ingressroute-47ba86a6b9f4755ff5fd@kubernetescrd
关于我
工作:运维工程师
方向:目前专注于微服务,容器技术 以及Devops
方面!
个人微信公众号:
ps:哈哈哈,希望有需求的大佬带上我一起进步啊!!!