0

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.

halfer
  • 19,824
  • 17
  • 99
  • 186
user1452759
  • 8,810
  • 15
  • 42
  • 58

2 Answers2

1

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.

Chris
  • 5,109
  • 3
  • 19
  • 40
  • So I don't need to give host.example.com:31165 (with the 31165 port in the url) in the browser? I think this host.example.com/ui might not work..? I will try this though and let you know. – user1452759 Mar 17 '23 at 16:23
  • Sure you need to add the port, thought that was clear. I edited my answer. If the answer was helpful please consider upvoting/accepting. – Chris Mar 17 '23 at 22:35
  • Thank you for your help! I tried this and it works in the way I was expecting. – user1452759 Mar 18 '23 at 15:44
1

one option is to add a host header.

an easier way for local dev stuff is to use a *.nip.io address.

If your ingress got an IP (look for an external IP in the result of k get svc -n istio-system istio-ingressgateway), then that's what you would use in the url.

e.g.

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: grafana-virtualservice
  namespace: monitoring
spec:
  gateways:
  - grafana-gateway
  hosts:
  - grafana.192.168.87.2.nip.io
  http:
  - route:
    - destination:
        host: kube-prometheus-stack-grafana
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:  
  name: grafana-gateway
  namespace: monitoring
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - grafana.192.168.87.2.nip.io
    port:
      name: http
      number: 80
      protocol: HTTP

HTTPS redirects work too if you create a certificate

e.g.

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: argocd-gateway
  namespace: argocd
spec:
  selector:
    istio: ingressgateway
  servers:
    - hosts:
        - argocd.192.168.87.2.nip.io
      port:
        name: http
        number: 80
        protocol: HTTP
      tls:
        httpsRedirect: true
    - hosts:
        - argocd.192.168.87.2.nip.io
      port:
        name: https
        number: 443
        protocol: HTTPS
      tls:
        credentialName: argocd.192.168.87.3.nip.io
        mode: SIMPLE
Stand__Sure
  • 253
  • 1
  • 13