Ingress Controller

Ingress Controllers

In order for the Ingress resource to work, the cluster must have an ingress controller running.

Unlike other types of controllers which run as part of the kube-controller-manager binary, Ingress controllers are not started automatically with a cluster.

AWS Load Balancer Controller

The AWS ALB Ingress Controller has been rebranded to AWS Load Balancer Controller.

AWS Load Balancer Controller is a controller to help manage Elastic Load Balancers for a Kubernetes cluster.

In this chapter we will focus on the Application Load Balancer.

AWS Elastic Load Balancing Application Load Balancer (ALB) is a popular AWS service that load balances incoming traffic at the application layer (layer 7) across multiple targets, such as Amazon EC2 instances, in multiple Availability Zones.

ALB supports multiple features including:

  • host or path based routing
  • TLS (Transport Layer Security) termination, WebSockets
  • HTTP/2
  • AWS WAF (Web Application Firewall) integration
  • integrated access logs, and health checks

Deploy the AWS Load Balancer Controller

Prerequisites

We will verify if the AWS Load Balancer Controller version has been set

if [ ! -x ${LBC_VERSION} ]
  then
    tput setaf 2; echo '${LBC_VERSION} has been set.'
  else
    tput setaf 1;echo '${LBC_VERSION} has NOT been set.'
fi

If the result is ${LBC_VERSION} has NOT been set., click here for the instructions.

We will use Helm to install the ALB Ingress Controller.

Check to see if helm is installed:

helm version --short

If Helm is not found, click installing Helm CLI for instructions.

Create IAM OIDC provider

eksctl utils associate-iam-oidc-provider \
    --region ${AWS_REGION} \
    --cluster eksworkshop-eksctl \
    --approve

Learn more about IAM Roles for Service Accounts in the Amazon EKS documentation.

Create an IAM policy called

Create a policy called AWSLoadBalancerControllerIAMPolicy

aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json

Create a IAM role and ServiceAccount

eksctl create iamserviceaccount \
  --cluster eksworkshop-eksctl \
  --namespace kube-system \
  --name aws-load-balancer-controller \
  --attach-policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy \
  --override-existing-serviceaccounts \
  --approve

Install the TargetGroupBinding CRDs

kubectl apply -k github.com/aws/eks-charts/stable/aws-load-balancer-controller/crds?ref=master

kubectl get crd

Deploy the Helm chart

The helm chart will deploy from the eks repo

helm repo add eks https://aws.github.io/eks-charts

helm upgrade -i aws-load-balancer-controller \
    eks/aws-load-balancer-controller \
    -n kube-system \
    --set clusterName=eksworkshop-eksctl \
    --set serviceAccount.create=false \
    --set serviceAccount.name=aws-load-balancer-controller \
    --set image.tag="${LBC_VERSION}"

kubectl -n kube-system rollout status deployment aws-load-balancer-controller

Deploy Sample Application

Now let’s deploy a sample 2048 game into our Kubernetes cluster and use the Ingress resource to expose it to traffic:

Deploy 2048 game resources:

export EKS_CLUSTER_VERSION=$(aws eks describe-cluster --name eksworkshop-eksctl --query cluster.version --output text)

if [ "`echo "${EKS_CLUSTER_VERSION} < 1.19" | bc`" -eq 1 ]; then     
    curl -s https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/examples/2048/2048_full.yaml \
    | sed 's=alb.ingress.kubernetes.io/target-type: ip=alb.ingress.kubernetes.io/target-type: instance=g' \
    | kubectl apply -f -
fi

if [ "`echo "${EKS_CLUSTER_VERSION} >= 1.19" | bc`" -eq 1 ]; then     
    curl -s https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/examples/2048/2048_full_latest.yaml \
    | sed 's=alb.ingress.kubernetes.io/target-type: ip=alb.ingress.kubernetes.io/target-type: instance=g' \
    | kubectl apply -f -
fi

After few seconds, verify that the Ingress resource is enabled:

kubectl get ingress/ingress-2048 -n game-2048

You should be able to see the following output


NAME           HOSTS   ADDRESS                                                                  PORTS   AGE
ingress-2048   *       k8s-game2048-ingress2-8ae3738fd5-251279030.us-east-2.elb.amazonaws.com   80      6m20s

You can find more information on the ingress with this command:

export GAME_INGRESS_NAME=$(kubectl -n game-2048 get targetgroupbindings -o jsonpath='{.items[].metadata.name}')

kubectl -n game-2048 get targetgroupbindings ${GAME_INGRESS_NAME} -o yaml

output


apiVersion: elbv2.k8s.aws/v1beta1
kind: TargetGroupBinding
metadata:
  creationTimestamp: "2020-10-24T20:16:37Z"
  finalizers:
  - elbv2.k8s.aws/resources
  generation: 1
  labels:
    ingress.k8s.aws/stack-name: ingress-2048
    ingress.k8s.aws/stack-namespace: game-2048
  name: k8s-game2048-service2-0e5fd48cc4
  namespace: game-2048
  resourceVersion: "292608"
  selfLink: /apis/elbv2.k8s.aws/v1beta1/namespaces/game-2048/targetgroupbindings/k8s-game2048-service2-0e5fd48cc4
  uid: a1e3567e-429d-4f3c-b1fc-1131775cb74b
spec:
  networking:
    ingress:
    - from:
      - securityGroup:
          groupID: sg-0f2bf9481b203d45a
      ports:
      - protocol: TCP
  serviceRef:
    name: service-2048
    port: 80
  targetGroupARN: arn:aws:elasticloadbalancing:us-east-2:197520326489:targetgroup/k8s-game2048-service2-0e5fd48cc4/4e0de699a21473e2
  targetType: instance
status:
  observedGeneration: 1

Finally, you access your newly deployed 2048 game by clicking the URL generated with these commands

It could take 2 or 3 minutes for the ALB to be ready.

export GAME_2048=$(kubectl get ingress/ingress-2048 -n game-2048 -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')

echo http://${GAME_2048}