2

So I have successfully deployed istio, atleast I think so, everything seems to work fine. I have deployed my API in Istio and I can reach it through my browser. I can even test my API using postman, but when I try to reach my API through curl it says The remote name could not be resolved: 'api.localhost'. That was the first red flag but I ignored it. Now I'm trying to reach my API from my webapp but Chrome responds with net:ERR_FAILED.

It seems like my services are only available for the host, which is me, and nothing else. I can't seem to find a solution for this on the internet so I hope someone has expirience and knows a fix.

Thanks!


EDIT: More information

My infrastructure is all local, Docker for Desktop with Kubernetes. The Istio version I'm using is 1.5.0.

Gateway:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: api-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http-api
        protocol: HTTP
      hosts:
        - "api.localhost"

Virtual service:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: pb-api
spec:
  gateways:
    - api-gateway
  hosts:
    - "*"
  http:
    - match:
        - uri:
            prefix: /
      rewrite:
        uri: /
      route:
        - destination:
            host: pb-api
            port:
                number: 3001

When I try to do curl http://api.localhost/user/me I expect a 401, but instead I get The remote name could not be resolved: 'api.localhost' as stated above. That error is just the same as when I turn off Docker for desktop and try again. Through postman and the browser it works fine, but curl and my react webapp can't reach it.

RiesvGeffen
  • 1,539
  • 2
  • 11
  • 29
  • What is your infrastructure(cloud,on prem)? What is the version of istio? Could you please add yamls of your gateway and virtual service? Could you add how you use curl? – Jakub Apr 30 '20 at 09:08
  • @jt97 I edited my post with additional information. Thanks already for looking into it! – RiesvGeffen Apr 30 '20 at 10:24
  • 1
    Everything in istio should go through ingress gateway, so if you check it with `kubectl get svc istio-ingressgateway -n istio-system` you should have an external-ip, if the status is pending then you should install some load balancer, for example [metallb](https://metallb.universe.tf/). Could you try to use then `curl -v -H "host: api.localhost" istio-ingressgateway-external-ip/` and check if it works? Take a look at testing on my example [here](https://stackoverflow.com/a/59309172/11977760). I can show you an example from minikube if you think it might help. – Jakub Apr 30 '20 at 11:02
  • 1
    External IP is `localhost` so I tried this command `curl -v -H "host: api.localhost" localhost/user/me` which gave me `401`. So that seems to work, I guess I'll add this header in the requests of the webapp to make it work. – RiesvGeffen Apr 30 '20 at 11:11
  • If you want you can change gateway hosts from "api.localhost" to wildcard, `"*"` and it should work without the header. – Jakub Apr 30 '20 at 11:15
  • But the reason I did that was because I have my client on `localhost` and my api on `api.localhost`. Or is this not the right way to do it? – RiesvGeffen Apr 30 '20 at 11:18
  • Then I would say everything is fine. I will make an answer from that for more visibility. – Jakub Apr 30 '20 at 11:28

1 Answers1

1

As I mentioned in the comments the curl should look like this

curl -v -H "host: api.localhost" istio-ingressgateway-external-ip/

You can check istio-ingressgateway-external ip with

kubectl get svc istio-ingressgateway -n istio-system

As @SjaakvBrabant mentioned

External IP is localhost so I tried this command curl -v -H "host: api.localhost" localhost/user/me which gave me 401


Ubuntu minikube example

Additionally if you would like to curl api.localhost itself then you would have to configure your hosts locally, i'm not sure how this would work in your situation since your external IP is localhost.

But if you want, you can use metallb which is a loadbalancer, so your istio-ingressgateway would get an IP which could be configured in etc/hosts.

Yamls

piVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: demo
spec:
  selector:
    matchLabels:
      app: demo
  replicas: 1
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "echo Hello nginx1 > /usr/share/nginx/html/index.html"]

---

apiVersion: v1
kind: Service
metadata:
  name: demo
  namespace: demo
  labels:
    app: demo
spec:
  ports:
  - name: http-demo
    port: 80
    protocol: TCP
  selector:
    app: demo


---

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: demo-gw
  namespace: demo
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      name: http
      number: 80
      protocol: HTTP
    hosts:
    - "example.com"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: demo-vs
  namespace: demo
spec:
  gateways:
  - demo-gw
  hosts:
  - "example.com"
  http:
  - match:
    - uri:
        prefix: /
    rewrite:
      uri: /
    route:
    - destination:
        host: demo.demo.svc.cluster.local
        port:
          number: 80

etc/hosts

127.0.0.1       localhost
10.101.143.xxx  example.com

Testing

curl -v -H "host: example.com" http://10.101.143.xxx/

< HTTP/1.1 200 OK


curl -v example.com

< HTTP/1.1 200 OK

Hope you find this useful.

Jakub
  • 8,189
  • 1
  • 17
  • 31
  • Thank you for your help. Since I can't change the host header in a request using React (host header is always 'localhost'). Browser don't allow you to do so. Do you maybe have advice on how to make this work in a webapp? – RiesvGeffen Apr 30 '20 at 12:51
  • The only thing which came to my mind is to change the hosts from api.localhost to wildcard, then you won't need to use the header. Worth to try how it's gonna work in your case. – Jakub Apr 30 '20 at 13:54
  • 1
    Changed it to wildcard, but because my client/ui is on wildcard too it clashes and my client wasn't reachable since the api returned with 404 when I tried to reach my client. I kept my api on wildcard and added rewrite from `/api/` to `/`. Now I can reach my api so I'll stick to this, I just preferred the `api.localhost` but I guess it won't work for browsers. – RiesvGeffen Apr 30 '20 at 14:12