How to Access a Service in EKS using an Application Load Balancer?

adil
3 min readOct 29, 2023

--

Part 2: How to Access Multiple Services in EKS using a Single Application Load Balancer?

When we create a Service with a Load Balancer in EKS, AWS will create a classic load balancer.

Photo by Marcin Jozwiak on Unsplash

We need three things in order to enable the application load balancer in EKS. (source):

  1. An IAM Policy
  2. A Service Account with an IAM Role
  3. AWS Load Balancer Controller

Create an IAM Policy

Download the latest IAM Policy rules:

wget https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json

Apply:

aws iam create-policy --policy-name AWSLoadBalancerControllerIAMPolicy --policy-document file://iam_policy.json

The policy should look like this:

Create a Service Account with an IAM Role

Add your EKS cluster’s OIDC data to IAM and create a service account:

eksctl utils associate-iam-oidc-provider --region=<YOUR_REGION> --cluster=<YOUR_CLUSTER_NAME> --approve
eksctl create iamserviceaccount \
--cluster=<YOUR_CLUSTER_NAME> \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--role-name AmazonEKSLoadBalancerControllerRole \
--attach-policy-arn=arn:aws:iam::<YOUR_ACCOUNT_ID>:policy/AWSLoadBalancerControllerIAMPolicy \
--approve

The service account has been created:

The OIDC provider added to IAM:

Add AWS Load Balancer Controller to Your Cluster

The AWS Load Balancer Controller’s helm chart is beneficial because there are many steps to take.

helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=<YOUR_CLUSTER_NAME> \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller

The AWS Load Balancer Controller has been added to the cluster:

The cluster can now set up an application load balancer.

Let’s create a pod and expose it via a service:

00-pod.yaml

apiVersion: v1
kind: Pod
metadata:
labels:
app: web-app
name: web-app
spec:
containers:
- image: ailhan/web-debug
name: web-app
ports:
- containerPort: 80

Apply:

➜ ~ kubectl apply -f 00-pod.yaml
pod/web-app created

01-service.yaml

apiVersion: v1
kind: Service
metadata:
name: web-app-expose
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: web-app

It is important to note that the type LoadBalancer is not used when we create the service. NodePort is the type.

(See: Kubernetes Network: Port, NodePort, TargetPort)

Apply:

➜  ~ kubectl apply -f 01-service.yaml
service/web-app-expose created

02-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-lb
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/load-balancer-name: "web-app-lb"
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-expose
port:
number: 80

Apply:

➜  ~ kubectl apply -f 02-ingress.yaml
ingress.networking.k8s.io/web-app-lb created

Let’s take a look at the load balancer configuration in AWS:

Let’s test it:

--

--