Istio istio-ingressgateway 抛出"URL '/'没有集群匹配"



我在docker-desktop上安装了Istio。总的来说,它工作得很好。我试图在一个非常简单的虚拟服务上设置一个基于http的匹配,但我只能得到404。以下是技术细节。

我的端点图像是hashi http-echo,它使用net/http库创建一个简单的http服务器,该服务器返回您提供的消息。它工作得很好,不能再简单了。

下面是我的pod和service配置:

kind: Pod
apiVersion: v1
metadata:
name: a
labels:
app: a
version: v1
spec:
containers:
- name: a
image: hashicorp/http-echo
args:
- "-text='this is service a: v1'"
- "-listen=:6789"
---
kind: Service
apiVersion: v1
metadata:
name: a-service
spec:
selector:
app: a
version: v1
ports:
# Default port used by the image
- port: 6789
targetPort: 6789
name: http-echo

下面是一个服务工作的例子,我把它从同一命名空间中的另一个pod中卷走:

/ # curl 10.1.0.29:6789
'this is service a: v1'

下面是在docker-desktop集群中运行的pod:

NAME       READY   STATUS    RESTARTS   AGE     IP          NODE             NOMINATED NODE   READINESS GATES
a          2/2     Running   0          45h     10.1.0.29   docker-desktop   <none>           <none>

下面是注册和管理pod的服务:

NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE     SELECTOR
a-service    ClusterIP   10.101.113.9   <none>        6789/TCP   45h     app=a,version=v1

这是我的istio istio-ingressgateway pod规范通过Helm(似乎工作得很好),我列出,因为这是我已经更改的安装的唯一部分,更改本身是完全微不足道的(只是添加一个新的端口块,似乎工作得很好,因为侦听确实正在发生):

gateways:
istio-ingressgateway:
name: istio-ingressgateway
labels:
app: istio-ingressgateway
istio: ingressgateway
ports:
- port: 15021
targetPort: 15021
name: status-port
protocol: TCP
- port: 80
targetPort: 8080
name: http2
protocol: TCP
- port: 443
targetPort: 8443
name: https
protocol: TCP
- port: 6789
targetPort: 6789
name: http-echo
protocol: TCP

这是istio-ingressgateway上的kubectl get svc只是为了表明我确实有一个外部ip,事情看起来很正常:

NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                     AGE     SELECTOR
istio-ingressgateway   LoadBalancer   10.109.63.15    localhost     15021:30095/TCP,80:32454/TCP,443:31644/TCP,6789:30209/TCP   2d16h   app=istio-ingressgateway,istio=ingressgateway
istiod                 ClusterIP      10.96.155.154   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP                       2d16h   app=istiod,istio=pilot

下面是我的virtualservice:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: a-service
namespace: default
spec:
hosts:
- 'a-service.default.svc.cluster.local'
gateways:
- gateway
http:
- match:
- port: 6789
route:
- destination:
host: 'a-service.default.svc.cluster.local'
port:
number: 6789

这是我的网关:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: gateway
namespace: default
spec:
selector:
app: istio-ingressgateway
servers:
- port:
number: 6789
name: http-echo
protocol: http
hosts:
- 'a-service.default.svc.cluster.local'

最后这里是istio-ingressgateway的调试日志,显示尽管所有这些看似正确的pod, service, gateway, virtualservice和ingressgateway配置,ingressgateway只返回404:

2021-09-27T15:34:41.001773Z debug   envoy connection    [C367] closing data_to_write=143 type=2
2021-09-27T15:34:41.001779Z debug   envoy connection    [C367] setting delayed close timer with timeout 1000 ms
2021-09-27T15:34:41.001786Z debug   envoy pool  [C7] response complete
2021-09-27T15:34:41.001791Z debug   envoy pool  [C7] destroying stream: 0 remaining
2021-09-27T15:34:41.001925Z debug   envoy connection    [C367] write flush complete
2021-09-27T15:34:41.002215Z debug   envoy connection    [C367] remote early close
2021-09-27T15:34:41.002279Z debug   envoy connection    [C367] closing socket: 0
2021-09-27T15:34:41.002348Z debug   envoy conn_handler  [C367] adding to cleanup list
2021-09-27T15:34:41.179213Z debug   envoy conn_handler  [C368] new connection from 192.168.65.3:62904
2021-09-27T15:34:41.179594Z debug   envoy http  [C368] new stream
2021-09-27T15:34:41.179690Z debug   envoy http  [C368][S14851390862777765658] request headers complete (end_stream=true):
':authority', '0:6789'
':path', '/'
':method', 'GET'
'user-agent', 'curl/7.64.1'
'accept', '*/*'
'version', 'TESTING'
2021-09-27T15:34:41.179708Z debug   envoy http  [C368][S14851390862777765658] request end stream
2021-09-27T15:34:41.179828Z debug   envoy router    [C368][S14851390862777765658] no cluster match for URL '/'
2021-09-27T15:34:41.179903Z debug   envoy http  [C368][S14851390862777765658] Sending local reply with details route_not_found
2021-09-27T15:34:41.179949Z debug   envoy http  [C368][S14851390862777765658] encoding headers via codec (end_stream=true):
':status', '404'
'date', 'Mon, 27 Sep 2021 15:34:41 GMT'
'server', 'istio-envoy'

