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

David💻 - Sep 18 - - Dev Community

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 !

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .