Istio Gateway/VirtualService does not work (local ip works)

9/22/2019

I just set up istio for the first time on a service, and i cannot get the gateway/vs working.

Here is my configuration, it is according with the docs:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: dragon-gateway
spec:
  selector:
    # use Istio default gateway implementation
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: dragon
spec:
  hosts:
  - "vtest.westus.cloudapp.azure.com"
  gateways:
  - dragon-gateway
  http:
  - match:
    - uri:
        prefix: /
    - uri:
        prefix: /status
    - uri:
        prefix: /delay
    - uri:
        prefix: /api/values
    route:
    - destination:
        host: dragon
        port:
          number: 80

The kubectl describe looks fine:

Name:         dragon-gateway
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"networking.istio.io/v1alpha3","kind":"Gateway","metadata":{"annotations":{},"name":"dragon-gateway","namespace":"default"},...
API Version:  networking.istio.io/v1alpha3
Kind:         Gateway
Metadata:
  Creation Timestamp:  2019-09-22T22:54:31Z
  Generation:          1
  Resource Version:    723889
  Self Link:           /apis/networking.istio.io/v1alpha3/namespaces/default/gateways/dragon-gateway
  UID:                 f0738082-dd8b-11e9-b099-e259debf6109
Spec:
  Selector:
    Istio:  ingressgateway
  Servers:
    Hosts:
      *
    Port:
      Name:      http
      Number:    80
      Protocol:  HTTP


Name:         dragon
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"networking.istio.io/v1alpha3","kind":"VirtualService","metadata":{"annotations":{},"name":"dragon","namespace":"default"},"...
API Version:  networking.istio.io/v1alpha3
Kind:         VirtualService
Metadata:
  Creation Timestamp:  2019-09-22T22:54:31Z
  Generation:          1
  Resource Version:    723891
  Self Link:           /apis/networking.istio.io/v1alpha3/namespaces/default/virtualservices/dragon
  UID:                 f0988c3c-dd8b-11e9-b099-e259debf6109
Spec:
  Gateways:
    dragon-gateway
  Hosts:
    vtest.westus.cloudapp.azure.com
  Http:
    Match:
      Uri:
        Prefix:  /
      Uri:
        Prefix:  /status
      Uri:
        Prefix:  /delay
      Uri:
        Prefix:  /api/values
    Route:
      Destination:
        Host:  dragon
        Port:
          Number:  80

The service has the configuration as follow:

apiVersion: v1
kind: Service
metadata:
  namespace: flight
  name: dragon
  labels:
    app: dragon
    release: r1
    version: 1.0.0
spec:
type: ClusterIP
  ports:
      - name: http
        port: 80
        targetPort: 80
      - name: https
        port: 443
        targetPort: 80

 selector:
    app: dragon
    release: r1

The docker file is quite simple:

FROM microsoft/dotnet:latest AS runtime


# ports 
EXPOSE 80
EXPOSE 443

WORKDIR /
COPY /publish /app

RUN dir /app

WORKDIR /app

FROM runtime AS final
ENTRYPOINT ["dotnet", "dragon.dll"]

Please let me know if you have any idea. I tried to curl from another pod, and it works. The problem is using the external IP or using the internal IP that's assigned to the gateway. None of these work.

Thanks in advance for any clue.

Edit:

Adding more info about the curl

curl 40.118.228.111/api/values -v
*   Trying 40.118.228.111...
* TCP_NODELAY set
* Connected to 40.118.228.111 (40.118.228.111) port 80 (#0)
> GET /api/values HTTP/1.1
> Host: 40.118.228.111
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 404 Not Found
< date: Sun, 22 Sep 2019 23:27:54 GMT
< server: istio-envoy
< content-length: 0
<
* Connection #0 to host 40.118.228.111 left intact

Adding proxy status as well:

NAME                                                   CDS        LDS        EDS               RDS        PILOT                           VERSION
dragon-dc789456b-g9fxb.flight                          SYNCED     SYNCED     SYNCED (50%)      SYNCED     istio-pilot-689d75bc8-j7j8m     1.1.3
istio-ingressgateway-5c4f9f859d-nj9sq.istio-system     SYNCED     SYNCED     SYNCED (100%)     SYNCED     istio-pilot-689d75bc8-j7j8m     1.1.3
-- user3053247
azure-kubernetes
envoyproxy
istio
kubernetes

2 Answers

9/23/2019

Looks like you put the dragon VirtualService and the dragon-gateway in the default namespace?

Because service names rely on dns and typically a pod's resolv.conf search paths only include the local namespace, the service name dragon will only resolve properly within the same namespace. Instead, use the fqdn for the dragon service:

...
    route:
    - destination:
        host: dragon.flight.svc.cluster.local
        port:
          number: 80

You have configured istio to route based on hostname but your curl command is using the ip address. Either configure DNS with an A record like this - vtest.westus.cloudapp.azure.com -> 40.118.228.111, or force curl to send the correct host header:

curl http://vtest.westus.cloudapp.azure.com/api/values --resolve vtest.westus.cloudapp.azure.com:80:40.118.228.111
-- erk
Source: StackOverflow

9/24/2019

Hi I am not expert about istio but after invsetigation it looks like working with host and istio gateway, virtualnetworkservices you should use Host prefix in order to pass host HTTP Header, like this:

curl -I -HHost:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/

This is needed because your ingress Gateway is configured to handle “httpbin.example.com”, but in your test environment you have no DNS binding for that host and are simply sending your request to the ingress IP.

From another point of view this setting must match Vitualservice:

A VirtualService must be bound to the gateway and must have one or more hosts that match the hosts specified in a server.

Specifying '*' bound all hostnames. Also you can restrict Virtualservices or specify multiple rules for servers like hosts/hosts using this approach.

More advanced examples you can find here- Istio Server:

Hope this help.

-- Hanx
Source: StackOverflow