DEV Community

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

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)