Multiple Istio Ingress in Single K8s
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:
- Kubernetes Cluster [Managed or On-premise]
- Domain [eg www.example.com]
- 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: rickspec:
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 :)