Quickstart: Deploy a web app and store data - Amazon EKS

Quickstart: Deploy a web app and store data

This quickstart tutorial shows the steps to deploy the 2048 game sample application and persist its data on an Amazon EKS cluster using eksctl. eksctl is an infrastructure-as-code utility leveraging AWS CloudFormation, allowing you to set up a fully-functional cluster, complete with all the essential components. These components include an Amazon VPC and an IAM role tailored to provide permissions to the AWS services we’ve defined. As we progress, we’ll walk you through the cluster setup process, incorporating Amazon EKS add-ons to power your cluster with operational capabilities. Finally, you’ll deploy a sample workload with the custom annotations required to fully integrate with AWS services.

In this tutorial

Using the eksctl cluster template that follows, you’ll build an Amazon EKS cluster with managed node groups. It configures the following components:

VPC Configuration

When using the eksctl cluster template that follows, eksctl automatically creates an IPv4 Virtual Private Cloud (VPC) for the cluster. By default, eksctl configures a VPC that addresses all networking requirements, in addition to creating both public and private endpoints.

Instance type

Utilize the t3.medium instance type. This instance type offers a well-balanced combination of compute, memory, and network resources—​ideal for applications with moderate CPU usage that may experience occasional spikes in demand.

Authentication

Establish the IRSA mappings to facilitate communication between Kubernetes pods and AWS services. The template is configured to set up an OpenID Connect (OIDC) endpoint for authentication and authorization. It also establishes a service account for the AWS Load Balancer Controller (LBC), a controller responsible for exposing applications and managing traffic.

Data Persistence

Integrate the AWS EBS CSI Driver managed add-on to ensure the persistence of application data, even in scenarios involving pod restarts or failures. The template is configured to install the add-on and establish a service account

External App Access

Set up and integrate with the AWS Load Balancer Controller (LBC) add-on to expose the 2048 game application, using the LBC to dynamically provision an Application Load Balancer (ALB).

Prerequisites

Before you begin, ensure you have the following prerequisites set up to use Amazon EKS.

Step 1: Configure the cluster

In this section, you’ll create a managed node group-based cluster using t3.medium instances containing two nodes. The configuration includes a service account for AWS Load Balancer Controller (LBC) add-on, and installation of the latest version of the AWS Amazon EBS CSI driver. For all available eksctl add-ons, see Discovering addons in eksctl documentation.

  1. Create a cluster-config.yaml file and paste the following contents into it. Replace region-code with a valid Region, such as us-east-1

    Example output is as follows:

    apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: web-quickstart region: region-code managedNodeGroups: - name: eks-mng instanceType: t3.medium desiredCapacity: 2 iam: withOIDC: true serviceAccounts: - metadata: name: aws-load-balancer-controller namespace: kube-system wellKnownPolicies: awsLoadBalancerController: true addons: - name: aws-ebs-csi-driver wellKnownPolicies: # Adds an IAM service account ebsCSIController: true cloudWatch: clusterLogging: enableTypes: ["*"] logRetentionInDays: 30

Step 2: Create the cluster

Now, we’re ready to create our Amazon EKS cluster. This process takes several minutes to complete. If you’d like to monitor the status, see the AWS CloudFormation console.

  1. Create the Amazon EKS cluster and specify the cluster-config.yaml.

    eksctl create cluster -f cluster-config.yaml
    Note

    If you receive an Error: checking STS access in the response, make sure that you’re using the correct user identity for the current shell session. You may also need to specify a named profile (for example, --profile clusteradmin) or get a new security token for the AWS CLI.

    Upon completion, you should see the following response output:

    2024-07-04 21:47:53 [✔] EKS cluster "web-quickstart" in "region-code" region is ready

Step 3: Set up external access to applications using the AWS Load Balancer Controller (LBC)

With the cluster operational, our next step is making its containerized applications accessible externally. This is accomplished by deploying an Application Load Balancer (ALB) to direct traffic outside the cluster to our services, in other words, our applications. When we created our cluster, we established an IAM Roles for Service Accounts (IRSA) for the Load Balancer Controller (LBC) with the permissions needed to dynamically create ALBs, facilitating external traffic routing to our Kubernetes services. In this section, we’ll set up the AWS LBC on our cluster.

To configure environment variables

  1. Set the CLUSTER_REGION environment variable for your Amazon EKS cluster. Replace the sample value for region-code.

    export CLUSTER_REGION=region-code
  2. Set the CLUSTER_VPC environment variable for your Amazon EKS cluster.

    export CLUSTER_VPC=$(aws eks describe-cluster --name web-quickstart --region $CLUSTER_REGION --query "cluster.resourcesVpcConfig.vpcId" --output text)

To install the AWS Load Balancer Controller (LBC)

The AWS Load Balancer Controller (LBC) leverages Custom Resource Definitions (CRDs) in Kubernetes to manage AWS Elastic Load Balancers (ELBs). These CRDs define custom resources such as load balancers and TargetGroupBindings, enabling the Kubernetes cluster to recognize and manage them.

  1. Use Helm to add the Amazon EKS chart repository to Helm.

    helm repo add eks https://aws.github.io/eks-charts
  2. Update the repositories to ensure Helm is aware of the latest versions of the charts:

    helm repo update eks
  3. Run the following Helm command to simultaneously install the Custom Resource Definitions (CRDs) and the main controller for the AWS Load Balancer Controller (AWS LBC). To skip the CRD installation, pass the --skip-crds flag, which might be useful if the CRDs are already installed, if specific version compatibility is required, or in environments with strict access control and customization needs.

    helm install aws-load-balancer-controller eks/aws-load-balancer-controller \ --namespace kube-system \ --set clusterName=web-quickstart \ --set serviceAccount.create=false \ --set region=${CLUSTER_REGION} \ --set vpcId=${CLUSTER_VPC} \ --set serviceAccount.name=aws-load-balancer-controller

    You should see the following response output:

    NAME: aws-load-balancer-controller LAST DEPLOYED: Wed July 3 19:43:12 2024 NAMESPACE: kube-system STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: AWS Load Balancer controller installed!

