Istio Envoy 网关已连接到上游但收到 404 响应

问题描述 投票:0回答:1

尝试了解 Istio 和服务网格。我设置了一个带有 nginx 入口并使用 TLS 证书管理器的工作集群。我切换到 Istio 并设置了网关/虚拟服务,据我所知,一切都已连接,但是当我尝试访问该站点时,它返回一个空白屏幕(网络选项卡上有 404 响应)并且当我卷曲时,我看到 404。这与尝试直接或指定 443 端口相同。不知道如何调试,Istio 的文档只提到了具有相同 TLS 证书的多个网关的 404,但我目前只有 1 个网关。另外,网关和虚拟服务位于同一命名空间中,并且在虚拟服务中,后端的路由 - /api 设置在前端 - /

之前

这是我得到的唯一错误响应,它是来自带选项的curl,执行普通的curl根本不会返回任何内容,甚至不会返回403。在GKE控制台上,所有工作负载都很好,日志中没有错误。

curl -X OPTIONS https://app.example.net -I
HTTP/2 404 
date: Wed, 29 Nov 2023 20:18:13 GMT
server: istio-envoy

日志显示与上游的连接:

2023-11-19T20:48:48.798743Z info    Readiness succeeded in 1.15333632s
2023-11-19T20:48:48.799470Z info    Envoy proxy is ready
2023-11-19T21:17:44.948873Z info    xdsproxy    connected to upstream XDS server: istiod.istio-system.svc:15012
2023-11-19T21:47:40.301270Z info    xdsproxy    connected to upstream XDS server: istiod.istio-system.svc:15012
2023-11-19T22:18:07.530190Z info    xdsproxy    connected to upstream XDS server: istiod.istio-system.svc:15012
...
2023-11-20T08:48:48.028231Z info    ads XDS: Incremental Pushing ConnectedEndpoints:2 Version:
2023-11-20T08:48:48.250424Z info    cache   generated new workload certificate  latency=221.620042ms ttl=23h59m59.749615036s
2023-11-20T09:17:09.369171Z info    xdsproxy    connected to upstream XDS server: istiod.istio-system.svc:15012
2023-11-20T09:46:07.080923Z info    xdsproxy    connected to upstream XDS server: istiod.istio-system.svc:15012
...

网格显示了网关、前端、后端的连接边车:

$ istioctl proxy-status
NAME                                           CLUSTER        CDS        LDS        EDS        RDS        ECDS         ISTIOD                      VERSION
backend-deploy-67486897bb-fjv5g.demoapp        Kubernetes     SYNCED     SYNCED     SYNCED     SYNCED     NOT SENT     istiod-64c94c5d78-5879x     1.19.3
demoapp-gtw-istio-674b96dcdb-mfsfg.demoapp     Kubernetes     SYNCED     SYNCED     SYNCED     SYNCED     NOT SENT     istiod-64c94c5d78-5879x     1.19.3
frontend-deploy-6f6b4984b5-lnq4p.demoapp       Kubernetes     SYNCED     SYNCED     SYNCED     SYNCED     NOT SENT     istiod-64c94c5d78-5879x     1.19.3

网关

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: demoapp-gtw
  namespace: demoapp
  annotations:
    cert-manager.io/issuer: "letsencrypt-prod"
spec:
  selector:
    istio: ingressgateway
  servers: 
  - port: 
      name: http
      number: 80
      protocol: HTTP
    hosts: [app.example.net]
    tls:
      httpsRedirect: true
  - port:
      name: https
      number: 443
      protocol: HTTPS
    hosts: [app.example.net]
    tls:
      mode: SIMPLE
      credentialName: demoapp-tls

虚拟服务

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: vert-serv-from-gw
spec:
  hosts: [ app.example.net ]
  gateways: 
  - "demoapp/demoapp-gtw"
  - mesh
  http:
  - match:
    - uri:
        prefix: /api
    route:
    - destination:
        host: backend-svc
        port:
          number: 5000
    corsPolicy:
      allowOrigins:
      - exact: https://app.octodemo.net
      allowMethods:
      - PUT
      - GET
      - POST
      - PATCH
      - OPTIONS
      - DELETE
      allowHeaders:
      - DNT
      - X-CustomHeader
      - X-LANG
      - Keep-Alive
      - User-Agent
      - X-Requested-With
      - If-Modified-Since
      - Cache-Control
      - Content-Type
      - X-Api-Key
      - X-Device-Id
      - Access-Control-Allow-Origin
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: frontend-svc
        port:
          number: 3000

不知道如何进一步尝试和调试,没有明显的错误,如果有人有任何建议,我洗耳恭听。谢谢

编辑 所以我想我已经了解了一些正在发生的事情。在网关的路由上运行 proxy-config 显示:

