如何以正确的方式在 Istio 中重写并避免 404 错误?
How to rewrite in Istio the right way and avoid 404 error?
场景-
我有 2 个部署 deployment-1
和 label- version:v1
以及 deployment-2
和 label- version:v2
都托管在 nodeport service- test-1
下。我已经创建了一个具有两个匹配条件的虚拟服务,如下所示
- match:
- uri:
exact: /v1
rewrite:
uri: /
route:
- destination:
host: test-1
port:
number: 80
subset: v1
- match:
- uri:
exact: /v2
rewrite:
uri: /
route:
- destination:
host: test-1
port:
number: 80
subset: v2
可以找到代码文件here
问题-
当我尝试在 http://ingress-gateway-ip/v1/favicon.ico 访问此入口网关 IP 时,我在控制台中遇到 404 错误,显示 http://ingress-gateway-ip
/favicon.ico 未找到 (因为已将其重写为“/”) 此路由中也没有样式和 js .但是当我尝试访问时
http://ingress-gateway-ip/v1
/favicon.ico 我可以看到 favicon 图标以及所有 js 和样式。
求问题截图here
期望-
如何使用 url 中的前缀路由访问这两个服务,这意味着当我导航到 /v1 时,只有 V1 版本应该出现而没有 404,当我导航到 /v2 时,应该只有 V2 版本?
EDIT-1:
- 从原始代码中添加了代码片段
- 添加代码 file link
EDIT-2:
- 添加了screenshot个问题
- 为了清楚理解修改了问题陈述
How can I access these two services using a prefix routing in the url, meaning when I navigate to /v1, only the V1 version should come up without 404, and when I navigate to /v2, only the V2 version should come up
我假设你的问题是你的 DestinationRule,在 v2 名称中你的标签是 version: v1
,它应该是 version: v2
,这就是为什么你来自 /v1 和 /v2 的请求只转到 v1 版本你的豆荚。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: test-destinationrule
spec:
host: test-1
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v1 <---
应该是
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: test-destinationrule
spec:
host: test-1
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
When I try to visit this Ingress Gateway IP, I encounter a 404 error in the console saying http://ingress-gateway-ip/favicon.ico
它按设计工作,您没有为 /
指定路径,只是为 /v1
和 /v2
。
如果您希望能够访问,则必须为 /
添加另一个匹配项
- match:
- uri:
prefix: /
route:
- destination:
host: test-1
有2个nginx的工作示例pods,看看。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-v1
spec:
selector:
matchLabels:
version: v1
replicas: 1
template:
metadata:
labels:
app: frontend
version: v1
spec:
containers:
- name: nginx1
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello nginx1 > /usr/share/nginx/html/index.html"]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-v2
spec:
selector:
matchLabels:
version: v2
replicas: 1
template:
metadata:
labels:
app: frontend
version: v2
spec:
containers:
- name: nginx2
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello nginx2 > /usr/share/nginx/html/index.html"]
---
apiVersion: v1
kind: Service
metadata:
name: test-1
labels:
app: frontend
spec:
ports:
- name: http-front
port: 80
protocol: TCP
selector:
app: frontend
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: simpleexample
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
port:
name: http
number: 80
protocol: HTTP
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-virtualservice
spec:
gateways:
- simpleexample
hosts:
- '*'
http:
- match:
- uri:
prefix: /v1
rewrite:
uri: /
route:
- destination:
host: test-1
port:
number: 80
subset: v1
- match:
- uri:
prefix: /v2
rewrite:
uri: /
route:
- destination:
host: test-1
port:
number: 80
subset: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: test-destinationrule
spec:
host: test-1
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
curl 结果:
curl -v ingress-gateway-ip/
404 Not Found
there is no path specified for that in virtual service
curl -v ingress-gateway-ip/v1
HTTP/1.1 200 OK
Hello nginx1
curl -v ingress-gateway-ip/v2
HTTP/1.1 200 OK
Hello nginx2
编辑
the problem is that all the stylings and js are not readable by the browser at "/" when they are being re-written
@Rinor 已经解释过了
我会在此处添加此 Istio in practise 教程,它很好地解释了处理该问题的方法,即为您的依赖项(js、css 等)添加更多路径。
Let’s break down the requests that should be routed to Frontend:
Exact path / should be routed to Frontend to get the Index.html
Prefix path /static/* should be routed to Frontend to get any static files needed by the frontend, like Cascading Style Sheets and JavaScript files.
Paths matching the regex ^.*.(ico|png|jpg)$ should be routed to Frontend as it is an image, that the page needs to show.
http:
- match:
- uri:
exact: /
- uri:
exact: /callback
- uri:
prefix: /static
- uri:
regex: '^.*\.(ico|png|jpg)$'
route:
- destination:
host: frontend
port:
number: 80
如果您还有其他问题,请告诉我。
场景-
我有 2 个部署 deployment-1
和 label- version:v1
以及 deployment-2
和 label- version:v2
都托管在 nodeport service- test-1
下。我已经创建了一个具有两个匹配条件的虚拟服务,如下所示
- match:
- uri:
exact: /v1
rewrite:
uri: /
route:
- destination:
host: test-1
port:
number: 80
subset: v1
- match:
- uri:
exact: /v2
rewrite:
uri: /
route:
- destination:
host: test-1
port:
number: 80
subset: v2
可以找到代码文件here
问题-
当我尝试在 http://ingress-gateway-ip/v1/favicon.ico 访问此入口网关 IP 时,我在控制台中遇到 404 错误,显示 http://ingress-gateway-ip
/favicon.ico 未找到 (因为已将其重写为“/”) 此路由中也没有样式和 js .但是当我尝试访问时
http://ingress-gateway-ip/v1
/favicon.ico 我可以看到 favicon 图标以及所有 js 和样式。
求问题截图here
期望-
如何使用 url 中的前缀路由访问这两个服务,这意味着当我导航到 /v1 时,只有 V1 版本应该出现而没有 404,当我导航到 /v2 时,应该只有 V2 版本?
EDIT-1:
- 从原始代码中添加了代码片段
- 添加代码 file link
EDIT-2:
- 添加了screenshot个问题
- 为了清楚理解修改了问题陈述
How can I access these two services using a prefix routing in the url, meaning when I navigate to /v1, only the V1 version should come up without 404, and when I navigate to /v2, only the V2 version should come up
我假设你的问题是你的 DestinationRule,在 v2 名称中你的标签是 version: v1
,它应该是 version: v2
,这就是为什么你来自 /v1 和 /v2 的请求只转到 v1 版本你的豆荚。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: test-destinationrule
spec:
host: test-1
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v1 <---
应该是
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: test-destinationrule
spec:
host: test-1
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
When I try to visit this Ingress Gateway IP, I encounter a 404 error in the console saying http://ingress-gateway-ip/favicon.ico
它按设计工作,您没有为 /
指定路径,只是为 /v1
和 /v2
。
如果您希望能够访问,则必须为 /
- match:
- uri:
prefix: /
route:
- destination:
host: test-1
有2个nginx的工作示例pods,看看。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-v1
spec:
selector:
matchLabels:
version: v1
replicas: 1
template:
metadata:
labels:
app: frontend
version: v1
spec:
containers:
- name: nginx1
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello nginx1 > /usr/share/nginx/html/index.html"]
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-v2
spec:
selector:
matchLabels:
version: v2
replicas: 1
template:
metadata:
labels:
app: frontend
version: v2
spec:
containers:
- name: nginx2
image: nginx
ports:
- containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello nginx2 > /usr/share/nginx/html/index.html"]
---
apiVersion: v1
kind: Service
metadata:
name: test-1
labels:
app: frontend
spec:
ports:
- name: http-front
port: 80
protocol: TCP
selector:
app: frontend
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: simpleexample
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
port:
name: http
number: 80
protocol: HTTP
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-virtualservice
spec:
gateways:
- simpleexample
hosts:
- '*'
http:
- match:
- uri:
prefix: /v1
rewrite:
uri: /
route:
- destination:
host: test-1
port:
number: 80
subset: v1
- match:
- uri:
prefix: /v2
rewrite:
uri: /
route:
- destination:
host: test-1
port:
number: 80
subset: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: test-destinationrule
spec:
host: test-1
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
curl 结果:
curl -v ingress-gateway-ip/
404 Not Found
there is no path specified for that in virtual service
curl -v ingress-gateway-ip/v1
HTTP/1.1 200 OK
Hello nginx1
curl -v ingress-gateway-ip/v2
HTTP/1.1 200 OK
Hello nginx2
编辑
the problem is that all the stylings and js are not readable by the browser at "/" when they are being re-written
@Rinor 已经解释过了
我会在此处添加此 Istio in practise 教程,它很好地解释了处理该问题的方法,即为您的依赖项(js、css 等)添加更多路径。
Let’s break down the requests that should be routed to Frontend:
Exact path / should be routed to Frontend to get the Index.html
Prefix path /static/* should be routed to Frontend to get any static files needed by the frontend, like Cascading Style Sheets and JavaScript files.
Paths matching the regex ^.*.(ico|png|jpg)$ should be routed to Frontend as it is an image, that the page needs to show.
http:
- match:
- uri:
exact: /
- uri:
exact: /callback
- uri:
prefix: /static
- uri:
regex: '^.*\.(ico|png|jpg)$'
route:
- destination:
host: frontend
port:
number: 80
如果您还有其他问题,请告诉我。