DEV Community

Cover image for Create an AWS EKS Fargate v1.30 and play Prince Of Persia !
David💻 Subscriber for AWS Community Builders

Posted on

Create an AWS EKS Fargate v1.30 and play Prince Of Persia !

In this article, I will provide a step by step guide on how to create an EKS cluster using eksctl (v1.30). I will also demonstrate how to deploy a game based on the MS-DOS version of Prince of Persia.

Requirements

  • AWS account / AWS CLI
  • Github account or any git repository
  • Docker
  • eksctl
  • helm

Walkthrough

Open Cloud Shell service in AWS.
If not already, install eksctl with the following command:

 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 
Enter fullscreen mode Exit fullscreen mode

eksctl version
Now, let's proceed to create our cluster with version 1.30, using fargate. Run the following command. (Be sure to create your cluster in the same region as your VPC)

 eksctl create cluster --name gaming-cluster --version 1.30 --region us-east-1 --fargate 
Enter fullscreen mode Exit fullscreen mode

If you want to create your cluster in a specific VPC be sure to specify the corresponding subnets (otherwise this command is going to create a vpc dedicated to the eks)

 eksctl create cluster --name gaming-cluster --version 1.30 --region us-east-1 --fargate --vpc-private-subnets subnet-private-1, subnet-private-2 
Enter fullscreen mode Exit fullscreen mode

EKS creation
This process might take around 20~25+ minutes.

Now let's associate an oidc provider in our cluster.

 eksctl utils associate-iam-oidc-provider --region us-east-1 --cluster gaming-cluster --approve 
Enter fullscreen mode Exit fullscreen mode

Our cluster is now ready with a default fargate profile that contains the namespace default and kube-system

Cluster new

Let's create a fargate profile for our game application. (Be sure to also create the ns inside our k8s cluster)
Default FP

 eksctl create fargateprofile \ --cluster gaming-cluster \ --name fp-gaming \ --namespace gaming \ --region us-east-1 
Enter fullscreen mode Exit fullscreen mode

Now, let's add the AWS Load Balancer Controller to expose our application using AWS load balancers.

To do this we need to create an iam policy, a serviceaccount and install the plugin with helm.

Take this IAM policy example:

 curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json 
Enter fullscreen mode Exit fullscreen mode

Create the IAM policy

 aws iam create-policy \ --policy-name AWSLoadBalancerControllerIAMPolicy-EKS \ --policy-document file://iam-policy.json 
Enter fullscreen mode Exit fullscreen mode

EKS Policy

Now let's create a service account for this controller

 eksctl create iamserviceaccount --cluster=gaming-cluster --namespace=kube-system --name=aws-load-balancer-controller --attach-policy-arn=arn:aws:iam::<account_id>:policy/AWSLoadBalancerControllerIAMPolicy-EKS --approve 
Enter fullscreen mode Exit fullscreen mode

Service Account

Great ! Now is helm turn, to install some useful charts, in this case the aws load balancer controller.

 curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash 
Enter fullscreen mode Exit fullscreen mode

Run the following commands:

 helm repo add eks https://aws.github.io/eks-charts 
Enter fullscreen mode Exit fullscreen mode
 kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller/crds?ref=master" 
Enter fullscreen mode Exit fullscreen mode
 helm upgrade -i aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=gaming-cluster --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller --set vpcId=<the same vpc as the cluster> 
Enter fullscreen mode Exit fullscreen mode

albc

Awesome now we can access our cluster

 aws eks update-kubeconfig --name gaming-cluster --region us-east-1 
Enter fullscreen mode Exit fullscreen mode

EKS

Before we proceed let's create our gaming namespace

 kubectl create ns gaming 
Enter fullscreen mode Exit fullscreen mode

We are almost there, now is the game turn.

For this I'm going to use this fork thanks to oklemenz, ultrabolido and jmechner

 git clone https://github.com/bdllerena/PrinceJS 
Enter fullscreen mode Exit fullscreen mode

After cloning our image make sure to create an ECR repository (or use any of your choice to host our Prince of Persia image)

ECR

Now copy the push command, it should look like this

 aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account_id>.dkr.ecr.us-east-1.amazonaws.com 
Enter fullscreen mode Exit fullscreen mode

Inside our repository there should be a Dockerfile that looks like this.

Note: We use the --platform=linux/amd64 flag because our Kubernetes cluster supports this platform. Otherwise, if we build the Docker image with tools like Docker Desktop, it will make the image compatible with the local OS instead.

 FROM --platform=linux/amd64 node:18 WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 8080 CMD ["npm", "start"] 