$ istioctl pc routes demoapp-gtw-istio-674b96dcdb-mfsfg.demoapp 
NAME                                                                            VHOST NAME        DOMAINS     MATCH                  VIRTUAL SERVICE
http.80                                                                         blackhole:80      *           /*                     404
https.443.default.demoapp-gtw-istio-autogenerated-k8s-gateway-https.demoapp     blackhole:443     *           /*                     404
                                                                                backend           *           /stats/prometheus*     
                                                                                backend           *           /healthz/ready*        

istio我对黑洞或直通集群的理解是,黑洞是为了防止未经授权的入口和出口流量进入网格服务,但默认是直通或ALLOW_ANY。在 istio 的配置图下面,我没有看到任何设计,从here

得到提示
$ kubectl get configmap istio -n istio-system -o yaml 
apiVersion: v1
data:
  mesh: |-
    defaultConfig:
      discoveryAddress: istiod.istio-system.svc:15012
      proxyMetadata: {}
      tracing:
        zipkin:
          address: zipkin.istio-system:9411
    defaultProviders:
      metrics:
      - prometheus
    enablePrometheusMerge: true
    rootNamespace: istio-system
    trustDomain: cluster.local
  meshNetworks: 'networks: {}'
kind: ConfigMap
metadata:
  creationTimestamp: "2023-10-26T17:45:35Z"
  labels:
    install.operator.istio.io/owning-resource: installed-state
    install.operator.istio.io/owning-resource-namespace: istio-system
    istio.io/rev: default
    operator.istio.io/component: Pilot
    operator.istio.io/managed: Reconcile
    operator.istio.io/version: 1.19.3
    release: istio
  name: istio
  namespace: istio-system
  resourceVersion: "69895477"
  uid: 3c542bc5-5f9f-4486-a37c-2c04fadba0ed

也许这是因为我的版本更新不够?

$ istioctl version
client version: 1.20.0
control plane version: 1.19.3
data plane version: 1.19.3 (3 proxies)

无论如何,我从网关到服务的路由不应该被黑洞,因为它们是在虚拟服务中声明的......对吗?

kubernetes istio istio-gateway
1个回答
0
投票

好吧,我没有解决方案,但我相当确定我已经找到了问题。

istio 路由指向属于另一个名称空间的服务:

$ istioctl pc routes backend-deploy-7f584f9fd7-mn5z4.demoapp
NAME                                                  VHOST NAME                                                DOMAINS                                                      MATCH                  VIRTUAL SERVICE
test-frontend-svc.demotest.svc.cluster.local:3000     test-frontend-svc.demotest.svc.cluster.local:3000         *                                                            /*                     
9090                                                  kiali.istio-system.svc.cluster.local:9090                 kiali.istio-system, 10.92.12.180                             /*                     
                                                      backend                                                   *                                                            /healthz/ready*        
inbound|80||                                          inbound|http|80                                           *                                                            /*                     
inbound|80||                                          inbound|http|80                                           *                                                            /*                     
test-backend-svcs.demotest.svc.cluster.local:5000     test-backend-svcs.demotest.svc.cluster.local:5000         *                                                            /*                     

基于另一个用户问题的 github 回答(从 2019 年开始)“我的理解是,这是现有解决方法的一个已知限制:使用不同的端口名称可以解决问题。”,我什至更改了端口名称以使得它们在每个命名空间中都是唯一的,并将端口号移动 1,但它仍然指向旧端口名称上的错误服务。

以下是这些更改后更新的虚拟服务:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: vert-serv-from-gw
spec:
  hosts: [ app.octodemo.net ]
  gateways: 
  - "demoapp/demoapp-gtw"
  - mesh
  http:
  - match:
    - uri:
        prefix: /api
    route:
    - destination:
        host: backend-svc
        port:
          number: 5001
    corsPolicy:
      allowOrigins:
      - exact: https://app.octodemo.net
      allowMethods:
      - PUT
      - GET
      - POST
      - PATCH
      - OPTIONS
      - DELETE
      allowHeaders:
      - DNT
      - X-CustomHeader
      - X-LANG
      - Keep-Alive
      - User-Agent
      - X-Requested-With
      - If-Modified-Since
      - Cache-Control
      - Content-Type
      - X-Api-Key
      - X-Device-Id
      - Access-Control-Allow-Origin
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: frontend-svc
        port:
          number: 3001

这不起作用,如上所示,istio 继续指向错误的命名空间服务(test-backend-svcs 和 test-frontend-svc)。因此,在深入研究他们的文档时,他们这样描述了路线:

Note for Kubernetes users: When short names are used (e.g. “reviews” instead of “reviews.default.svc.cluster.local”), Istio will interpret the short name based on the namespace of the rule, not the service. A rule in the “default” namespace containing a host “reviews will be interpreted as “reviews.default.svc.cluster.local”, irrespective of the actual namespace associated with the reviews service. To avoid potential misconfigurations, it is recommended to always use fully qualified domain names over short names.

所以我尝试了这个,通过这篇文章的方法使用通过服务注册表提供的长名称(backend-svc.demoapp.svc.cluster.local和frontend-svc.demoapp.svc.cluster.local),但我仍然得到相同的结果,仅显示尚未配置的其他命名空间的服务。

其他命名空间中甚至没有网关或虚拟服务,我在那里采取的唯一步骤是启用 sidecar 的自动注入。那么这种情况是如何发生的以及为什么会发生,尽管更具体地(不是他们应该需要的)更改指向正确的服务,但它仍然指向错误端口上另一个命名空间中的服务。除了转储集群并重新开始之外,我不知道该怎么办。如果有人知道这是如何发生的,或者他们是否有类似的问题,请告诉我,因为这无助于解决问题或指出需要避免继续下去的事情。

© www.soinside.com 2019 - 2024. All rights reserved.