MR

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).

Services and Ingress in K8s
Services and Ingress in K8s

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:

Exposing your app using a Load Balancer
Exposing your app using a Load Balancer

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.

Deploying another LB for the Internal Alp
Deploying another LB for the Internal Alp

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.

Adding one more load balancer ot proxy request to apt services
Adding one more load balancer ot proxy request to apt 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.

Ingress let's you create one component for exposing and routing traffic
Ingress let's you create one component for exposing and routing traffic

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.

Ingress is setup in two phases: Deployment and Configuration
Ingress is setup in two phases: Deployment and Configuration

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

Ingress controller is the deployment and Resource is the set of rules and config
Ingress controller is the deployment and Resource is the set of rules and config

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:

YAML
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.0

This 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.

Ingress Resource defines the rules on how to route the traffic.
Ingress Resource defines the rules on how to route the traffic.

We can define the Ingress Resource at a high level like this:

YAML
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: 80

Understanding 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 :)