Understanding Services & Ingress in Kubernetes
Services make Pods reachable; Ingress routes external traffic to the right Service. Learn ClusterIP, NodePort, LoadBalancer, and Ingress (controller vs resource).

A lot of folks trying to learn about Kubernetes get confused about Ingress / Ingress Controller and Ingress Resource in Kubernetes. The agenda of this article is to clear that by building your intuition from the ground up.
PREREQUISITE: Basic knowledge of Kubernetes and it's architecture.
With that out of the way let's get started!
Services
Services in Kubernetes are a way to to expose your app, they allocate IPs to Pods, enabling them for connection in the Cluster.
There are three types of services in Kubernetes:
1. ClusterIP
It exposes the app on a cluster-internal IP address. This means your app will only be accessible inside the Kubernetes Cluster’s network.
2. NodePort
It builds on top of ClusterIP and allocates a port between 30000 to 32676 on each node’s IP, which the external client’s can use to reach your app. Eg: 192.156.0.1:30008
3. LoadBalancer
This integrates with the cloud provider’s load balancers to expose your app to the external world. You cannot try this on minikube or while building a K8s cluster locally.
Okay, so everything is fine until up here, right?
Let’s explore the problem with load balancers in Kubernetes. Let’s say you have an ecom platoform at https://mystore.com and you deploy it using a Kubernetes cluster.
You expose your application using a LoadBalancer as stated in the diagram:

Now, let’s say you’re expanding your business, and you want to create an internal app to manage the inventory and your employees.
The developers build this as a separate app.
To harness the existing resources, you deploy this new internal in the same cluster as a different service.
Then you deploy yet another LoadBalancer service to expose your internal app.

Great, but your cloud provider is going to charge you for both of these load balancers.
But wait, how do you decide to route which requests to which services?
You deploy yet another load balancer to proxy the request to appropriate services.

Now your cloud provider charges your for all the load balancers.
Now imagine a company like Amazon having 1000s of services, it would skyrocket your cloud bills to have a LB for each of these services.
This is where Ingress comes into picture.
Ingress
Ingress lets your users access your app using a single externally accessible URL that you can configure to route traffic to different services.

To understand how Ingress works, let’s see how we would do it without ingress.
We would typically set up a reverse-proxy solution using something like NGINX and write a Configuration on how to route the traffic.

Now the solution you deploy (NGINX) is known as the Ingress Controller and your configuration for routing (and other stuff like SSL certs.) is known as Ingress Resource

Remember: Ingress Controllers are not installed in Kubernetes by default. So if you just write Ingress Resource and expect them to work, it won’t.
Ingress Controller
We have multiple Ingress Controllers like NGINX, GCE, Istio, etc. The most popular is the NGINX and that’s what we’re going to use to understand.
An Ingress Controller is basically just a Pod with a specialized purpose in our Kubernetes Cluster. We can define it somewhat like this:
apiVersion: extensions/vlbetal
kind: Deployment
metadata:
name: nginx-ingress-controller
spec:
replicas: 1
selector:
matchLabels:
name: nginx-ingress
template:
metadata:
labels:
name: nginx-ingress
spec:
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.21.0This is just a demo config, you can refer to the documentation to get the actual configuration yaml manifest for the NGINX Ingress Controller.
Ideally there are other configurations and env variables required that are stored using ConfigMaps and Secrets. We also specify auth using ServiceAccount following the best practices.
After creating this controller, we also need to create a Service to expose this controller, we can setup a simple NodePort service to expose our Ingress Controller and link it using labels and selectors.
Ingress Resource
An ingress resource is just a set of rules and configurations applied on the Ingress Controller.
In our case we can route traffic to our main domain mystore.com to our public facing ecommerce platform while the requests to subdomain internal.mystore.com can be routed to our internal app.

We can define the Ingress Resource at a high level like this:
apiVersion: extensions/v1
kind: Ingress
metadata:
name: ingress-routeer
spec:
rules:
- host: mystore.com
http:
paths:
- backend:
serviceName: shop-service
servicePort: 80
- host: internal.mystore.com
http:
paths:
- backend:
serviceName: internal-service
servicePort: 80Understanding the difference between Ingress Controllers and Resource
Ingress Controller
At the most basic level Ingress Controller is the actual running service that exposes your application.
It’s basically a Pod running inside your Kubernetes cluster that has the specialized purpose of routing traffic to appropriate services in your cluster.
It’s not installed in the Kubernetes Cluster by default.
You get to pick and choose which service (NGINX, Traefik, Istio) you want to use as your ingress controller
Ingress Resource
It’s just the set of rules and configurations you define for the Ingress Controller to direct it on how to route the traffic.
It’s defined by kind: Ingress in k8s manifests files.
An Ingress Resources requires an Ingress Controller to work.
Alright!
I hope I was able to clear out your confusion between Ingress, Ingress Controllers and Ingress Resources.
If you found this blogs useful, please share it with your friends and colleagues.
You can check more of my wriitings at: moyezrabbani.dev/blogs
Thanks for reading, have a great day :)