Step By Step Guide to Setup Elastic Kubernetes Service with Application Load Balancer on Amazon Web Service

Hello, EKS & ALB are two different services of Amazon Web Service(AWS). In this blog, we are explaining how to setup EKS with ALB on AWS account. There are some steps to setup EKS with ALB using a command line. And we are giving a simple code for testing EKS  with ALB on ubuntu. Using ALB, we can easily open the application & manage the traffic on servers.

Step 1: First, setup the EKS Cluster & Node group on AWS account so click on link https://www.hackerxone.com/2021/08/25/steps-to-create-amazon-eks-node-group-on-amazon-web-service-aws/

  • Attached the following policies on Node-group Role.

AmazonEKS_CNI_Policy
AWSAppMeshFullAccess

Step 2: Launch a instance (master instance).Master instance controls the eks cluster & node-group.

  • Login in to Master instance using ssh.

ssh -i ".pem file" instance-user-name@public-dns-name
or
ssh -i ".pem file" instance-user-name@public-ip-address

  • Update the system.

apt-get update

  • Install awscli on master instance.Run the following commands:

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
apt install unzip
unzip awscliv2.zip
./aws/install

  • Configure the awscli.

aws configure

  • Provide the access-key & secret key from aws account.
  • Update the packages.

apt-get update

  • Install kubectl.

curl -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.21.2/2021-07-05/bin/linux/amd64/kubectl
openssl sha1 -sha256 kubectl
chmod +x ./kubectl
mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin

  • Now,Install eksctl.

curl --silent –location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin

  • Check eksctl version.

eksctl version

  • Check the status of Cluster.

aws eks --region region-name describe-cluster --name cluster-name --query cluster.status

  • Create or update kubeconfig for cluster.

aws eks --region region-name update-kubeconfig --name cluster-name

  • Create an OIDC (OpenID Connect) identity provider for cluster.

eksctl utils associate-iam-oidc-provider region region-name --cluster cluster-name --approve

Step 3: Now,Run the following command.

  • To list EKS clusters.

eksctl get cluster

  • To list NodeGroups in a cluster.

eksctl get nodegroup –cluster=<clusterName>

  • To list Nodes in current kubernetes cluster.

kubectl get nodes -o wide

  • kubectl context should be automatically changed to new cluster.

kubectl config view --minify

  • To list Service Accounts.

kubectl get sa -n kube-system

Step 4: Create a Kubernetes service account named alb-ingress-controller in the kube-system namespace.

  • Create ClusterRole, ClusterRoleBinding & ServiceAccount.

kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/master/docs/examples/rbac-role.yaml

  • Now Again list Service Accounts.

kubectl get sa -n kube-system

  • To describe Service Account alb-ingress-controller.

kubectl describe sa alb-ingress-controller -n kube-system

Step 5: Now, Create IAM Policy for ALB Ingress Controller.

  • Create IAM Policy using command.

aws iam create-policy --policy-name ALBIngressControllerIAMPolicy \
--policy-document https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/master/docs/examples/iam-policy.json

  • Create IAM policy manually.
  • Go to IAM Policy on AWS account.
  • Create a new policy & Click on Json format.
  • Open the link in Browser.

https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/master/docs/examples/iam-policy.json

  • Copy the content.
  • Paste on New Policy Json Format.
  • Provide the Policy name (ALBIngressControllerIAMPolicy).
  • Click on Create policy.
  • Then,Attached to the Node-Group Role.

Step 6:Create an IAM role for the ALB Ingress Controller and attach the role to the service account.

  • Create service account.

eksctl create iamserviceaccount \
--region region-name \
--name alb-ingress-controller \
--namespace kube-system \
--cluster cluster-name \
--attach-policy-arn created-policy-role-arn \
--override-existing-serviceaccounts \
--approve

  • Check the service-account.

eksctl get iamserviceaccount --cluster cluster-name

  • Now,Go to Cloudformation on aws account.
  • Here,One stack has been created.
  • To describe Service Account alb-ingress-controller.

kubectl describe sa alb-ingress-controller -n kube-system

Step 7: Now,Deploy ALB Ingress Controller.

kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress- controller/master/docs/examples/alb-ingress-controller.yaml

  • Verify Deployment.

kubectl get deploy -n kube-system

  • Run the following command to open the alb-ingress-controller file.

kubectl edit deployment.apps/alb-ingress-controller -n kube-system

  • Edit the following lines:
  • Provide the cluster-name.

# Template file
spec:
containers:
- args:
- --ingress-class=alb
- --cluster-name=cluster-name

  • To verify ALB Ingress Controller is running or not.

kubectl get pods -n kube-system

  • T0 verify logs.

kubectl logs -f $(kubectl get po -n kube-system | egrep -o 'alb-ingress-controller-[A-Za-z0-9-]+') -n kube-system

Step 8: Now Create a .yaml file.(Create a namespace, deployment, service & alb load balancer).

vim text.yaml

  • Add the following lines.
  • Provide a docker-image-uri.

---
apiVersion: v1
kind: Namespace
metadata:
name: apache-1
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: apache-1
name: deployment-1
spec:
selector:
matchLabels:
app.kubernetes.io/name: app-1
replicas: 2
template:
metadata:
labels:
app.kubernetes.io/name: app-1
spec:
containers:
- image: docker-image-uri
imagePullPolicy: Always
name: app-1
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: apache-1
name: service-1
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
---
app.kubernetes.io/name: app-1
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
namespace: apache-1
name: ingress-1
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: /*
backend:
serviceName: service-1
servicePort: 80

OR

  • Create a folder & go to created directory.

cd directory-name

  • Now,create a different-different files.One file for deployment.yaml,one for service.yaml & one for ALB.yaml file.
  • Open Deployment.yaml file.

---
apiVersion: v1
kind: Namespace
metadata:
name: apache-1
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: apache-1
name: deployment-1
spec:
selector:
matchLabels:
app.kubernetes.io/name: app-1
replicas: 2
template:
metadata:
labels:
app.kubernetes.io/name: app-1
spec:
containers:
- image: 683716129767.dkr.ecr.sa-east-1.amazonaws.com/test:latest
imagePullPolicy: Always
name: app-1
ports:
- containerPort: 80

  • Open Service.yaml file.

---
apiVersion: v1
kind: Service
metadata:
namespace: apache-1
name: service-1
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
app.kubernetes.io/name: app-1

  • Open ALB.yaml file.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
namespace: apache-1
name: ingress-1
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: /*
backend:
serviceName: service-1
servicePort: 80

  • Run the .yaml file or folder.

kubectl apply -f folder-name
or
kubectl apply -f file-name.yaml

  • Verify App is UP and Running.

kubectl get pods -n namespace-name
kubectl logs -f <pod-name>

  • Check running service.

kubectl get service/service-name -n namespace-name

  • Check deployment status.

Kubectl get deployment/deployment-name -n namespace-name

  • Get List of Ingress.

kubectl get ingress/alb-name -n namespace-name

  • Verify ALB Ingress Controller logs.

kubectl logs -f $(kubectl get po -n kube-system | egrep -o 'alb-ingress-controller-[A-Za-z0-9-]+') -n kube-system

  • If we are getting this Error.

E0507 15:40:13.134304 1 controller.go:217] kubebuilder/controller "msg"="Reconciler error" "error"="failed to build LoadBalancer configuration due to failed to resolve 2 qualified subnet with at least 8 free IP Addresses for ALB. Subnets must contains these tags: 'kubernetes.io/cluster/eksdemo1': ['shared' or 'owned'] and 'kubernetes.io/role/elb': ['' or '1']. See https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/controller/config/#subnet-auto-discovery for more details. Resolved qualified subnets: '[]'" "controller"="alb-ingress-controller" "request"={"Namespace":"default","Name":"ingress-usermgmt-restapp-service"}

Soluation:

  • Go to VPC -> EKS VPC -> Subnets -> For both Public Subnets, add the following tag:

Name = value
kubernetes.io/cluster/eksdemo1 = shared
kubernetes.io/role/elb = 1

  • After this,Check ALB on AWS account & Run the Application using ALB DNS.

Leave a Reply