如何以正确的方式在 Istio 中重写并避免 404 错误? [英] How to rewrite in Istio the right way and avoid 404 error?

查看:36
本文介绍了如何以正确的方式在 Istio 中重写并避免 404 错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

场景-

我有 2 个部署 deployment-1label- version:v1deployment-2label- version:v2> 两者都托管在 nodeport service-test-1 下.我创建了一个具有两个匹配条件的虚拟服务,如下

 - 匹配:- uri:精确:/v1改写:里:/路线:- 目的地:主持人:test-1港口:数量:80子集:v1- 比赛:- uri:精确:/v2改写:里:/路线:- 目的地:主持人:test-1港口:数量:80子集:v2

可以在此处

找到代码文件

问题-

当我尝试在 http://ingress-gateway-ip/v1/favicon.ico 上访问此 Ingress 网关 IP 时,我在控制台中遇到了一个 404 错误,内容为 http://<代码>ingress-gateway-ip/favicon.ico not found (因为这已经被重写为/") 样式和js也不存在在这条路线上.但是当我尝试访问时http://ingress-gateway-ip/v1/favicon.ico 我可以看到 favicon 图标以及所有 js 和样式.

请在这里找到问题的截图

期待-

如何使用url中的前缀路由访问这两个服务,这意味着当我导航到/v1时,应该只出现V1版本而没有404,而当我导航到/v2时,应该只出现V2版本起来了?

EDIT-1:

  1. 从原始代码中添加了代码片段
  2. 添加了代码文件链接

EDIT-2:

  1. 添加了问题的屏幕截图
  2. 修改问题陈述以便清楚理解

解决方案

如何使用url中的前缀路由访问这两个服务,这意味着当我导航到/v1时,应该只出现V1版本而没有404,而当我导航到/v2时,应该只出现V2版本向上

我假设您的问题是您的 DestinationRule,在 v2 名称中,您的标签是 version: v1 并且应该是 version: v2,这就是您从/v1 发出请求的原因并且/v2 仅转到您的 pod 的 v1 版本.

apiVersion:networking.istio.io/v1alpha3种类:目的地规则元数据:名称:测试目的地规则规格:主持人:test-1子集:- 名称:v1标签:版本:v1- 名称:v2标签:版本:v1 <---

应该是

apiVersion:networking.istio.io/v1alpha3种类:目的地规则元数据:名称:测试目的地规则规格:主持人:test-1子集:- 名称:v1标签:版本:v1- 名称:v2标签:版本:v2


<块引用>

当我尝试访问这个 Ingress 网关 IP 时,我在控制台中遇到了一个 404 错误说 http://ingress-gateway-ip/favicon.ico

它按设计工作,您没有为 / 指定路径,只为 /v1/v2 指定路径.

如果您希望能够访问,则必须为 /

添加另一个匹配项

- 匹配:- uri:字首:/路线:- 目的地:主持人:test-1


有 2 个 nginx pod 的工作示例,请看一看.

apiVersion: apps/v1种类:部署元数据:名称:nginx-v1规格:选择器:匹配标签:版本:v1复制品:1模板:元数据:标签:应用程序:前端版本:v1规格:容器:- 名称:nginx1图片:nginx端口:- 容器端口:80生命周期:后开始:执行:命令:[/bin/sh"、-c"、echo Hello nginx1"/usr/share/nginx/html/index.html"]---api版本:应用程序/v1种类:部署元数据:名称:nginx-v2规格:选择器:匹配标签:版本:v2复制品:1模板:元数据:标签:应用程序:前端版本:v2规格:容器:- 名称:nginx2图片:nginx端口:- 容器端口:80生命周期:后开始:执行:命令:[/bin/sh"、-c"、echo Hello nginx2"/usr/share/nginx/html/index.html"]---api版本:v1种类:服务元数据:名称:test-1标签:应用程序:前端规格:端口:- 名称:http-front端口:80协议:TCP选择器:应用程序:前端---api 版本:networking.istio.io/v1alpha3种类:网关元数据:名称:简单示例规格:选择器:istio:入口网关服务器:- 主持人:- '*'港口:名称:http数量:80协议:HTTP---api 版本:networking.istio.io/v1alpha3种类:虚拟服务元数据:名称:测试虚拟服务规格:网关:- 简单的例子主持人:- '*'网址:- 比赛:- uri:前缀:/v1改写:里:/路线:- 目的地:主持人:test-1港口:数量:80子集:v1- 比赛:- uri:前缀:/v2改写:里:/路线:- 目的地:主持人:test-1港口:数量:80子集:v2---api 版本:networking.istio.io/v1alpha3种类:目的地规则元数据:名称:测试目的地规则规格:主持人:test-1子集:- 名称:v1标签:版本:v1- 名称:v2标签:版本:v2

curl 的结果:

curl -v ingress-gateway-ip/404 未找到在虚拟服务中没有为此指定路径curl -v ingress-gateway-ip/v1HTTP/1.1 200 正常你好 nginx1curl -v ingress-gateway-ip/v2HTTP/1.1 200 正常你好 nginx2


编辑

<块引用>

问题是浏览器无法在/"处读取所有样式和js当它们被重写时

@Rinor 这里

我会在此处添加此 Istio 实践教程,它很好地解释了处理该问题的方法,即为您的依赖项(js、css 等)添加更多路径.

<块引用>

让我们分解应该路由到前端的请求:

确切路径/应该路由到 Frontend 以获取 Index.html

前缀路径/static/* 应该路由到前端以获取前端所需的任何静态文件,例如层叠样式表JavaScript文件.

匹配正则表达式 ^.*.(ico|png|jpg)$ 的路径应该路由到前端,因为它是页面需要显示的图像.

http:- 比赛:- uri:精确的:/- uri:准确:/回调- uri:前缀:/静态- uri:正则表达式:'^.*\.(ico|png|jpg)$'路线:- 目的地:主持人:前端港口:数量:80

如果您还有其他问题,请告诉我.

Scenario-

I have 2 deployments deployment-1 with label- version:v1 and deployment-2 with label- version:v2 both are hosted under a nodeport service- test-1. I have created a virtual service with two match conditions as follows

  - 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

The code file can be found here

Problem-

When I try to visit this Ingress Gateway IP at http://ingress-gateway-ip/v1/favicon.ico, I encounter a 404 error in the console saying http://ingress-gateway-ip/favicon.ico not found (because this has been re-written to "/") also the stylings and js are absent at this route. But when I try to visit http://ingress-gateway-ip/v1/favicon.ico I can see the favicon icon along with all the js and stylings.

Please find the screenshots of the problem here

Expectation-

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?

EDIT-1:

  1. Added code snippet from the original code
  2. Added code file link

EDIT-2:

  1. Added screenshot of the problem
  2. Modified problem statement for clear understanding

解决方案

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

I assume your issue is your DestinationRule, in the v2 name your label is version: v1 and it should be version: v2, that's why your requests from /v1 and /v2 went only to v1 version of your pod.

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 <--- 

It should be

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

It's working as designed, you haven't specified path for /, just for /v1 and /v2.

If you want to be able to access then you would have to add another match for /

- match:
  - uri:
      prefix: /
  route:
    - destination:
        host: test-1


There is working example with 2 nginx pods, take a look.

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

Results from 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


EDIT

the problem is that all the stylings and js are not readable by the browser at "/" when they are being re-written

It was already explained by @Rinor here

I would add this Istio in practise tutorial here, it explains well a way of dealing with that problem, which is to add more paths for your dependencies(js,css,etc).

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

Let me know if you have any more questions.

这篇关于如何以正确的方式在 Istio 中重写并避免 404 错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