Ingress Resource

Ingress Resource

It’a single entry point into the cluster.
It’s basically a layer-7 load balancer that is managed within the K8s cluster.
An Ingress is capable of providing more functionality than a simple NodePort Service
It provides features like:
  1. SSL termination
  • Create a Kubernetes Secret containing the SSL certificate and private key. • Update the application's service to use this Secret for TLS termination. • Ensure that the Ingress controller (e.g., Nginx Ingress) is configured to handle TLS. • Define an Ingress resource that specifies the host, paths, and TLS settings for the application.
  1. Advanced load balancing
  1. Request based routing
Ingress actually do nothing by themselves. In order for Ingresses to do anything, we must install one or more Ingress controllers.
There are a variety of Ingress Controllers available, all of which implement different methods for providing external access to your Services.
Ingress uses an existing reverse proxy solution like Nignx or Traefik to run an Ingress Controller. Then a set of ingress rules are configured using definition files. These are called as Ingress Resources. A K8s cluster does not have an ingress controller by default. If you just configure ingress resources, it won’t work.
Note: Ingress Controllers are not just regular reverse-proxy solutions. They have additional intelligence built into them to monitor the K8s cluster for new ingress resources and configure themselves accordingly. The ingress controller needs a service account to do this.
The ingress controller requires a NodePort Service to be exposed at a node port on the cluster. Alternatively, the ingress controller requires a LoadBalancer Service to be exposed as a public IP. DNS server can then be configured to point to the IP of the cloud-native NLB.
notion image

Deploying Ingress Controller

  • An ingress controller is deployed as just another deployment in K8s.
  • The example below uses the build image of ingress controller using Nginx as reverse proxy.
  • The program to run the ingress controller is present at /nginx-ingress-controller which is passed as args.
  • Nginx requires some configuration to run as expected. Instead of configuring these in the deployment definition file. These should be decoupled into a ConfigMap nginx-configuration. This config file is passed in args as well.
  • Nginx ingress controller requires two environment variables POD_NAME and POD_NAMESPACE to be passed. This can be fetched from the metadata.
  • Finally, expose the ports on the ingress controller pod to allow the service to reach the pod.
apiVersion: extensions/v1beta1 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 args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/nginx-configuration env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: http containerPort: 80 - name: https containerPort: 443
A NodePort service can then be configured to make the ingress controller accessible at a node port in the cluster.
apiVersion: v1 kind: Service metadata: name: nginx-ingress spec: type: NodePort ports: - port: 80 targetPort: 80 protocol: TCP name: http - port: 443 targetPort: 443 protocol: TCP name: https selector: name: nginx-ingress

Ingress Resource

Ingress resources are set of rules and configuration applied on the ingress controller. This includes path based routing, subdomain based routing, etc. The backend in the ingress definition file defines the service name and the port at which the application service is running.
For every hostname or domain name, we need a separate rule. For each rule, we can route traffic based on the path.

Ingress to route all traffic to a backend service

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-wear spec: backend: serviceName: wear-service servicePort: 80

Path based routing

In the example below, we have a single hostname (1 rule) and 2 paths.
notion image
 
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-wear spec: rules: - http: paths: - path: /wear pathType: Prefix backend: service: name: wear-service port: number: 80 - path: /watch pathType: Prefix backend: service: name: watch-service port: number: 80
If none of the rules or paths match, then the user will be redirected to the default backend service if it is configured in the ingress resource. So, you should deploy a service by that name if you want to display a nice 404 not found message.

Hostname based routing

In case of routing to different hostnames, we need separate rules.
notion image
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-wear spec: rules: - host: wear.my-online-store.com http: paths: - backend: service: name: wear-service port: number: 80 - host: watch.my-online-store.com http: paths: - backend: service: name: wear-service port: number: 80

Rewrite target

Rewrite target rewrites the URL by replacing whatever is under rules->http->paths->path which happens to be /pay in this case with the value in rewrite-target. This works just like a search and replace function.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-wear annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: wear.my-online-store.com http: paths: - backend: service: name: wear-service port: number: 80

Demo using Traefik as Ingress Controller

The first video in the playlist demonstrates setting up MetalLB as the load balancer on a VM to allow the ingress service to be accessed externally at the IP of the VM and setting up Traefik ingress controller. The second video shows examples of ingress resources to route traffic to different backend services.