istioct proxy-status:

istioctl proxy-status                                                                                                                     ⎈ docker-desktop/istio-system
NAME                                                   CDS        LDS        EDS        RDS        ISTIOD                     VERSION
a.default                                              SYNCED     SYNCED     SYNCED     SYNCED     istiod-b9c8c9487-clkkt     1.11.3
istio-ingressgateway-5797689568-x47ck.istio-system     SYNCED     SYNCED     SYNCED     SYNCED     istiod-b9c8c9487-clkkt     1.11.3

这里是istioctl pc cluster $ingressgateway:

SERVICE FQDN                                            PORT      SUBSET     DIRECTION     TYPE           DESTINATION RULE
BlackHoleCluster                                        -         -          -             STATIC
a-service.default.svc.cluster.local                     6789      -          outbound      EDS
agent                                                   -         -          -             STATIC
istio-ingressgateway.istio-system.svc.cluster.local     80        -          outbound      EDS
istio-ingressgateway.istio-system.svc.cluster.local     443       -          outbound      EDS
istio-ingressgateway.istio-system.svc.cluster.local     6789      -          outbound      EDS
istio-ingressgateway.istio-system.svc.cluster.local     15021     -          outbound      EDS
istiod.istio-system.svc.cluster.local                   443       -          outbound      EDS
istiod.istio-system.svc.cluster.local                   15010     -          outbound      EDS
istiod.istio-system.svc.cluster.local                   15012     -          outbound      EDS
istiod.istio-system.svc.cluster.local                   15014     -          outbound      EDS
kube-dns.kube-system.svc.cluster.local                  53        -          outbound      EDS
kube-dns.kube-system.svc.cluster.local                  9153      -          outbound      EDS
kubernetes.default.svc.cluster.local                    443       -          outbound      EDS
prometheus_stats                                        -         -          -             STATIC
sds-grpc                                                -         -          -             STATIC
xds-grpc                                                -         -          -             STATIC
zipkin                                                  -         -          -             STRICT_DNS

下面是同一入口上的istioctl pc侦听器:

ADDRESS PORT  MATCH DESTINATION
0.0.0.0 6789  ALL   Route: http.6789
0.0.0.0 15021 ALL   Inline Route: /healthz/ready*
0.0.0.0 15090 ALL   Inline Route: /stats/prometheus*

最后是istioctl routes

NOTE: This output only contains routes loaded via RDS.
NAME          DOMAINS                                 MATCH                  VIRTUAL SERVICE
http.6789     a-service.default.svc.cluster.local     /*                     a-service.default
*                                       /stats/prometheus*
*                                       /healthz/ready*

我已经尝试了许多不同的配置从改变选择器,以确保端口名称匹配尝试不同的端口。如果我将我的虚拟服务从http更改为tcp,端口匹配工作得很好。但是因为我的最终目标是做更高级的基于报头的匹配,我需要在http上匹配。任何见解将非常感激!

原来问题是我在我的网关和虚拟服务的hosts指令中指定了我的服务。将服务指定为hosts条目几乎肯定是不正确的,尽管可以"变通"。这是通过添加一个主机头到curl,即curl ... -H 'Host: kubernetes.docker.internal' ...。但正确的解决方案是简单地添加正确的主机条目,即- mysite.mycompany.com等。在这种情况下,主机就像Apache中的vhosts;它们是一个FQDN,可以解析为网格和集群可以用来发送请求的东西。host,然而,在virtualservice中,destination是服务,这有点复杂,这让我很困惑。

最新更新