Skip to content

EKS Fargate Profiles - Basics

Step-01: What are we going to learn?

  • Assumptions:
  • We already havea EKS Cluster whose name is eksdemo1 created using eksctl
  • We already have a Managed Node Group with private networking enabled with two worker nodes
  • We are going to create a fargate profile using eksctl on our existing EKS Cluster eksdemo1
  • We are going to deploy a simple workload
  • Deployment: Nginx App 1
  • NodePort Service: Nginx App1
  • Ingress Service: Application Load Balancer
  • Ingress manifest going to have a additional annotation related to target-type: ip as these are going to be fargate workloads we are not going to have Dedicated EC2 Worker Node - Node Ports
  • Refer Presentation from slide 116 onwards

Image

Kubernetes Manifests

#01-namespace.yml
apiVersion: v1
kind: Namespace
metadata: 
  name: fp-dev
#02-Nginx-App1-Deployment-and-NodePortService.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app1-nginx-deployment
  labels:
    app: app1-nginx
  namespace: fp-dev 
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app1-nginx
  template:
    metadata:
      labels:
        app: app1-nginx
    spec:
      containers:
        - name: app1-nginx
          image: stacksimplify/kube-nginxapp1:1.0.0
          ports:
            - containerPort: 80
          resources:
            requests:
              memory: "128Mi"
              cpu: "500m"
            limits:
              memory: "500Mi"
              cpu: "1000m"                         
---
apiVersion: v1
kind: Service
metadata:
  name: app1-nginx-nodeport-service
  labels:
    app: app1-nginx
  namespace: fp-dev  
  annotations:
#Important Note:  Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer    
    alb.ingress.kubernetes.io/healthcheck-path: /app1/index.html
spec:
  type: NodePort
  selector:
    app: app1-nginx
  ports:
    - port: 80
      targetPort: 80
#03-ALB-Ingress-SSL-Redirect-with-ExternalDNS.yml
# Annotations Reference:  https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-usermgmt-restapp-service
  labels:
    app: usermgmt-restapp
  namespace: fp-dev     
  annotations:
    # Ingress Core Settings  
    kubernetes.io/ingress.class: "alb"
    alb.ingress.kubernetes.io/scheme: internet-facing
    # Health Check Settings
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTP 
    alb.ingress.kubernetes.io/healthcheck-port: traffic-port
    #Important Note:  Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer    
    #alb.ingress.kubernetes.io/healthcheck-path: /usermgmt/health-status
    alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15'
    alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
    alb.ingress.kubernetes.io/success-codes: '200'
    alb.ingress.kubernetes.io/healthy-threshold-count: '2'
    alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
    ## SSL Settings
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-1:180789647333:certificate/9f042b5d-86fd-4fad-96d0-c81c5abc71e1
    #alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS-1-1-2017-01 #Optional (Picks default if not used)    
    # SSL Redirect Setting
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'   
    # External DNS - For creating a Record Set in Route53
    external-dns.alpha.kubernetes.io/hostname: fpdev.kubeoncloud.com      
    # For Fargate
    alb.ingress.kubernetes.io/target-type: ip    
