I would like to configure an Istio ingress gateway which routes traffic to different services based on the prefix of the HTTP path.
For example HTTP traffic path /myservice shall be routed to service myservice.
I have created the following YAML configuration so far:
apiVersion: apps/v1 kind: Deployment metadata: name: myservice namespace: microservices labels: app: myservice spec: replicas: 1 selector: matchLabels: app: myservice template: metadata: labels: app: myservice spec: containers: - name: myservice image: myservice-node ports: - containerPort: 3002 imagePullPolicy: Never --- apiVersion: v1 kind: Service metadata: name: myservice namespace: microservices spec: ports: - nodePort: 32015 port: 3002 targetPort: 3002 selector: app: myservice type: LoadBalancer --- apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: mygateway namespace: microservices spec: selector: istio: ingressgateway # use Istio default gateway implementation servers: - port: number: 80 name: http protocol: HTTP hosts: - "host.docker.internal" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: crossway namespace: microservices spec: hosts: - "*" gateways: - mygateway http: - match: - uri: prefix: /myservice route: - destination: port: number: 3002 host: myservice.microservices.svc.cluster.local
Sending a request to http://192.168.99.111:31878/myservice yielded a 404 error as can be seen below.
$ export INGRESS_HOST=$(minikube ip) $ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}') $ echo "INGRESS_HOST=$INGRESS_HOST, INGRESS_PORT=$INGRESS_PORT" INGRESS_HOST=192.168.99.111, INGRESS_PORT=31878 $ curl -I http://192.168.99.111:31878/myservice HTTP/1.1 404 Not Found date: Sat, 17 Apr 2021 10:54:43 GMT server: istio-envoy transfer-encoding: chunked
In the log file of the ingress gateway I found the following error message:
[2021-04-17T10:54:43.408Z] "HEAD /myservice HTTP/1.1" 404 NR route_not_found - "-" 0 0 0 - "172.17.0.1" "curl/7.64.0" "3b11c571-4372-9b4a-971e-25af260eeba3" "192.168.99.111:31878" "-" - - 172.17.0.4:8080 172.17.0.1:42458 - -
Does anyone have any idea what the problem could be?
2 Answers
I could resolve the problem by changing the value of hosts from "host.docker.internal" to "*".
To explain the solution of Alexander a bit more I added:
Issue: "404 Not Found" caused by istio-envoy "404 NR route_not_found"
When the routing from Gateway to VirtualService is not configured correctly using hosts
property you will get a response status 404 Not Found as response from server: istio-envoy
(response header) like:
$ curl -I http://192.168.99.111:31878/myservice HTTP/1.1 404 Not Found date: Sat, 17 Apr 2021 10:54:43 GMT server: istio-envoy transfer-encoding: chunked
That is caused by the ingress gateway (istio-envoy
) which can't find the route. Thus you saw such an error-message in envoy's access logs with response-flag NR
:
NR: No route configured for a given request in addition to 404 response code, or no matching filter chain for a downstream connection.
Like given part 404 NR route_not_found
in your log-except.
Fix: add a wildcard-route
To make the internal service (virtual host) reachable from outside, like from a browser, you have to define a wildcard-route from *
to *
. See explained in Istio docs Accessing ingress services using a browser:
To work around this problem for simple tests and demos, use a wildcard *
value for the host
in the Gateway and VirtualService configurations.
See also
The official Istio guide: Configure Istio Ingress Gateway also includes steps to test the ingress gateway configuration.
For observation of a 404 NR
with Istio there are similar issues reported:
- isto: Issue #26562: "GET / HTTP/2" 404 NR when trying trying to go via ingressgateway
- envoyproxy: Issue #12936: Connection closed after a 404 + NR
ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJobXBpY2yEdYKOoqqtoZ9itq%2Bz0Z6qrGWXlsGmw8CyZG1oZGK7s3nRqKytnV2jvLV5xaisp5w%3D