Architecture Overview
The AWS Load Balancer Controller manages AWS Elastic Load Balancers for Kubernetes clusters. Below is the architecture diagram showing how the controller integrates with EKS and AWS services:
Prerequisites
- AWS CLI configured with appropriate permissions
kubectlconfigured to access your EKS clusterhelmv3 installed- EKS cluster with OIDC provider enabled
Step-by-Step Installation Guide
Step 1: Download IAM Policy
Download the IAM policy file required for the AWS Load Balancer Controller:
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.14.0/docs/install/iam_policy.jsonStep 2: Create IAM Policy
Create an IAM policy using the downloaded file:
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.jsonNote the Policy ARN from the output - you’ll need it later.
Step 3: Get OIDC Provider ARN
Get your EKS cluster’s OIDC provider ARN:
# Replace with your cluster name and region
CLUSTER_NAME=your-cluster-name
REGION=ap-south-1
aws eks describe-cluster \
--name $CLUSTER_NAME \
--region $REGION \
--query "cluster.identity.oidc.issuer" \
--output textThe output will be something like: https://oidc.eks.ap-south-1.amazonaws.com/id/XXXXXXXXXX
Extract the OIDC ID and construct the ARN:
OIDC_ARN=arn:aws:iam::<account-id>:oidc-provider/oidc.eks.ap-south-1.amazonaws.com/id/XXXXXXXXXX
Step 4: Create Trust Policy File
Create a trust-policy.json file:
cat > trust-policy.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "${OIDC_ARN}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"$(echo ${OIDC_ARN#*:oidc-provider/}):sub": "system:serviceaccount:kube-system:aws-load-balancer-controller"
}
}
}
]
}
EOFNote: Replace ${OIDC_ARN} with your actual OIDC ARN.
Step 5: Create IAM Role
Create the IAM role with the trust policy:
aws iam create-role \
--role-name AWSLoadBalancerControllerRole \
--assume-role-policy-document file://trust-policy.json \
--region ap-south-1Step 6: Attach Policy to Role
Attach the IAM policy to the role:
# Replace with your actual policy ARN
POLICY_ARN=arn:aws:iam::<account-id>:policy/AWSLoadBalancerControllerIAMPolicy
aws iam attach-role-policy \
--role-name AWSLoadBalancerControllerRole \
--policy-arn $POLICY_ARN \
--region ap-south-1Step 7: Create Kubernetes Service Account
Create a ServiceAccount with the IAM role annotation:
cat > service-account.yaml << EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: aws-load-balancer-controller
namespace: kube-system
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/AWSLoadBalancerControllerRole
EOF
kubectl apply -f service-account.yamlStep 8: Install Controller using Helm
Add and update the EKS Helm repository:
helm repo add eks https://aws.github.io/eks-charts
helm repo update eksInstall the AWS Load Balancer Controller:
# Replace with your cluster name and VPC ID
CLUSTER_NAME=your-cluster-name
VPC_ID=vpc-xxxxxxxx
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=$CLUSTER_NAME \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set vpcId=$VPC_ID \
--version 1.13.0Step 9: Verify Installation
Check if the controller pods are running:
kubectl -n kube-system get pods -l app.kubernetes.io/instance=aws-load-balancer-controllerCheck the controller logs:
kubectl -n kube-system logs -f --selector app.kubernetes.io/instance=aws-load-balancer-controllerVerification and Testing
Test with a Sample Application
Create a test deployment and service:
cat > test-app.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-app
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: test-app
template:
metadata:
labels:
app: test-app
spec:
containers:
- name: app
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: test-app
namespace: default
spec:
selector:
app: test-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-app
namespace: default
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-app
port:
number: 80
EOF
kubectl apply -f test-app.yamlCheck if the ALB is provisioned:
kubectl get ingress -n default -wTroubleshooting
Common Issues and Solutions
-
Controller pods not starting:
# Check pod events kubectl -n kube-system describe pod -l app.kubernetes.io/instance=aws-load-balancer-controller # Check IAM role permissions aws iam simulate-principal-policy \ --policy-source-arn arn:aws:iam::<account-id>:role/AWSLoadBalancerControllerRole \ --action-names elasticloadbalancing:CreateLoadBalancer -
Ingress not provisioning ALB:
# Check controller logs kubectl -n kube-system logs -f --selector app.kubernetes.io/instance=aws-load-balancer-controller # Check ingress events kubectl describe ingress <ingress-name> -
Subnet tags missing: Ensure your subnets have the correct tags:
# For public subnets aws ec2 create-tags --resources subnet-xxx --tags Key=kubernetes.io/role/elb,Value=1 # For private subnets aws ec2 create-tags --resources subnet-yyy --tags Key=kubernetes.io/role/internal-elb,Value=1
Cleanup
To remove the AWS Load Balancer Controller:
# Uninstall Helm chart
helm uninstall aws-load-balancer-controller -n kube-system
# Delete ServiceAccount
kubectl delete -f service-account.yaml
# Detach and delete IAM role
aws iam detach-role-policy \
--role-name AWSLoadBalancerControllerRole \
--policy-arn $POLICY_ARN
aws iam delete-role --role-name AWSLoadBalancerControllerRole
# Delete IAM policy
aws iam delete-policy --policy-arn $POLICY_ARN
# Delete downloaded files
rm -f iam_policy.json trust-policy.json service-account.yaml test-app.yaml