Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save misskecupbung/f9c5436d0d73a13f9ac2123e0a54d7af to your computer and use it in GitHub Desktop.

Select an option

Save misskecupbung/f9c5436d0d73a13f9ac2123e0a54d7af to your computer and use it in GitHub Desktop.

Amazon EKS + AWS Load Balancer Controller

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.


1. EKS Cluster Setup

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=20

2. AWS Load Balancer Controller Setup

2.1 Associate IAM OIDC Provider

eksctl utils associate-iam-oidc-provider \
  --region us-west-2 \
  --cluster Cluster-1 \
  --approve

2.2 Create IAM Policy

curl -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.json

2.3 Create IAM Service Account

eksctl 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 \
  --approve

2.4 Install Helm & Add Repository

pushd /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 update

2.5 Install Load Balancer Controller

VPC_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-controller

3. Namespace and ConfigMaps

kubectl 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

4. Deploy Applications

4.1 Deploy Frontend v1 and v2

# 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-v2

4.2 Create Services

kubectl apply -f service-v1.yaml
kubectl apply -f service-v2.yaml
kubectl get svc,ep

5. Ingress Controller (ALB)

5.1 Basic Ingress

cat << 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
EOF

5.2 Verify ALB

ALB_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"

5.3 Advanced Ingress Routing

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..."}}
EOF

Generate 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.yaml

5.4 Access Final Routes

ALB_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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment