Kubernetes Ingress: Beginners Guide

Image for post
Image for post
Nginx Ingress

I personally felt exposing services to an external world from Kubernetes cluster is more interesting and challenging topic. It might be a simple ask and can be done just by creating a Kubernetes service within a cluster, but we need to take security and resource cost into an account before implementing a solution. This article take you through how service can be exposed using Ingress and its use compared to other solutions.

Exposing Service to External system

Before going further deep into Ingress resources, let us see all the options available in Kubernetes to expose its services outside the cluster. We have got 3 different options to achieve this, each one has got its own advantages.

NodePort: This is one of the service type which expose the application in a specific port across each of your nodes. You can access the service from outside of the cluster using node IP (http://node-ip-addresss:node-port).

LoadBalancer: This is an another service type which expose the application in an external load balancer IP, this type of service is widely used when the cluster is running in Cloud Infrastructure. This service has got its own limitation when you want to expose multiple services to external system where you need to have separate public IP for each services which will have impact on cost.

Image for post
Image for post
NodePort and LoadBalancer Service

Ingress: Ingress is a separate API object in Kubernetes which is not part of Service resource. Ingress provides similar functionality of load balancer service with additional features which is discussed in later part of this article. Ingress address the major limitation of LoadBalancer service which is exposing multiple service to external world using single public IP address which is cost effective when your application runs in cloud infrastructure, below diagram explains the ingress flow.

Image for post
Image for post
Ingress Flow

What is Ingress?

Ingress is an API object which manages the connection to services within the cluster from external resources/systems via HTTP/HTTPS protocol. Ingress provide us the capability to define a rules to control the traffic routing to each services within the cluster.

Ingress provide us many advantages, below are few of them.

  • Load balancing
  • Handling SSL connection
  • Name based virtual routing
  • URI based routing
  • Exposing application to external world

Setting up an ingress in k8s is a two step process, where we need to create an Ingress controller first and then configure the Ingress resource with the set of rules, let us see each one in details now.

Ingress Controller

K8s has got different type of controllers to manage its resources which will be started automatically as part of control plane component called kube controller manager, but Ingress resources is different and it is not part of default controller manager component you need to deploy this separately. Ingress controller is a prerequisite for creating an ingress resource and it a mandatory component for ingress to work.

We have got number of Ingress controller available in the market and you can chose any one of your choice from them, each had got its own advantages. In this article I will take you through the nginx controller which is widely used in many live applications. You can get the entire list in this link.

prerequisites:1. Kubernetes cluster and kubectl utility.
2. Admin access to Kubernetes cluster

Setting up of ingress controller includes creation of specific namespace, cluster role and cluster role binding, secret, configmap, deployment, service account and jobs. Creating each manually is a time consuming process and prone to human errors, to avoid this Kubernetes github has got a yaml file which will create all resources need for ingress controller, this file is available for different providers you can select based on your requirement, once you run this file using kubectl apply command it will create all the resources and starts the ingress controller deployment within the cluster, the output will looks like below, where you can see all the resources created by this script.

Image for post
Image for post
Ingress controller

Ingress resource

Once you successfully created Ingress controller then we can proceed with creating an Ingress resource. You can create ingress resource using kubectl command. As like other k8s resources ingress has also got 4 components apiVersion, Kind, metadata and spec. The spec part contains the rules to handle the incoming traffic which we can configure according to our project requirements, the below is the sample yaml file which re-direct the traffic to /login to loginService backend in Kubernetes cluster.

You can configure annotations to alter the behaviour of your ingress resource, below example has got simple annotation which rewrite the URL /login to /. You can find the full list of nginx annotation in this link. All the annotation starts with the prefix nginx.ingress.kubernetes.io which is default value, but you can change this by setting — annotations-prefix command line parameter in ingress controller startup script.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: testhost.com
http:
paths:
- path: /login
pathType: Prefix
backend:
service:
name: loginService
port:
number: 80

You can configure any number of path in rule section with specific backend to each of them. Ingress also allow us to configure multiple host in the single ingress resource which enables the feature of name based virtual routing capability. Hosts can be configured for exact match ("test.host.com”) or with a wildcard characters ("*.host.com”). You can get more details in the documentation link.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-host
spec:
rules:
- host: "test.host.com"
http:
paths:
- pathType: Prefix
path: "/test"
backend:
service:
name: testService
port:
number: 80
- host: "*.host.com"
http:
paths:
- pathType: Prefix
path: "/wildcard"
backend:
service:
name: wildCardService
port:
number: 80

HTTP Ingress rules contain below components.

  • Host: An Optional field to specify the hostname of the incoming request.
  • Paths: A list of path which should match to the incoming traffic, “/login” in our example, when user request http://hostname:port/login it invokes the service loginService:80 in the cluster.
  • Backend: Combination of service name and port where request will be redirected if the path and host name match to the incoming traffic.

If none of the hosts or paths matches the HTTP request in the Ingress objects then the traffic will be routed to default backend (which is 404). You can define specific backend for default as well, you can do this in 2 ways either by configuring — default-backend-service command line parameter in controller startup command or by using annotation in ingress resource creation like below, in both the cases you have to create a default service first. You can refer this documentation for more details.

apiVersion: v1
kind: Service
metadata:
name: default-backend-service
spec:
ports:
- port: 80
targetPort: http
selector:
app: default-backend
---apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/default-backend: default-backend-service
spec:
rules:
- host: test.host.com
http:
paths:
- path: /login
pathType: Prefix
backend:
service:
name: loginService
port:
number: 80

TLS In Ingress

In all the above scenarios we have not configured any SSL (HTTPS) for Ingress resources, so the service will be exposed in a plain HTTP protocol, now let us see how we can implement SSL in Ingress, this can achieved in 2 ways which has been explained below.

SSL Passthrough

We can configure Ingress as a SSL passthrough where it will just act as a proxy and allow the request to pass through without validating the certificate, the actual SSL termination(certificate validation) will be handled in the backend service. We can implement this in 2 either by setting an annotation ssl-passthrough value to ‘true’ in ingress resource (as shown below) or by setting — enable-ssl-passthrough command line parameter in nginx controller startup command.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
tls:
- hosts:
- ssl.test.host.com
rules:
- host: test.host.com
http:
paths:
- path: /login
pathType: Prefix
backend:
service:
name: loginService
port:
number: 80

SSL Termination

Ingress can handle SSL termination where certificate validation will happen in Ingress layer. This is a 2 step process where first we need to create a secret with certificate and key file which will used to validate the certificate presented by the client system for handshake, and then configure this secret in Ingress resource.

apiVersion: v1
kind: Secret
metadata:
name: test-tls-secret
type: kubernetes.io/tls
data:
tls.crt: <<base64-encoded-cert>>
tls.key: <<base64-encoded-key>>
---apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /

spec:
tls:
- hosts:
- ssl.test.host.com
secretName: test-tls-secret
rules:
- host: test.host.com
http:
paths:
- path: /login
pathType: Prefix
backend:
service:
name: loginService
port:
number: 80

Conclusion

This is very simple and basic article on Kubernetes Ingress using nginx controller, I hope you find this useful and gives you some insight on Ingress, its use and how to configure it. Please leave me a comment if you need any clarification on any of this topics, and click on clap(like) if you felt this article is interesting and useful. Thank You.

Written by

DevOps Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store