ALB Ingress Controller on AWS EKS

Sheikh Vazid
Tensult Blogs
Published in
5 min readAug 20, 2019

This Blog has moved from Medium to blogs.tensult.com. All the latest content will be available there. Subscribe to our newsletter to stay updated.

ALB Ingress Workflow

After Successfully Deploying Kubernetes on AWS EKS, now we can start working on Application Load Balancer on kubernetes.

AWS ALB Ingress Controller for Kubernetes is a controller that triggers the creation of an Application Load Balancer and the necessary supporting AWS resources whenever an Ingress resource is created on the cluster with the kubernetes.io/ingress.class: alb annotation. The Ingress resource uses the ALB to route HTTP or HTTPS traffic to different endpoints within the cluster.

Before starting deployment ALB ingress controller we need to add these Tag to the subnets in your VPC that you want to use for your load balancers so that the ALB Ingress Controller knows that it can use them.

Public subnets in your VPC should be tagged accordingly so that Kubernetes knows to use only those subnets for external load balancers.

Key:  kubernetes.io/role/elbValue: 1

Also, private subnets in your VPC should be tagged accordingly so that Kubernetes knows that it can use them for internal load balancers:

Key: kubernetes.io/role/internal-elbValue: 1

Part - 2: Deploying the ALB ingress controller

Prerequisites:

Download Helm

https://helm.sh/docs/using_helm/#installing-helm

Download Helm Incubator

helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator

Install the chart for ALB Ingress Controller


helm install incubator/aws-alb-ingress-controller --set clusterName=<Cluster Name> --set autoDiscoverAwsRegion=true --set autoDiscoverAwsVpcID=true --name <Release Name> --namespace kube-system

To verify that alb-ingress-controller has started, run

kubectl --namespace=kube-system get pods -l “app.kubernetes.io/name=<Ingress name>,app.kubernetes.io/instance=alb”

Check logs

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

This will show you creating container and worker in the kube system.

Your aws-alb-ingress-controller satisfies Kubernetes ingress resources by provisioning Application Load Balancers.

Creating Ingress Object

Actual ALB will not be created until you create an ingress object which is expected.

Here is a sample deployment file which we are going to expose using ingress object.

Sample app YAML:

cat > sample-app.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: blog
spec:
selector:
matchLabels:
app: blog
replicas: 3
template:
metadata:
labels:
app: blog
spec:
containers:
- name: blog
image: dockersamples/static-site
env:
- name: AUTHOR
value: blog
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
labels:
app: blog
name: blog
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: blog
EOF

Deploy the sample app

kubectl create -f sample-app.yaml

View pods

kubectl get all --selector=app=blog

Ingress object YAML file

cat > ingress.yaml <<EOF
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: blog
labels:
app: blog
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: blog
servicePort: 80
EOF

Deploy ingress object

kubectl apply -f ingress.yaml

Check ingress object

kubectl get ingress -o wide

Here you can see ingress is created and it has the address of Load Balancer which is deployed in AWS Application Load Balancer.

Add these annotation in Ingress object

Add Scheme

Defines whether an ALB should be internal or internet-facing. See Load balancer scheme in the AWS documentation for more details.

kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing

Target Type

Defines if the EC2 instance ID or the pod IP are used in the managed Target Groups. Defaults to instance. Valid options are instance and ip. With instance the Target Group targets are <ec2 instance id>:<node port>, for ip the targets are <pod ip>:<pod port>. ip is to be used when the pod network is routable and can be reached by the ALB.

alb.ingress.kubernetes.io/target-type: instance

Add Subnet ID

The subnets where the ALB instance should be deployed. Must include 2 subnets, each in a different availability zone. These can be referenced by subnet IDs or the name tag associated with the subnet.

Example values for subnet IDs are subnet-a4f0098e,subnet-457ed533,subnet-95c904cd. Example values for name tags are: webSubnet,appSubnet. If subnets are not specified the ALB controller will attempt to detect qualified subnets. This qualification is done by locating subnets that match the following criteria.

kubernetes.io/cluster/$CLUSTER_NAME where $CLUSTER_NAME is the same cluster name specified on the ingress controller. The value of this tag must be shared or owned.

kubernetes.io/role/internal-elb should be set to 1 or an empty tag value for internal load balancers.

kubernetes.io/role/elb should be set to 1 or an empty tag value for internet-facing load balancers.

After subnets matching the above 2 tags have been located, they are checked to ensure 2 or more are in unique AZs, otherwise, the ALB will not be created. If 2 subnets share the same AZ, only 1 of the 2 is used.

alb.ingress.kubernetes.io/subnets:<Public_subnetID 1>,<Public_subnetID 2>,<Public_subnetID 3>

Add Security Groups

Security groups that should be applied to the ALB instance. These can be referenced by security group IDs or the name tag associated with each security group.

Example ID values are sg-723a380a,sg-a6181ede,sg-a5181edd. Example tag values are appSG, webSG. When the annotation is not present, the controller will create a security group with appropriate ports allowing access to 0.0.0.0/0 and attached to the ALB. It will also create a security group for instances that allows all TCP traffic when the source is the security group created for the ALB.

alb.ingress.kubernetes.io/security-groups:

Add certificate ARN

Enables HTTPS and uses the certificate defined, based on arn, stored in your AWS Certificate Manager.

alb.ingress.kubernetes.io/certificate-arn: 

Listen to HTTP/HTTPS ports

Defines the ports the ALB will expose. It defaults to [{"HTTP": 80}] unless a certificate ARN is defined, then it is [{"HTTPS": 443}]. Uses a format as follows '[{"HTTP":8080,"HTTPS": 443}]'.

alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":8080,"HTTPS": 443}]'

Healthcheck Port

Specifies the port used when performing a health check on targets. The default is traffic-port, which indicates the port on which each target receives traffic from the load balancer.

alb.ingress.kubernetes.io/healthcheck-port: traffic-port

Now you check for LoadBalancer, listeners, and TargetGroup is created
LoadBalancer is active now and ready to use LoadBalancer DNS to run into a browser.

Add Success Code Annotation

Defines the HTTP status code that should be expected when doing health checks against the defined healthcheck-path. When omitted, 200 is used.

eg:

alb.ingress.kubernetes.io/success-codes: 200,404,301

Add Domain Hosts

If you are using Domain and sub-domain. We can expose by adding Host in the Ingress object file. These domains will be hosted on Route 53.

Here you can also add a number of Hosts in Ingress object

- host: dashboard.in.com
http:
paths:
- path: /*
backend:
serviceName: kubernetes-dashboard
servicePort: 80

References

--

--

Sheikh Vazid
Tensult Blogs

I’m a Data engineer | learning, writing about data engineering