Enter fullscreen mode Exit fullscreen mode

Inside our repository execute the following commands

 docker build -t prince-of-persia . 
Enter fullscreen mode Exit fullscreen mode

After we built our image let's tag it and push it to ECR

 docker tag prince-of-persia:latest <account_id>.dkr.ecr.us-east-1.amazonaws.com/prince-of-persia:latest docker push <account_id>.dkr.ecr.us-east-1.amazonaws.com/prince-of-persia:latest 
Enter fullscreen mode Exit fullscreen mode

ECR code

ECR Repo

 apiVersion: apps/v1 kind: Deployment metadata: name: prince-of-persia namespace: gaming spec: replicas: 1 selector: matchLabels: app: prince-of-persia template: metadata: labels: app: prince-of-persia spec: containers: - name: prince-of-persia image: <account_id>.dkr.ecr.us-east-1.amazonaws.com/prince-of-persia:latest ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: annotations: service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing service.beta.kubernetes.io/aws-load-balancer-type: external name: prince-of-persia namespace: gaming spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: prince-of-persia type: LoadBalancer 
Enter fullscreen mode Exit fullscreen mode

After checking that our image is the same that we pushed to ECR, execute our manifest !

 kubectl apply -f manifest.yaml 
Enter fullscreen mode Exit fullscreen mode

This manifest is going to create a deployment with 1 replica (1 pod) and a service that creates a network load balancer as client-facing (public)

After some minutes, check if the service was created with this command

 kubectl get svc -n gaming 
Enter fullscreen mode Exit fullscreen mode

svc created

Awesome ! if you want you can check the logs of the pod, and see if everything is up and running

 kubectl get pods -n gaming kubectl logs -f prince-of-persia-.... -n gaming 
Enter fullscreen mode Exit fullscreen mode

Logs

Finally let's enjoy our game by going to the svc that we created previously, it should look a bit like this

 k8s-gaming-princeof-15fa57ff31-6933c5aaecd54910.elb.us-east-1.amazonaws.com 
Enter fullscreen mode Exit fullscreen mode

Prince of Persia

Optional

If you want to enable logging of your pods follow this steps

Create a namespace for aws-observability, and a fargate profile

 kubectl create ns aws-observability 
Enter fullscreen mode Exit fullscreen mode
 eksctl create fargateprofile \ --cluster gaming-cluster \ --name fp-observability \ --namespace aws-observability \ --region us-east-1 
Enter fullscreen mode Exit fullscreen mode

New profile

Verify that the execution role of this fargate profile has the necessary permissions to execute logs event into cloudwatch, otherwise create an inline policy inside that role with the following permissions.

Note: Be sure to add the specific name of the log group you are going to use

 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:CreateLogGroup", "logs:DescribeLogStreams", "logs:PutLogEvents" ], "Resource": "*" } ] } 
Enter fullscreen mode Exit fullscreen mode

Json policy

Now create a configmap like this an apply it, be sure to modify per your requirements, this configmap is going to start logging at a log group in cloudwatch named gaming-cluster

 apiVersion: v1 kind: ConfigMap metadata: name: aws-logging namespace: aws-observability data: flb_log_cw: "false" # set to true to ship Fluent Bit process logs to CloudWatch. filters.conf: | [FILTER] Name parser Match * Key_name log Parser crio [FILTER] Name kubernetes Match kube.* Merge_Log On Keep_Log Off Buffer_Size 0 Kube_Meta_Cache_TTL 300s output.conf: | [OUTPUT] Name cloudwatch_logs Match kube.* region us-east-1 log_group_name gaming-cluster log_stream_prefix from-fluent-bit- log_retention_days 60 auto_create_group true parsers.conf: | [PARSER] Name crio Format Regex Regex ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>P|F) (?<log>.*)$ Time_Key time Time_Format %Y-%m-%dT%H:%M:%S.%L%z 
Enter fullscreen mode Exit fullscreen mode
 kubectl apply -f observability.yaml 
Enter fullscreen mode Exit fullscreen mode

Be sure to rollout restart your deployments !

 kubectl rollout restart deployment prince-of-persia -n gaming 
Enter fullscreen mode Exit fullscreen mode

Note: Is it recommended to only filter what is critical, modify the retention of the log group as it can get costly to get tons of logs

Log groups

Hope this guide can be helpful ! Happy gaming !

Top comments (0)