Playing with EKS Fargate
The purpose of this tutorial is to deploy a ‘simple’ application to EKS Fargate. In this tutorial, I will try to be practical as possible and deploy ‘httpbin’ application to EKS Fargate.
First, a regular EKS cluster with node groups will be created, then I will add the Fargate profile as ‘play-with-fargate’ namespace and every application deployed to this namespace will use Fargate.
AWS Fargate
AWS Fargate is a technology that provides on-demand, right-sized compute capacity for containers. With AWS Fargate, you don’t have to provision, configure, or scale groups of virtual machines on your own to run containers. You also don’t need to choose server types, decide when to scale your node groups, or optimize cluster packing. You can control which pods start on Fargate and how they run with Fargate profiles. Fargate profiles are defined as part of your Amazon EKS cluster.
httpbin
A simple HTTP Request & Response Service.
Prerequisites
- AWS account with all needed permissions to create EKS cluster
- Installed kubectl and eksctl
- Installed AWS CLI
Let’s provision the EKS cluster
Provision EKS cluster with eksctl to the region: eu-west-3, name: fargate-cluster
eksctl create cluster \
--name fargate-cluster \
--region eu-west-3
kubectl get pods -A
kubectl get nodes
Add Fargate profile to an existing EKS cluster
eksctl create fargateprofile \
--cluster fargate-cluster \
--name play-with-fargate \
--namespace play-with-fargate \
--region eu-west-3
That is what you need to see in AWS Console -> Amazon Container Services, you need to be in the eu-west-3 region.
Let’s test we can deploy applications to EKS Fargate
I will deploy Nginx to ‘play-with-fargate’ namespace:
kubectl create ns play-with-fargate
kubectl create deployment nginx --image=nginx -n play-with-fargate
Took some time to spin up the pod, almost 1 minute to be more precise before deployment status become ‘ContainerCreated’. hmm, I feel some improvements are needed here:-)
Fargate node provisioned on the fly.
We can see Nginx indeed provisioned on Fargate node
Let’s delete the Nginx
kubectl delete deployments nginx -n play-with-fargate
Next, I will deploy AWS Load Balancer Controller, to use ALB ingress with our application and make it externally accessible.
Install AWS Load Balancer Controller to EKS
Based on this workshop: https://www.eksworkshop.com/beginner/180_fargate/prerequisites-for-alb/
Create IAM OIDC provider
This step is required to give IAM permissions to a Fargate pod running in the cluster using the IAM for Service Accounts feature.
eksctl utils associate-iam-oidc-provider \
--region eu-west-3 \
--cluster fargate-cluster \
--approve
Create an IAM policy
The next step is to create the IAM policy that will be used by the AWS Load Balancer Controller. This policy will be later associated to the Kubernetes Service Account and will allow the controller pods to create and manage the ELB’s resources in your AWS account for you.
curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.2.0/docs/install/iam_policy.json
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
rm iam_policy.json
Create an IAM role and ServiceAccount for the Load Balancer controller
First, change ${ACCOUNT_ID} to your account, which you can find in the AWS console on the top -> right side
eksctl create iamserviceaccount \
--cluster fargate-cluster \
--region eu-west-3 \
--namespace kube-system \
--name aws-load-balancer-controller \
--attach-policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy \
--override-existing-serviceaccounts \
--approve
The above command deploys a CloudFormation template that creates an IAM role and attaches the IAM policy to it.
Install the TargetGroupBinding CRDs
kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=master"
Install the AWS Load Balancer Controller
You need your VPC ID first:
aws eks describe-cluster \
--name fargate-cluster \
--region eu-west-3 \
--query "cluster.resourcesVpcConfig.vpcId" \
--output text
Change vpcId before executing the next command.
helm repo add eks https://aws.github.io/eks-charts
helm upgrade -i aws-load-balancer-controller eks/aws-load-balancer-controller \
--set clusterName=fargate-cluster \
--set serviceAccount.create=false \
--set region=eu-west-3 \
--set vpcId=vpc-xxxxx \
--set serviceAccount.name=aws-load-balancer-controller -n kube-system
Verify that the AWS Load Balancer Controller is installed
kubectl get deployment -n kube-system aws-load-balancer-controller
Let’s deploy our application: httpbin
‘httpbin’ will be deployed to ‘play-with-fargate’ namespace
All manifests combined in all-resources.yaml:
apiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
namespace: play-with-fargate
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
namespace: play-with-fargate
labels:
app: httpbin
service: httpbin
spec:
ports:
- name: http
port: 8000
targetPort: 80
selector:
app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
namespace: play-with-fargate
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
template:
metadata:
labels:
app: httpbin
spec:
serviceAccountName: httpbin
containers:
- image: docker.io/kennethreitz/httpbin
name: httpbin
ports:
- containerPort: 80
You can find gist with all commands and manifests here: https://gist.github.com/warolv/e982ccce78a6b78c40cea4227c13912f
kubectl apply -f all-resources.yaml
Let’s connect to httpbin using the port-forwarding
Will use ‘kubectl port-forward’ to get access to httpbin
Looks good:-)
The only thing left is to access this application externally, will use ‘AWS Load Balancer Controller’ we installed and ‘ingress’ manifest.
‘AWS Load Balancer Controller’ will provision ALB on AWS behind the scenes.
Ingress for httpbin
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
name: httpbin-ingress
spec:
rules:
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: httpbin
port:
number: 8000
Provision ALB may take a couple of minutes, be patient.
Success! :-)
annotations: ‘kubernetes.io/ingress.class: alb’ instructs AWS Load Balancer Controller to create ALB on AWS for this application.
alb.ingress.kubernetes.io/scheme: internet-facing instructs AWS Load Balancer Controller to create external LB for this application and not internal.
You can find gist with all commands and manifests here: https://gist.github.com/warolv/e982ccce78a6b78c40cea4227c13912f
In this tutorial, I explained how to add a Fargate profile to an existing EKS cluster, how to deploy ‘httpbin’ application, and to provision AWS Load Balancer Controller to make the application accessible externally.
Thank you for reading, I hope you enjoyed it, see you in the next post.
Please subscribe to my YT channel
If you want to be notified when the next post of this tutorial is published, please follow me on Twitter @warolv.
My medium account: warolv.medium.com