I have a 'UI' and an 'API' microservice that I'm deploying on k8s default namespace with Istio enabled. My k8s environment is a dev box and doesn't have an External Load Balancer.
The UI's port configuration is 80(service port):80(container port in pod).
The API's port configuration is 8000(service port):80(container port in pod)
I have to expose both these microservices for external traffic, since some people might use the 'UI' and some people might directly call the 'API' (via postman) for their requests.
When these microservices were running as simple docker containers without the k8s layer, users directly used the host.example.com
for UI and host.example.com:8000/api
for API calls (API calls are JSON-RPC).
I have a Gateway and VirtualService set up for both these microservices:
For UI:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ui-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- host.example.com
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ui-vs
spec:
hosts:
- host.example.com
gateways:
- ui-gateway
http:
- route:
- destination:
port:
number: 80
host: ui --> name of k8s svc
For API:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: api-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- host.example.com
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: api-vs
spec:
hosts:
- host.example.com
gateways:
- api-gateway
http:
- route:
- destination:
host: api -> name of api service
port:
number: 8000
Now going by the Istio documentation (accessing on browser) to access this UI in the browser I need to access it via ${INGRESS_HOST}:${INGRES_PORT}
. In my case:
INGRESS_HOST=host.example.com
INGRESS_PORT=31165
So accessing http://host.example.com:31165 loads the UI, how do I now access the API microservice externally on host.example.com
via Postman etc? The 8000 API port is not accessible from outside. I guess it all has to go via 31165, but what route do I need to use to access the API directly? What changes do I need to do for this, if any, in my set-up? I have just started with Istio.
Simplest solution is to combine both into one VirtualService
and work with something like a path + a rewrite:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-vs
spec:
hosts:
- host.example.com
gateways:
- my-gateway
http:
- match:
- uri:
prefix: /api
rewrite:
uri: /
route:
- destination:
host: api # -> name of api service
port:
number: 8000
- match:
- uri:
prefix: /ui
rewrite:
uri: /
route:
- destination:
port:
number: 80
host: ui # --> name of k8s svc
If you query host.example.com:<nodePort>/api
you'll end up at the api host, and with host.example.com:<nodePort>/ui
the the ui.
You could also use subdomains (ui.example.com:<nodePort>
and api.example.com:<nodePort>
) or route based on headers. Check out the docs for more examples.