尝试了解 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)
无论如何,我从网关到服务的路由不应该被黑洞,因为它们是在虚拟服务中声明的......对吗?
好吧,我没有解决方案,但我相当确定我已经找到了问题。
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 的自动注入。那么这种情况是如何发生的以及为什么会发生,尽管更具体地(不是他们应该需要的)更改指向正确的服务,但它仍然指向错误端口上另一个命名空间中的服务。除了转储集群并重新开始之外,我不知道该怎么办。如果有人知道这是如何发生的,或者他们是否有类似的问题,请告诉我,因为这无助于解决问题或指出需要避免继续下去的事情。