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.
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
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.