This guide will walk you through setting up an Amazon EKS cluster using eksctl, deploying the AWS Load Balancer Controller, and running a sample web application with versioned frontend deployments and dynamic routing via ALB Ingress.
eksctl create cluster \
--version=1.31 \
--name=Cluster-1 \
--nodes=1 \
--node-type=t2.medium \
--ssh-public-key="cloudacademylab" \
--region=us-west-2 \
--zones=us-west-2a,us-west-2b,us-west-2c \
--node-volume-type=gp2 \
--node-volume-size=20eksctl utils associate-iam-oidc-provider \
--region us-west-2 \
--cluster Cluster-1 \
--approvecurl -o /tmp/iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file:///tmp/iam_policy.jsoneksctl create iamserviceaccount \
--cluster Cluster-1 \
--namespace kube-system \
--name aws-load-balancer-controller \
--attach-policy-arn arn:aws:iam::<ACCOUNT_ID>:policy/AWSLoadBalancerControllerIAMPolicy \
--override-existing-serviceaccounts \
--approvepushd /tmp
curl -o helm-v3.12.1-linux-amd64.tar.gz https://get.helm.sh/helm-v3.9.2-linux-amd64.tar.gz
tar -xvf helm-v3.12.1-linux-amd64.tar.gz
sudo mv linux-amd64/helm /usr/local/bin/helm
popd
helm repo add eks https://aws.github.io/eks-charts
helm repo updateVPC_ID=$(aws eks describe-cluster \
--name Cluster-1 \
--query "cluster.resourcesVpcConfig.vpcId" \
--output text)
echo $VPC_ID
kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller/crds?ref=master"
helm install \
aws-load-balancer-controller \
eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=Cluster-1 \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set image.tag=v2.5.2 \
--set region=us-west-2 \
--set vpcId=${VPC_ID} \
--version=1.5.3
kubectl -n kube-system rollout status deployment aws-load-balancer-controller
kubectl describe deployment -n kube-system aws-load-balancer-controllerkubectl create ns webapp
kubectl config set-context $(kubectl config current-context) --namespace=webapp
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: webapp-cfg-v1
namespace: webapp
labels:
version: v1
data:
message: "CloudAcademy.v1.0.0"
bgcolor: "yellow"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: webapp-cfg-v2
namespace: webapp
labels:
version: v2
data:
message: "CloudAcademy.v2.0.0"
bgcolor: "cyan"
EOF# v1
kubectl apply -f frontend-v1.yaml
# v2
kubectl apply -f frontend-v2.yaml
kubectl rollout status deployment frontend-v1
kubectl rollout status deployment frontend-v2kubectl apply -f service-v1.yaml
kubectl apply -f service-v2.yaml
kubectl get svc,epcat << EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend
namespace: webapp
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
rules:
- http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: frontend-v1
port:
number: 80
EOFALB_FQDN=$(kubectl -n webapp get ingress frontend -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
echo ALB_FQDN=$ALB_FQDN
until nslookup $ALB_FQDN >/dev/null 2>&1; do sleep 2 && echo waiting for DNS to propagate...; done
until curl --silent $ALB_FQDN | grep CloudAcademy >/dev/null 2>&1; do sleep 2 && echo waiting for ALB to register targets...; done
curl -I $ALB_FQDN
echo "READY... Visit: http://$ALB_FQDN"Create annotations.config
cat > annotations.config << EOF
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/actions.forward-tg-svc1: >
{"type":"forward","forwardConfig":{"targetGroups":[{"serviceName":"frontend-v1","servicePort":"80"}]}}
alb.ingress.kubernetes.io/actions.forward-tg-svc2: >
{"type":"forward","forwardConfig":{"targetGroups":[{"serviceName":"frontend-v2","servicePort":"80"}]}}
alb.ingress.kubernetes.io/actions.custom-path1: >
{"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"200","messageBody":"follow the white rabbit..."}}
EOFGenerate and Apply Ingress Config
ANNOTATIONS="$(cat annotations.config)"
cat > ingress.annotations.yaml << EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend
namespace: webapp
annotations:
$ANNOTATIONS
spec:
rules:
- http:
paths:
- path: /yellow
pathType: Exact
backend:
service:
name: forward-tg-svc1
port:
name: use-annotation
- path: /cyan
pathType: Exact
backend:
service:
name: forward-tg-svc2
port:
name: use-annotation
- path: /white
pathType: Exact
backend:
service:
name: custom-path1
port:
name: use-annotation
EOF
kubectl apply -f ingress.annotations.yamlALB_FQDN=$(kubectl -n webapp get ingress frontend -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
echo "V1: http://$ALB_FQDN/yellow"
echo "V2: http://$ALB_FQDN/cyan"
echo "Custom: http://$ALB_FQDN/white"🎉 Your Amazon EKS cluster is now up and running with multiple frontend versions and a dynamic ALB Ingress router!
Note: Replace <ACCOUNT_ID> with your actual AWS Account ID wherever necessary.