【问题标题】:How to rewrite in Istio the right way and avoid 404 error?如何在 Istio 中以正确的方式重写并避免 404 错误?
【发布时间】:2020-12-03 00:21:06
【问题描述】:

场景-

我有两个部署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 访问此 Ingress Gateway IP 时,我在控制台中遇到 404 错误,提示 http://@ 987654335@/favicon.ico 未找到 (因为这已被重写为“/”) 此路线中也没有样式和 js。但是当我尝试访问时 http://ingress-gateway-ip/v1/favicon.ico 我可以看到 favicon 图标以及所有 js 和样式。

请找问题截图here

期待-

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

EDIT-1:

  1. 从原始代码中添加了代码 sn-p
  2. 添加代码file link

EDIT-2:

  1. 添加了screenshot的问题
  2. 修改后的问题陈述以便于理解

【问题讨论】:

  • 您已经指定了 2 个匹配项,/v1 和 v2,所以如果您使用 ingress-gateway-ip,则没有匹配项,如果您只有 test-1 服务,那么 v2 也不应该工作,所以现在只有 v1 可以工作。据我了解,您在虚拟服务和适当的目标规则中缺少一个子集,如下例所示。如果它们都在 test-1 下,那么 /v2 的目标主机应该是 test-1,然后它应该匹配基于子集的部署。看看金丝雀示例here 和here
  • 我很抱歉在那里造成混乱,我确实在原始文件中有子集,只是我想突出匹配规则,因此我以不完整的方式表示它。我已经编辑了问题,这里 [gist.github.com/directlinks/9a019d940caa4516bcff3ff1358e06a0] 是我的完整代码

标签: url-rewriting url-routing istio


【解决方案1】:

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

我假设您的问题是您的 DestinationRule,在 v2 名称中,您的标签是 version: v1,它应该是 version: v2,这就是为什么您来自 /v1 和 /v2 的请求只发送到您的 pod 的 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

当我尝试访问此 Ingress Gateway IP 时,我在控制台中遇到 404 错误说 http://ingress-gateway-ip/favicon.ico

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

如果您希望能够访问,则必须为 / 添加另一个匹配项

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

有 2 个 nginx pod 的工作示例,看看。

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

编辑

问题是所有样式和js在重写时都不能被浏览器在“/”处读取

@Rinor here已经解释过了

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

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

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

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

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

http:
  - match:
    - uri:
        exact: /
    - uri:
        exact: /callback
    - uri:
        prefix: /static
    - uri:
        regex: '^.*\.(ico|png|jpg)$'
    route:
    - destination:
        host: frontend             
        port:
          number: 80

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

【讨论】:

  • 感谢您抽出宝贵时间指出目的地规则错误,我会为 V2.0 修复该问题。让我们关注 V1 版本。假设我有一条规则说如果 URL 有“v1”作为前缀然后将其重写为“/”,在此过程中它完全按照规则中指定的方式执行,但问题是所有样式和 js 不可读当它们被重写时由浏览器在“/”处进行,因为它们实际上存在于“V1”处。看看这个截图->imgur.com/a/Rl4xAFu
  • 嗨@johnmich,我已经编辑了我的答案来回答你的问题,看看。如果它有助于考虑支持/接受答案如果没有,请让我知道您的结果/其他问题。
  • 谢谢,我会尽快检查并提供更新。
猜你喜欢
  • 2021-07-12
  • 1970-01-01
  • 2020-03-15
  • 1970-01-01
  • 2017-03-10
  • 2011-01-27
  • 2020-09-15
  • 1970-01-01
  • 2019-08-18
相关资源
最近更新 更多