Kubernetes Ingress with AWS ALB Ingress Controller

Senthilkumar.P
5 min readSep 23, 2022

--

Introduction

Kubernetes Ingress is an API resource that allows you manage external or internal HTTP(S) access to Kubernetes services running in a cluster.

Amazon Elastic Load Balancing Application Load Balancer (ALB) is a popular AWS service that load balances incoming traffic at the application layer (layer 7) across multiple targets, such as Amazon EC2 instances, in a region.

ALB supports multiple features including host or path based routing, TLS (Transport Layer Security) termination, WebSockets, HTTP/2, AWS WAF (Web Application Firewall) integration, integrated access logs, and health checks.

The open source AWS ALB Ingress controller triggers the creation of an ALB and the necessary supporting AWS resources whenever a Kubernetes user declares an Ingress resource in the cluster.

The Ingress resource uses the ALB to route HTTP(S) traffic to different endpoints within the cluster. The AWS ALB Ingress controller works on any Kubernetes cluster including Amazon Elastic Kubernetes Service (Amazon EKS)

Prerequisite

· AWS EC2

· Existing Kubernates Cluster

· Kubectl cli

· Eksctl cli

Architecture

The following diagram details the AWS components that the aws-alb-ingress-controller creates whenever an Ingress resource is defined by the user.

The Ingress resource routes ingress traffic from the ALB to the Kubernetes cluster.

Kubernetes Ingress Architecture

Following the steps in the numbered blue circles in the above diagram

  1. The controller watches for Ingress events from the API server. When it finds Ingress resources that satisfy its requirements, it starts the creation of AWS resources.
  2. An ALB is created for the Ingress resource.
  3. TargetGroups are created for each backend specified in the Ingress resource.
  4. Listeners are created for every port specified as Ingress resource annotation. If no port is specified, sensible defaults (80 or 443) are used.
  5. Rules are created for each path specified in your Ingress resource. This ensures that traffic to a specific path is routed to the correct TargetGroup created.

Ingress traffic

AWS ALB Ingress controller supports two traffic modes: instance mode and ip mode. Users can explicitly specify these traffic modes by declaring the alb.ingress.kubernetes.io/target-type annotation on the Ingress and the service definitions.

Instance mode: Ingress traffic starts from the ALB and reaches the NodePort opened for your service. Traffic is then routed to the pods within the cluster.

Ip mode: Ingress traffic starts from the ALB and reaches the pods within the cluster directly. To use this mode, the networking plugin for the Kubernetes cluster must use a secondary IP address on ENI as pod IP, also known as the AWS CNI plugin for Kubernetes

Note: If you are using the ALB ingress with EKS on Fargate you want to use ip mode

Kubernetes Services can be exposed in different ways by specifying a type in the ServiceSpec

1. ClusterIp

Exposes the Service on an internal IP in the cluster. This type makes the Service only reachable from within the cluster.

2. NodePort

Exposes the Service on the same port of each selected Node in the cluster using NAT. Makes a Service accessible from outside the cluster using <NodeIP>:<NodePort>. Superset of ClusterIP.

3. LoadBalancer

Creates an external load balancer in the current cloud (if supported) and assigns a fixed, external IP to the Service. Superset of NodePort.

This is classic load balancer type and supported by cloud providers. While we deploy our app and service type as LoadBalacer will get LoadBalancer URL. Refer below screen shot,

LoadBalancer Service

4. Ingress (Explains this doc)

Configure AWS Ingress

  1. Deploy an Amazon EKS cluster

eksctl create cluster \
— name eks-alb-cluster \
— version 1.18 \
— region eu-west-3 \
— nodegroup-name eks-alb-node\
— node-type t2.micro \
— nodes 2 \
— nodes-min 1 \
— nodes-max 4 \
— zones eu-west-3,eu-west-2 \
— managed

2. Create an IAM OIDC provider and associate it with your cluster using below command

eksctl utils associate-iam-oidc-provider — cluster=cluster-name — -approve

3. Deploy AWS ALB Ingress controller

Deploy the relevant RBAC roles and role bindings as required by the AWS ALB Ingress controller:

kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/do

4. Create an IAM policy named ALBIngressControllerIAMPolicy to allow the ALB Ingress controller to make AWS API calls on your behalf

Record the Policy.Arn in the command output, you will need it in the next step

aws iam create-policy \
— policy-name ALBIngressControllerIAMPolicy \
— policy-document
https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1

5. Create a Kubernetes service account and an IAM role (for the pod running the AWS ALB Ingress controller) by substituting $PolicyARN with the recorded value from the previous step

eksctl create iamserviceaccount \
— cluster=clster-name \
— namespace=kube-system \
— name=alb-ingress-controller \
— attach-policy-arn=$PolicyARN \
— override-existing-serviceaccounts \
— approve

6. Deploy the AWS ALB Ingress controller:

curl -sS “https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/alb-ingress-controller.yaml" \
| sed “s/# — — cluster-name=devCluster/- — cluster-name=cluster-name/g” \ | kubectl apply -f –

7. Verify that the deployment was successful and the controller started on using below command

kubectl logs -n kube-system $(kubectl get po -n kube-system | egrep -o alb-ingress[a-zA-Z0–9-]+)

The output should come like below,

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
AWS ALB Ingress controller
Release: v1.1.4
Build: git-0db46039
Repository:
https://github.com/kubernetes-sigs/aws-alb-ingress-controller
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

Deploy a sample application to test the AWS Load Balancer Controller

Deploy a sample application to verify that the AWS Load Balancer Controller creates an Application Load Balancer because of the Ingress object

To deploy a game called 2048 as a sample application, run the following command:

kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/2048/2048-namespace.yaml

kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/2048/2048-deployment.yaml

kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/2048/2048-service.yaml

Deploy an Ingress resource for the 2048 game

kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/2048/2048-ingress.yaml

Ingress Resource

Open a browser and copy-paste your DNS-Name-Of-Your-ALB and you should be able to access your newly deployed 2048 game

Clean Up

Delete AWS Kubernetes Ingress

kubectl delete ing ingress-name

Conclusion

We have successfully created a Kubernetes Ingress with AWS ALB Ingress Controller. Hope you find this article useful.

--

--