EKS simplified on EC2 Graviton2 instances

Amazon Web Services (AWS) and Kubernetes (K8s) have proven to be a powerful combination, with more K8s users also using Amazon Elastic Kubernetes Service (EKS) more than any other Kubernetes managed service. With EKS, users are able to benefit from the agility and scalability of Kubernetes on AWS without having to manage the K8s control plane. Paired with Ocean by Spot, users are able to abstract away infrastructure management as well. Ocean provides a full  data plane management platform creating a serverless container experience. 

Powering all this is the EC2 instances provisioned by AWS, who are gradually making available a new generation of EC2 Graviton instances, which allow for more applications to run without the need for more CPU cores and memory, providing an ideal environment for fast-scaling applications.

In this guide, you will learn:

EC2 Graviton

Custom built by AWS, and exclusively for the cloud, these EC2 instances run on an Arm architecture processor (as opposed to X86 architecture). Arm architecture is gaining popularity with many enterprises, including Apple who has plans to adopt it for its next generation of Macbooks.  The first generation of these Arm-based instances—the A1 instance family—was introduced two years ago and AWS Graviton2 will now power M6g, C6g, and R6g instance family types. These instances promise better price/performance compared with the M5 instance types, and when tested against CPU intensive workloads did result in faster performance and less costs. With the addition of these compute choices, users are better able to utilize their resources more efficiently and match the right type of compute to the right workload, making these instances especially beneficial to Kubernetes and EKS users. In fact, EKS provides support for Arm instances with modifications of AWS-VPC-CNI, CoreDNS, and kube-proxy components.

Learn more in our guide on EKS on EC2 Graviton instances.

Building multi-architecture Docker images

Once EC2 Arm instances have been added to the EKS cluster, some modifications have to be made to the docker build process in order to utilize the worker nodes running on these new instances. When building the docker image, an image should be built and tagged for every hardware architecture that is being run (e.g. my-docker-image:arm-v1, my-docker-image:x86-v1, my-docker-image:arm-v1.1). For Ocean users, that means that all of their Docker images (alongside with Ocean K8s controller) need to be configured to run on the Gravition Arm-based instance.

Multiple deployment files per architecture also need to be created to run the “right” image (built for the right architecture) on the target instance. Luckily, Docker released a new set of build tools that enable users to create a single docker image with multiple architectures in it. When the Docker daemon runs a container from that image, the daemon will pull only the needed layers of that docker image according to the instance architecture. 

Ocean by Spot

A fully automated solution for managing the Kubernetes data plane (i.e. Kubernetes worker nodes), Ocean by Spot implements and automates the concept of container-driven auto-scaling, where infrastructure is scaled to meet pod requirements. Via its K8s controller, Ocean continuously monitors and reports pod metrics for resource requests and allocations, and subsequently scales infrastructure to the right size and configuration. 

To enable Ocean users to leverage the new EC2 Graviton instances within their EKS clusters, Spot has put together the guidelines below. 

  1. Build an EKS cluster with one node as described in the following guide: https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html
    • Make sure you’ve launched an instance and that it is connected to your EKS cluster, and that instance is of arm64 architecture.
    • Use the following command which should return the value of “arm64” specifying that the instance is arm64 based:
      kubectl get node -o jsonpath='{.items[*].status.nodeInfo.architecture}'
  2. Sample application with a Multi-Arch image. A simple python flask HTTP responder is used and a multi-architecture docker image is created from it. See https://github.com/tsahiduek/flask-http for more information
  3. Connect your AWS account to Spot SaaS platform

Connecting Ocean to the EKS cluster

In order for the K8s controller in Ocean to run on a Graviton arm-based instance, the ‘docker buildx’ tool is used to generate the multi-architecture docker image needed. The docker image can be found on tduek/kubernetes-cluster-controller:multiarch in Docker hub.

To create your own Ocean cluster for EC2 Graviton instances:

Create Ocean Log in to your Spot console, move over to the Ocean → Cloud Clusters tab and press the Create Cluster:

kubernetes, aws eks, graviton ec2

Choose the “Migrate Worker Node” option.

kubernetes, aws eks, graviton ec2

Name the cluster ‘arm-cluster’, as well as the cluster identifier field.

Choose the Region where your cluster had been created.

In the ‘Import From’ field, choose ‘Instance’ and type the instance ID which had been created as part of the EKS creation process described above.

In the next part, we need to choose only EC2 Graviton instances. Click on the ‘Customize’ button under ‘Machine Types’ and un-select all instance types except A1 instances.

All other configurations (VPC, subnets, AMI, UserData, etc…) are automatically imported from the running instance.

kubernetes, aws eks, graviton ec2

The next step is to install Ocean-Kubernetes-Controller as described above. Instead of using the script that is shown in the UI, use the following custom script. Replace the placeholders with appropriate values (Spot token and Spot account – this can be taken from the UI). The reason for this modification is because of the arm supported deployment image.

kubernetes, aws eks, graviton ec2

The output of this script should look like this:

kubernetes, aws eks, graviton ec2

After a few seconds, you can click on the ‘Test Connectivity’ button and verify that the controller is running properly and all configurations successfully created.

kubernetes, aws eks, graviton ec2

Click on the create button and verify that the cluster created successfully

kubernetes, aws eks, graviton ec2

After about a minute, you can see that a new instance had been created by Ocean, which is of the lifecycle of Spot and is part of the A1 instance-type family.

From here, you can successfully drain the single on-demand node, and let Ocean manage all infrastructure (data plane) of your arm-based EKS cluster.

kubernetes, aws eks, graviton ec2

Deploy sample application

As described above, a super simple flask python application is used. The docker image is built using the ‘docker buildx’ new tool (see Makefile in that repo). Use the following command file to deploy this application in your cluster:

kubectl apply

-f https://raw.githubusercontent.com/tsahiduek/flask-http/master/K8s/deployment.yaml

As you can see, we have one pod in a Running state, with one node in the cluster.

Let’s simulate a scale of our application. Use the following command to simulate a scale for our deployment

kubectl scale deployment flask-http --replicas=4

Running kubectl get pods shows that there are pods in a Pending state because there is insufficient Cpu in the cluster:

Ocean instantaneously monitors the pending pods and reacts with automatic scaling events.

kubernetes, aws eks, graviton ec2

After about 45 seconds, the new worker nodes are launched and registered to the cluster, which can now take advantage of the newly improved Graviton instances while users continue to focus on their applications while Ocean manages infrastructure.