Multiple Istio Ingress in Single K8s

Suman Sourav
3 min readNov 8, 2022

Hey folks, this article will guide you to install and control multiple Istio ingresses in a single K8s cluster.

Context:

Why do we need multiple Istio ingresses in a single K8s cluster?

To answer this first we need to know what are ingresses.

Kubernetes says Ingress: An API object that manages external access to the services in a cluster, typically HTTP.

Ingress may provide load balancing, SSL termination and name-based virtual hosting.

So, It manages the external requests that are coming to the services in a cluster. Generally, there is a pod running [ i.e. Nginx, Istio] in our case Istio that will be running and handling all the incoming traffic. We then expose that service using a Load Balancer Service that has an external IP attached to it [ that does not change until we delete the service].

Then we add multiple ingress rules to route our traffic to specific services that are private to the cluster that finally takes the request to pods that are meant to handle that request.

Let’s get out hands dirty and jump into the action.

Prerequisite:

  1. Kubernetes Cluster [Managed or On-premise]
  2. Domain [eg www.example.com]
  3. Istioctl installed in your local machine https://istio.io/latest/docs/reference/commands/istioctl/

Windows: https://community.chocolatey.org/packages/istioctl
Linux: https://istio.io/latest/docs/ops/diagnostic-tools/istioctl/
Mac: https://formulae.brew.sh/formula/istioctl

Steps:

Step 1:

Create namespaces in the Kubernetes cluster for which you want the traffic.

Here I’ll be creating two namespaces Rick and Morty

kubectl create ns rick

kubectl create ns morty

Step 2:

Create a YAML file to install the IstioOperator in the Kubernetes Cluster

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
components:
ingressGateways:
- name: istio-ingressgateway-rick
enabled: true
namespace: rick
enabled: true
label:
istio: istio-ingressgateway-rick
- name: istio-ingressgateway-morty
enabled: morty
namespace: rick
enabled: true
label:
istio: istio-ingressgateway-morty

istioctl install -f .\IstioOperator.yaml -y

After this you can see a LoadBalancer service is created in your namespace

Create a A record in your dns and route it to the EXTERNAL-IP

Step 2.5 [Optional]:

Enable the istio injection

kubectl label namespace default istio-injection=enabled — overwrite

Step 3:

Create Gateway: Create a gateway.yaml file for both the namespaces

Here is an example how it should look

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: api-app-gateway
namespace: rick
spec:
selector:
istio: istio-ingressgateway-rick
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- rick.example.com
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: tls-secret
hosts:
- rick.example.com

kubectl install -f gateway.yaml -n <namespace>

Step 4:

Creating a VirtualService which connects to the service:

This virtual service will connect to a service.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: <nameOftheVirtualService>
spec:
hosts:
- rick.example.com
http:
- name: "<nameOfTheRoute>"
match:
- uri:
prefix: "/<servicename>"
route:
- destination:
host: <servicename>.<namespace>.svc.cluster.local
subset: v2
- name: "nameOfTheRoute"
route:
- destination:
host: <servicename>.<namespace>.svc.cluster.local
subset: v1

kubectl install -f virtualservice.yaml -n <namespace>

That’s all :)

--

--