实现思路

Ingress nginx通过不同uri去匹配代理多个kibana时问题处理

我前期想实现的结果是这样的

当访问ingress域名kibana.putianhui.cn/30203时请求到kibana-video这个svc的kibana。

当访问ingress域名kibana.putianhui.cn/30204时请求到kibana-media这个svc的kibana。

出现问题

第一次ingress.yaml这样写的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: kibana-ingress
namespace: es
spec:
rules:
- host: kibana.putianhui.cn
http:
paths:
- path: /30203
pathType: Prefix
backend:
serviceName: kibana-video
servicePort: 5601
- path: /30204
pathType: Prefix
backend:
serviceName: kibana-media
servicePort: 5601

这样的yaml出现了一个问题,就是我访问kibana.putianhui.cn/30203或者kibana.putianhui.cn/30204都是提示的404

当把某个匹配路径改为 / 后,只能访问到当前的kibana,另外一个kibana提示404

解决方案

需要做的是将kibanabasePath设置为/30203/30204

请参阅下面的网址:https://www.elastic.co/guide/zh-CN /kibana/current/settings.html

因为我是通过Deployment部署的kibana,这里我添加kibana.basePath的环境变量到容器中即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: kibana-video
name: kibana-video
spec:
replicas: 1
selector:
matchLabels:
app: kibana-video
template:
metadata:
labels:
app: kibana-video
spec:
containers:
- name: kibana
image: registry.cn-shanghai.aliyuncs.com/cmdsdis/kibana:7.9.3
ports:
- containerPort: 5601
protocol: TCP
env:
- name: ELASTICSEARCH_HOSTS
value: "http://video.es.svc:9200"
- name: SERVER_BASEPATH # 新增的环境变量
value: /30203

修改后的ingress规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: kibana-ingress
namespace: es
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: kibana.putianhui.cn
http:
paths:
- path: /30203(/|$)(.*)
pathType: Prefix
backend:
serviceName: kibana-video
servicePort: 5601
- path: /30204(/|$)(.*)
pathType: Prefix
backend:
serviceName: kibana-media
servicePort: 5601
status:
loadBalancer:
ingress:
- ip: 192.168.203.28

如果不加rewrite注解请求的话会将http://kibana.putianhui.cn/30203/URL转发到集群中的http://svc-nginx/30203/URL上,也就是说最后一行的path: /30203也会当作请求的一部分,追加到url中。

但是,如果nginx实际的请求地址为http://svc-nginx/30203/URL,则会报404,找不到服务。

因此,需要使用rewrite注解:

Name Description Values
nginx.ingress.kubernetes.io/rewrite-target Target URI where the traffic must be redirected string
nginx.ingress.kubernetes.io/ssl-redirect Indicates if the location section is accessible SSL only (defaults to True when Ingress contains a Certificate) bool
nginx.ingress.kubernetes.io/force-ssl-redirect Forces the redirection to HTTPS even if the Ingress is not TLS Enabled bool
nginx.ingress.kubernetes.io/app-root Defines the Application Root that the Controller must redirect if it’s in ‘/‘ context string
nginx.ingress.kubernetes.io/use-regex Indicates if the paths defined on an Ingress use regular expressions bool

表达式说明((/|$)(.*)):两个括号用以分组,第一个是匹配/或者 $表示已经结束,第二组 .表示任意一个非换行符的字符 *表示0次或多次,两部分组合到一起就是,以 /匹配任意内容的,都转发到 /第二部分匹配到的文本。

再请求http://kibana.putianhui.cn/30203,会转发到http://kibana.putianhui.cn/30203/,path的声明由指定路径改为一个正则表达式,匹配上/30203(/|$)(.*)的请求,都会转发到一个以“/”开始拼接正则表达式的第二个组内容的URL,使用这种方式去掉了30203

应用后问题即可解决。