Step 4: Deploy the 2048 game sample application

Now that the load balancer is set up, it’s time to enable external access for containerized applications in the cluster. In this section, we walk you through the steps to deploy the popular "2048 game" as a sample application within the cluster. The provided manifest includes custom annotations for the Application Load Balancer (ALB), specifically the 'scheme' annotation and 'target-type' annotation. These annotations integrate with and instruct the AWS Load Balancer Controller (LBC) to handle incoming HTTP traffic as "internet-facing" and route it to the appropriate service in the 'game-2048' namespace using the target type "ip". For more annotations, see Annotations in the AWS LBC documentation.

  1. Create a Kubernetes namespace called game-2048 with the --save-config flag.

    kubectl create namespace game-2048 --save-config

    You should see the following response output:

    namespace/game-2048 created
  2. Deploy the 2048 Game Sample application.

    kubectl apply -n game-2048 -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.8.0/docs/examples/2048/2048_full.yaml

    This manifest sets up a Kubernetes Deployment, Service, and Ingress for the game-2048 namespace, creating the necessary resources to deploy and expose the game-2048 application within the cluster. It includes the creation of a service named service-2048 that exposes the deployment on port 80, and an Ingress resource named ingress-2048 that defines routing rules for incoming HTTP traffic and annotations for an internet-facing Application Load Balancer (ALB). You should see the following response output:

    namespace/game-2048 configured deployment.apps/deployment-2048 created service/service-2048 created ingress.networking.k8s.io/ingress-2048 created
  3. Run the following command to get the Ingress resource for the game-2048 namespace.

    kubectl get ingress -n game-2048

    You should see the following response output:

    NAME CLASS HOSTS ADDRESS PORTS AGE ingress-2048 alb * k8s-game2048-ingress2-eb379a0f83-378466616.region-code.elb.amazonaws.com 80 31s

    You’ll need to wait several minutes for the Application Load Balancer (ALB) to provision before you begin the following steps.

  4. Open a web browser and enter the ADDRESS from the previous step to access the web application. For example:

    k8s-game2048-ingress2-eb379a0f83-378466616.region-code.elb.amazonaws.com

    You should see the 2048 game in your browser. Play!

    Play the 2048 game

Step 5: Persist Data using the Amazon EBS CSI Driver nodes

Now that the 2048 game is up and running on your Amazon EKS cluster, it’s time to ensure that your game data is safely persisted using the Amazon EBS CSI Driver managed add-on. This add-on was installed on our cluster during the creation process. This integration is essential for preserving game progress and data even as Kubernetes pods or nodes are restarted or replaced.

  1. Create a Storage Class for the EBS CSI Driver:

    kubectl apply -n game-2048 -f https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/master/examples/kubernetes/dynamic-provisioning/manifests/storageclass.yaml
  2. Create a Persistent Volume Claim (PVC) to request storage for your game data. Create a file named ebs-pvc.yaml and add the following content to it:

    apiVersion: v1 kind: PersistentVolumeClaim metadata: name: game-data-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: ebs-sc
  3. Apply the PVC to your cluster:

    kubectl apply -f ebs-pvc.yaml

    You should see the following response output:

    persistentvolumeclaim/game-data-pvc created
  4. Now, you need to update your 2048 game deployment to use this PVC for storing data. The following deployment is configured to use the PVC for storing game data. Create a file named ebs-deployment.yaml and add the following contents to it:

    apiVersion: apps/v1 kind: Deployment metadata: namespace: game-2048 name: deployment-2048 spec: replicas: 3 # Adjust the number of replicas as needed selector: matchLabels: app.kubernetes.io/name: app-2048 template: metadata: labels: app.kubernetes.io/name: app-2048 spec: containers: - name: app-2048 image: public.ecr.aws/l6m2t8p7/docker-2048:latest imagePullPolicy: Always ports: - containerPort: 80 volumeMounts: - name: game-data mountPath: /var/lib/2048 volumes: - name: game-data persistentVolumeClaim: claimName: game-data-pvc
  5. Apply the updated deployment:

    kubectl apply -f ebs-deployment.yaml

    You should see the following response output:

    deployment.apps/deployment-2048 configured

With these steps, your 2048 game on Amazon EKS is now set up to persist data using the Amazon EBS CSI Driver. This ensures that your game progress and data are safe even in the event of pod or node failures.

If you liked this tutorial, let us know by providing feedback so we’re able to provide you with more use case-specific quickstart tutorials like this one.

Step 6: Delete your cluster and nodes

After you’ve finished with the cluster and nodes that you created for this tutorial, you should clean up by deleting the cluster and nodes with the following command. If you want to do more with this cluster before you clean up, see Next steps.

eksctl delete cluster -f ./cluster-config.yaml

Upon completion, you should see the following response output:

2024-07-05 17:26:44 [✔] all cluster resources were deleted

Next steps

The following documetation topics help you to extend the functionality of your cluster:

To explore ways to create different types of clusters: