In the previous chapter, we learnt how to setup a nginx web server on Local Minikube Cluster. In this chapter, we are gonna deploy a Sample Node.js application on a cloud provider such as AWS. Here, we are gonna deploy our sample application on EKS (Elastic Kubernetes Service). Also, we are gonna learn about different types of components such as Service, Deployments, etc.
Pre-requisites:-
1.) Docker
2.) EKS Cluster
3.) aws cli
Now, let's proceed to deploy a Node.js Application on the currently running EKS Cluster.
We need Docker so that we can package the code as an image which we will later push it to our ECR repository.
Here's our sample Node.js Application code:
const express=require('express');
const port=3000
const app=express();
app.get('/',(req,res)=>{
res.send('Hi, we are live now!')
})
app.listen(port,()=>{
console.log(`App currently listening on port:${port}`)
})
Let's create a file called index.js
and add the above code to it.
In order to create an image of the above Node.js application, we have to create a Dockerfile and add the following instructions to it.
FROM node:16-alpine
WORKDIR /src
RUN npm install express
COPY . /src
CMD node .
Now, let's build the image:-
docker build -t node-sample-app .
If we want to run the image locally i.e. on our localhost, we can run the following command:-
docker run --rm -it -p 80:3000 nodejs-sample
In the above command, we are running the nodejs-sample
image on port 3000 and we will be accessing it at http://127.0.0.1
Also, it'll remove the container once the execution is completed.
Now let us create a repository in AWS.
Considering our AWS Cli is configured, let us run the following command to create the repository on Amazon ECR:-
aws ecr create-repository \
--repository-name node-sample-repo \
--image-tag-mutability IMMUTABLE
--image-scanning-configuration scanOnPush=true
In the above command, we are creating a repo called node-sample-repo
in Amazon ECR and we are setting the tag immutability property which will prevent us to create images with the same tag i.e. we cannot have images with the same tag name. Also, we are setting up image scanning configuration where it'll scan for any vulnerabilities if present in the image.
Suppose, we want to update the existing image then we can disable mutability (by default its disabled)
Now, that the repo has been created, let's push the image to the ECR repository. We are gonna first authenticate our client.
aws ecr get-login-password --region <aws_region> | docker login --username AWS --password-stdin <account_id>.dkr.ecr.<aws_region>.amazonaws.com
Replace account_id
and aws_region
with the appropriate values.
The above command will retrieve an authentication token and authenticate the Docker client to our registry. Once that is done, let's tag our image in order to push it to the repository.
docker tag node-sample-app:latest <account_id>.dkr.ecr.<aws_region>.amazonaws.com/node-sample-repo:latest
Finally, push the image to the ECR repository
docker push <account_id>.dkr.ecr.<aws_region>.amazonaws.com/node-sample-repo:latest
Now, the image is present in our ECR, the ARN of the image would be something like this.
<account_id>.dkr.ecr.<aws_region>.amazonaws.com/node-sample-repo:latest
Now, let's proceed with deploying the above image to our Kubernetes cluster.
Considering an EKS Cluster is already setup (Refer this to create an EKS Cluster) and our local machine is configured to connect to EKS, let us create a file called Deployment.yml
and paste the following piece of code:-
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: node-app
name: node-app
spec:
replicas: 1
selector:
matchLabels:
app: node-app
template:
metadata:
labels:
app: node-app
spec:
containers:
- image: <account_id>.dkr.ecr.<aws_region>.amazonaws.com/node-sample-repo:latest
name: node-app
imagePullPolicy: Always
resources: {}
ports:
- containerPort: 3000
We create another file called Service.yml
which will actually create the service:-
apiVersion: v1
kind: Service
metadata:
name: node-app
labels:
run: node-app
spec:
ports:
- port: 3000
protocol: TCP
selector:
app: node-app
We are gonna run the following two commands:-
kubectl create -f Deployment.yml
kubectl create -f Service.yml
The above 2 commands will deploy 1 replica/instance of the sample Node.js application on EKS Cluster where Deployment.yaml
will create the sample Node.js application by pulling the image from the ECR and Service.yaml
will be responsible for forwarding the requests to the pods. This will be an internal service. Now, suppose we want to have an endpoint and want to access the webpage, we can add the type to type: LoadBalancer
followed by which if we run the following command:-
kubectl get pods -o wide
where, it'll provide the public ip through which it can be accessed.
Note:- What is the difference between thekind: Deployment
vs thekind: Pod
?
Well, Deployment creates a replica of Pods where the ReplicaSet or the Replication Controller takes care of maintaining the healthy status and the required number of Pods where as thekind: Pod
just creates the number of Pods as mentioned and it isn't maintained by any kind of controller. Also, thekind: Pod
, is mostly used in a development environment and not commonly used in a Production Environment.
Hopefully, this chapter helps you in creating/deploying a Sample Application in your EKS cluster.
In the next chapter, we are gonna learn how to create services like Cassandra or MySQL which have storage involved in Kubernetes. Cheers!