spec:
  rules:
    - http:
        paths:
          - path: /* # SSL Redirect Setting
            backend:
              serviceName: ssl-redirect
              servicePort: use-annotation            
          - path: /*
            backend:
              serviceName: app1-nginx-nodeport-service
              servicePort: 80                                   
# Important Note-1: In path based routing order is very important, if we are going to use  "/*", try to use it at the end of all rules.         

Step-02: Pre-requisites

Pre-requisite Note about eksctl CLI

  • eksctl will have continuous releases with new feature additions to it. Its always good to be on latest version of eksctl.
  • You can upgrade to latest version using below command on Mac
  • Currently highly evolving space (continuous features and new releases) from Kubernetes in AWS is eksctl and Fargate.
  • eksctl Releases URL: https://github.com/weaveworks/eksctl/releases
    # Check version
    eksctl version
    
    # Update eksctl on mac
    brew upgrade eksctl && brew link --overwrite eksctl
    
    # Check version
    eksctl version
    

Pre-requisite check about ALB Ingress Controller & external-dns

  • We need to have the below two listed components to be already running on our NodeGroup before deploying our application on fargate.
  • ALB Ingress Controller
  • External DNS
  • For our application, in addition to just deploying it we are going to access it via DNS registed url fpdev.kubeoncloud.com
# Get Current Worker Nodes in Kubernetes cluster
kubectl get nodes -o wide

# Verify Ingress Controller Pod running
kubectl get pods -n kube-system

# Verify external-dns Pod running
kubectl get pods

Best Selling AWS EKS Kubernetes Course on Udemy

Image

Start Learning Now!

Step-03: Create Fargate Profile on cluster eksdemo1

Create Fargate Profile

# Get list of Fargate Profiles in a cluster
eksctl get fargateprofile --cluster eksdemo1

# Template
eksctl create fargateprofile --cluster <cluster_name> \
                             --name <fargate_profile_name> \
                             --namespace <kubernetes_namespace>


# Replace values
eksctl create fargateprofile --cluster eksdemo1 \
                             --name fp-demo \
                             --namespace fp-dev

Output

[ℹ]  Fargate pod execution role is missing, fixing cluster stack to add Fargate resources
[ℹ]  checking cluster stack for missing resources
[ℹ]  cluster stack is missing resources for Fargate
[ℹ]  adding missing resources to cluster stack
[ℹ]  re-building cluster stack "eksctl-eksdemo1-cluster"
[ℹ]  updating stack to add new resources [FargatePodExecutionRole] and outputs [FargatePodExecutionRoleARN]
[ℹ]  creating Fargate profile "fp-demo" on EKS cluster "eksdemo1"
[ℹ]  created Fargate profile "fp-demo" on EKS cluster "eksdemo1"

Step-04: Review NGINX App1 & Ingress Manifests

  • We are going to deploy a simple NGINX App1 with Ingress Load Balancer
  • We cannot use Worker Node Node Ports for Fargate Pods for two reasons
  • Fargate Pods are created in Private Subnets, so no access to internet to access
  • Fargate Pods are created on random worker nodes whose information is unknown to us to use NodePort Service
  • But in our case, we are in mixed environment with Node Groups and Fargate, if we create a NodePort service, it will create the service with Node Group EC2 Worker Nodes Ports and it will work but when we delete those Node Groups, we will have an issue.
  • Always recommended to use alb.ingress.kubernetes.io/target-type: ip in ingress manifest for Fargate workloads

Create Namespace Manifest

  • This namespace manifest should match the one with we have created the Fargate Profile namespace value fp-dev
    apiVersion: v1
    kind: Namespace
    metadata: 
      name: fp-dev
    

Update All other manifests with namespace tag in metadata section

  namespace: fp-dev 

Update All Deployment Manifests with Resources in Pod Template

  • In Fargate, it is super highly recommended to provide the resources.requests, resources.limits about cpu and memory. Almost you can make it mandatory.
  • This will help Fargate to schedule a Fargate Host accordingly.
  • As fargate follows 1:1 ratio Host:Pod, one pod per host concept, we defining resources section in pod template (Deployment pod template spec) should be our mandatory option.
  • Even if we forget to define resources in our Deployment Pod Template, low memory using pods like NGINX will come up, high memory using Apps like Spring Boot REST APIs will keep restarting continuously due to unavailable resources.
              resources:
                requests:
                  memory: "128Mi"
                  cpu: "500m"
                limits:
                  memory: "500Mi"
                  cpu: "1000m"    
    

Update Ingress Manifest

  • As we are running our pods on Fargate Serverless, we need to change our target-type to IP as there is no dedicated EC2 worker nodes concept in Fargate.
  • Important Note: When we are using same ingress in mixed mode deployments Node Groups & Fargate we can use this annotation at service level.
        # For Fargate
        alb.ingress.kubernetes.io/target-type: ip    
    
  • Also update the DNS Names
        # External DNS - For creating a Record Set in Route53
        external-dns.alpha.kubernetes.io/hostname: fpdev.kubeoncloud.com   
    

Step-05: Deploy Workload to Fargate

# Deploy 
kubectl apply -f kube-manifests/

# List Namespaces
kubectl get ns

# List Pods from fpdev namespace
kubectl get pods -n fp-dev -o wide

# List Worker Nodes
kubectl get nodes -o wide

# List Ingress
kubectl get ingress -n fp-dev

Step-06: Access Application & Test

# Access Application
http://fpdev.kubeoncloud.com/app1/index.html

Step-07: Delete Fargate Profile

# Get list of Fargate Profiles in a cluster
eksctl get fargateprofile --cluster eksdemo1

# Delete Fargate Profile
eksctl delete fargateprofile --cluster <cluster-name> --name <Fargate-Profile-Name> --wait
eksctl delete fargateprofile --cluster eksdemo1 --name fp-demo --wait

Step-08: Verify NGINX App1 got scheduled on Managed Node Group

  • After fargate profile deletions, apps running on fargate will be scheduled on Node Groups if they exists if not will go to pending state
    # List Pods from fpdev namespace
    kubectl get pods -n fp-dev -o wide
    

Step-09: Clean-up

# Delete
kubectl delete -f kube-manifests/

Free Courses

Image

Start with our Getting Started Free Courses!

References

  • https://eksctl.io/usage/fargate-support/
  • https://docs.aws.amazon.com/eks/latest/userguide/fargate.html
  • https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#annotations
  • https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#traffic-routing

How ALB Ingress Controller Works?

AWS ALB Ingress Installation

AWS ALB Ingress Implementation Basics

Subscribe to our Youtube Channel