π Kubernetes Ingress Explained: Enterprise Routing, Cost Optimization & Practical Setup
When people start learning Kubernetes, Services look powerful.
They provide:
Service discovery
Internal load balancing
External exposure (NodePort / LoadBalancer)
So naturally, the question arises:
If Services already expose applications, why do we need Ingress?
This blog will answer that β clearly, practically, and professionally.
π 1. The Real Problem: Why Ingress Was Introduced
Before Kubernetes v1.1, Ingress did not exist.
Organizations used only:
Deployment
Service (ClusterIP / NodePort / LoadBalancer)
At first, everything looked good.
But as enterprises migrated from Virtual Machines β Kubernetes, they started facing serious limitations.
π¨ Problem 1: Services Lack Enterprise Load Balancing Features
Kubernetes Services provide simple Round Robin load balancing via kube-proxy.
But enterprise load balancers like:
NGINX
F5
HAProxy
Traefik
Support advanced features such as:
β Sticky Sessions
β Path-based routing (
/app1,/app2)β Host-based routing (
amazon.com,amazon.in)β TLS/SSL termination
β IP whitelisting / blacklisting
β Ratio-based load balancing
β Web Application Firewall
Kubernetes Services do NOT support these features natively.
This was a major gap.
π° Problem 2: Cost Explosion with LoadBalancer Services
If you create:
type: LoadBalancer
Kubernetes asks the cloud provider for a static public IP.
Now imagine:
200 microservices
200 LoadBalancer services
200 public static IPs
Cloud providers charge for each static IP.
This becomes expensive very quickly.
In traditional VM architecture:
π One Load Balancer
π One Public IP
π Routes traffic internally
But in Kubernetes without Ingress:
π One Service = One IP
π High cost
π― Enter Kubernetes Ingress
Ingress solves BOTH problems:
| Problem | Ingress Solution |
|---|---|
| Missing enterprise routing | Supports path, host, TLS, security |
| Too many public IPs | One Ingress, one IP, many services |
π§ 2. Understanding Ingress Architecture (Very Important)
This is where many people get confused.
Ingress has two parts:
1οΈβ£ Ingress Resource (YAML)
This is just a configuration file.
Example:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-example
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: flask-service
port:
number: 80
π§ What Is This YAML Actually Doing?
This YAML file is creating a routing rule inside Kubernetes.
It tells Kubernetes:
Watch for requests coming to the domain
foo.bar.comIf the request path starts with
/Forward that traffic to the Service named
flask-serviceThe Service will then send the request to one of the running Pods
In simple terms:
This file does not expose your application directly.
It only defines how traffic should be routed once an Ingress Controller is available.
2οΈβ£ Ingress Controller (The Brain)
Ingress Controller is:
The actual load balancer implementation.
Kubernetes does NOT ship with one by default.
You must install it.
Examples:
NGINX Ingress Controller
HAProxy Ingress
Traefik
F5
Ambassador
The controller:
Watches Ingress resources
Updates load balancer configuration
Applies routing logic
Without controller:
π Ingress resource is ignored.
π 3. Practical Demo: Setting Up Ingress on Minikube
Now let's move to hands-on.
π§± Prerequisite: Service Setup
If you have not created a Deployment and Service yet, you can use the complete setup from my previous blog.
π Previous Blog (Service Practical Walkthrough):
https://codeops-labshashnodedev.hashnode.dev/kubernetes-services-deep-dive-service-discovery-nodeport-load-balancing-practical-walkthrough
π GitHub Repository:
https://github.com/Kunja-Ravikiran/k8s-service-deep-dive
This repository includes:
Deployment YAML
Service YAML
NodePort setup
Working example used in this blog
Simply clone the repository and apply the manifests:
git clone https://github.com/Kunja-Ravikiran/k8s-service-deep-dive
cd k8s-service-deep-dive
cd k8s
kubectl apply -f deployment.yaml
kubectl apply -f service-nodeport.yaml
Once your service is running, continue with the Ingress setup explained below.
Step 1οΈβ£ Verify Existing Service
From your previous setup:
kubectl get svc
Example output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
flask-service LoadBalancer 10.109.52.192 <pending> 80:32697/TCP 2m58s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11h
(Your service is of type LoadBalancer. In Minikube, since no real cloud load balancer exists, we access it using the allocated NodePort.)
You can access it using the Minikube IP and the NodePort:
minikube ip
Example:
192.168.49.2
Now access using the NodePort shown in the PORT(S) column (32697 in this case):
curl http://192.168.49.2:32697
Output:
<h1>Kubernetes Service Deep Dive π</h1>
<p><strong>Pod Name:</strong> flask-app-f4646f58c-w6vz7</p>
<p>This response helps demonstrate load balancing.</p>
β οΈ Note: If you try a different port (for example 30007), it will fail because Kubernetes dynamically assigns the NodePort unless explicitly defined.
Step 2οΈβ£ Create Ingress Resource
Create:
vim ingress.yaml
Paste:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-example
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: flask-service
port:
number: 80
π§ What Are We Doing Here?
Here we are creating an Ingress resource and defining how external traffic should be routed inside the cluster.
In simple terms, we are saying:
If a request comes to
foo.bar.comAnd the path is
/Then forward that traffic to the
flask-serviceon port80
This is called host-based + path-based routing.
At this point, we are only defining the rule in Kubernetes.
The actual routing will happen only when an Ingress Controller reads this configuration and applies it.
Apply:
kubectl apply -f ingress.yaml
Check:
kubectl get ingress
Output:
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-example <none> foo.bar.com 80 7s
You will notice:
π The ADDRESS field is empty
π The Ingress is created, but it is not working yet
Why?
Because the Ingress Controller is not installed.
π Step 3οΈβ£ Install Ingress Controller (Minikube)
Enable addon:
minikube addons enable ingress
Output:
π‘ ingress is an addon maintained by Kubernetes.
βͺ Using image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.5
βͺ Using image registry.k8s.io/ingress-nginx/controller:v1.14.1
π Verifying ingress addon...
π The 'ingress' addon is enabled
Now verify:
kubectl get pods -A | grep nginx
Output:
ingress-nginx ingress-nginx-admission-create-65cqx 0/1 Completed 0 82s
ingress-nginx ingress-nginx-admission-patch-4bx6h 0/1 Completed 1 82s
ingress-nginx ingress-nginx-controller-8675c6b56f-4nds5 1/1 Running 0 82s
Notice:
π ingress-nginx-controller is in Running state
This confirms the Ingress Controller is successfully installed.
Now check:
kubectl get ingress
Output:
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-example <none> foo.bar.com 192.168.49.2 80 6m27s
You will now see:
π The ADDRESS field is populated (192.168.49.2)
This means:
The Ingress Controller has picked up your routing rules and assigned an IP address.
π₯ Step 4οΈβ£ Local Testing (Important Trick)
Since foo.bar.com is not a real domain:
You must update:
sudo vim /etc/hosts
Add:
<ingress-ip> foo.bar.com
Now test:
curl http://foo.bar.com/
Boom π₯
It works.
π Bonus: TLS with Ingress
Ingress also supports:
tls:
- hosts:
- foo.bar.com
secretName: tls-secret
This allows:
HTTPS traffic
SSL termination
Secure routing
Enterprise-grade setup.
π§© 4. Visual Flow of Ingress
Hereβs the traffic flow:
User β Ingress Controller β Service β Pod
Instead of:
User β Service (LoadBalancer)
Now:
One Ingress
One IP
Multiple services
Advanced routing
LoadBalancer Service vs Ingress
| Feature | LoadBalancer | Ingress |
|---|---|---|
| IP per service | Yes | No |
| Cost | High | Low |
| Path routing | No | Yes |
| Host routing | No | Yes |
| TLS termination | Limited | Yes |
| Enterprise features | No | Yes |
π Production Reality
In production:
You donβt edit
/etc/hostsDNS maps domain to Ingress IP
Ingress controller runs in dedicated namespace
Often deployed via Helm
Can integrate with API Gateway
Common real-world controllers:
NGINX
Traefik
AWS ALB Ingress Controller
HAProxy
π Key Takeaways
Kubernetes Services are basic load balancers.
Ingress adds enterprise routing features.
Ingress reduces cloud cost significantly.
Ingress requires an Ingress Controller.
One Ingress can manage hundreds of services.