Deploy nodeJS app to kubernetes cluster with load balancer service

Victor Yeo
3 min readAug 4, 2022

--

This article describes ways to dockerize a nodeJS app, create kubernetes deployment and service, deploy the nodeJS app to kubernetes cluster and access the REST API of the nodeJS app deployed in the kubernetes cluster.

The nodeJS app can be anything. For the purpose of this article, it will have a REST API returning helloworld string.

  1. Create a Dockerfile

We must create a docker image of the nodeJS app before we can deploy the app to kubernetes cluster.

FROM node:16.13.0 AS builder
WORKDIR /dist
COPY ./package.json ./
COPY ./package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:16.13-alpine
WORKDIR /dist
EXPOSE 4002
COPY --chown=node:node --from=builder /dist ./
USER node
CMD [“npm”, “run”, “start”]

In the Dockerfile above, we use two stage process. Firstly, we use node 16.13 image as the builder, copy the package.json and package-lock.json, install the dependencies, and copy the files (COPY . . ) and build the nodejs app. Secondly, we use node 16.13 alpine image to run the nodejs app. We copy the files from first stage (COPY --chown=node:node --from=builder /dist ./) to the working directory. In the last line, we call npm run start to run the nodejs app. This two stage process is able to reduce docker image size because only the built files are copied to the docker image.

2. Setup a kubernetes cluster and connect to the cluster

We can use AWS EKS or Google GKE user interface to setup the kubernetes cluster. Alternatively, we can use terraform as well. Then we use the following command to connect our local environment to the cluster.

For AWS:

aws eks --region us-west-2 update-kubeconfig --name my-cluster

For GKE:

gcloud container clusters get-credentials my-cluster --zone us-east1 --project <proj_name>

3. Create deployment yaml file

apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: myprog
name: myprog
spec:
replicas: 2
selector:
matchLabels:
app: myprog
template:
metadata:
labels:
app: myprog
spec:
containers:
- image: myusername/myprog:latest
name: myprog
ports:
- containerPort: 4002

In the yaml file above, we specify the file as deployment (kind: Deployment). We specify the label (app: myprog) and selector must match with the label (matchLabels). For the purpose of this article, we set to two replica copy (replicas: 2). Each replica set will contain a pod.

We apply the yaml file.

kubectl apply -f deployment.yaml

Output from get pod

$ kubectl get pod
NAME READY STATUS RESTARTS AGE
myprog-5dbb5d4dd5–5cs9w 1/1 Running 0 73s
myprog-5dbb5d4dd5-fx8kx 1/1 Running 0 73s

Output from get replica set

$ kubectl get rs
NAME DESIRED CURRENT READY AGE
myprog-5dbb5d4dd5 2 2 2 57m

4. Create service yaml file

apiVersion: v1
kind: Service
metadata:
name: myprog-service
spec:
type: LoadBalancer
selector:
app: myprog
ports:
- protocol: TCP
port: 4002
targetPort: 4002

In the yaml file above, it declares a service (kind: Service). The type is load balancer (type: LoadBalancer).The selector is matched to the label of deployment (app: myprog). The target port is the port on the kubernetes pod (targetPort: 4002). The service opens a port to the target port (port: 4002).

We apply the yaml file.

kubectl apply -f service.yaml

Output from get svc

$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myprog-service LoadBalancer 172.20.141.130 a971e8a5–158085.us-west-2.elb.amazonaws.com 4002:30125/TCP 68m

5. Access the nodeJS app from command line

On the command line, we run the curl command

$ curl -X GET http://a971e8a5–158085.us-west-2.elb.amazonaws.com:4002/api/v1/hello
helloworld

The nodeJS app returns “helloworld” to us ! We can access the kubernetes pod of nodeJS app, externally.

The whole process of running nodeJS app within kubernetes cluster is successful.

Note: to delete the deployment and service, run

kubectl delete deployment myprogkubectl delete service myprog-service

--

--

No responses yet