Kubernetes Ingress with AWS ALB Ingress Controller
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.
Following the steps in the numbered blue circles in the above diagram
- 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.
- An ALB is created for the Ingress resource.
- TargetGroups are created for each backend specified in the Ingress resource.
- Listeners are created for every port specified as Ingress resource annotation. If no port is specified, sensible defaults (
80
or443
) are used. - 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,
4. Ingress (Explains this doc)
Configure AWS Ingress
- 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
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.