javascript Kubernetes tutorial

Kubernetes quick tutorial

Kubernetes - Quick Tutorial
by Francesco Ciulla | May 12, 2023

A step-by-step process to create your first Kubernetes example.

šŸ‘‹ Introduction

Let’s make the most straightforward but most understandable Kubernetes example ever.

Video version: youtu.be/noJmOirhHKM

We will create our first example with Kubernetes starting from scratch, using:

  • JavaScript
  • Node.js
  • Docker
  • Docker Compose
  • Kubernetes

šŸ“ƒ Requirements

  • Node.js
  • Docker (with Kubernetes enabled)

šŸš€ Getting started

Let’s start in a new VS Code window (or any other editor you choose).

1. Create a new project

npm init -y

2. Install the dependencies

npm i express

3. Create a new file calledĀ index.js

touch index.js

Create index.js file

Let’s create a simple Express server that listens on port 3000 and returns a response.

//simple express server
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(3000, () => {
  console.log('Example app listening on port 3000!');
});

Run this by typing:

node index.js

Run node.js

Now it’s time to Dockerize our application.


šŸ³ Dockerizing our application

We will dockerize the application by creating three files:

  • .dockignore
  • Dockerfile
  • docker-compose.yml
touch .dockignore Dockerfile docker-compose.yml

āŒ .dockignore

AddĀ node_modules to the file:

Add node modules to the file

This is to ignore the localĀ node_modulesĀ folder when building the image.

šŸ³ Dockerfile

Open theĀ DockerfileĀ and add the following:

FROM node:19-alpine

# Create app directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy source code
COPY . .

# Expose port 3000
EXPOSE 3000

# Run the app
CMD [ "node", "index.js" ]

To build the app, let’s populate theĀ docker-compose.ymlĀ file with the following:

version: '3.9'

services:
  myapp:
    container_name: myapp
    image: myapp:1.0.0
    build: .
    ports:
      - 3000:3000

Explanation of theĀ docker-compose.ymlĀ file:

  • version: '3.9'Ā – the version of the docker-compose file
  • services:Ā – the services (containers) we want to run. In this case, just one.
  • myapp:Ā – the name of the service
  • container_name: myappĀ – the name of the container
  • image: myapp:1.0.0Ā – the name of the image
  • build: .Ā – the path to the Dockerfile. In this case, the current directory.
  • ports:Ā – the ports that we want to expose. In this case, port 3000 of the container will be exposed on port 3000 of the host machine.

Before we test it with Docker, let’s modify the index.js file by changingĀ Hello World!Ā toĀ Hello Docker!

//simple express server
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello Docker!');
});

app.listen(3000, () => {
  console.log('Example app listening on port 3000!');
});

Now let’s run the container by typing this in the terminal:

docker compose up

Run the container

Nice! Now it’s the turn of Kubernetes.

But before we do that, let’s change theĀ Hello Docker!Ā toĀ Hello Kubernetes!

//simple express server
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello Kubernetes!');
});

app.listen(3000, () => {
  console.log('Example app listening on port 3000!');
});

Then rebuild the image by typing:

docker compose build

ā„¹ļø This is not really necessary, but good to understand how it works.


ā˜øļø Kubernetes

Before we start, be sure Kubernetes is enabled in Docker Desktop.

Kubernetes is enabled in Docker Desktop

Pods, Deployments, and Services

Kubernetes is a container orchestration tool. It is used to manage multiple containers on multiple hosts. In our case, we will use our machine as a single host.

We will keep it as minimal as possible by creating a deployment and a service.

Just three definitions to get started as soon as possible.

pod: the smallest deployable unit of computing that can be created and managed in Kubernetes.

deployment: a Kubernetes object that manages a set of pods. It is responsible for creating and updating pods.

service: an abstraction that defines a logical set of pods and a policy by which to access them. They are used to expose a set of pods to external traffic.

šŸ“ Create the deployment

We will create a deployment in less than 20 lines of code.

At the root of the project, create a new file calledĀ deployment.yamlĀ and add the following:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp
          image: myapp:1.0
          ports:
            - containerPort: 3000

āš ļø You might see a warning in the last five lines, but it’s only because this configuration might eat a lot of resources. But let’s keep it simple for now.

Explanation of theĀ deployment.yamlĀ file:

  • apiVersion: apps/v1Ā – the version of the Kubernetes API
  • kind: DeploymentĀ – the kind of object we want to create. In this case, a deployment.
  • name: myappĀ – the name of the deployment
  • replicas: 3Ā – the number of replicas of the deployment
  • image: myapp:1.0Ā – the image of the container. We defined this in the docker-compose.yml file
  • ports:Ā – the ports of the container. 3000 in this case.

Before we create the deployment, let’s check if there are any deployments in the cluster:

kubectl get deployments

check if there are any deployments in the cluster

Let’s create the deployment by typing:

kubectl apply -f deployment.yaml

Then let’s try to get the deployments again:

kubectl get deployments

We can also get a detail of the pods:

kubectl get pods

Get the pods details

As you can see, we have 3/3 pods running (we defined replicas: 3 in the deployment.yaml file).

But creating a deployment is not enough. We need to expose the deployment to the outside world!

šŸŒ Create the service

We will create a service in 11 lines of code.

At the root of the project, create a new file calledĀ service.yamlĀ and add the following:

apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp
  ports:
    - port: 80
      targetPort: 3000
  type: LoadBalancer

This is enough to expose the deployment to the outside world (port 80)

Before we apply this configuration, let’s check if there are any services in the cluster:

kubectl get services

Check if there are any services in the cluster

There is one calledĀ KubernetesĀ but that’s the default service that is created when you install Kubernetes.

Let’s create the service by typing:

kubectl apply -f service.yaml

Then let’s try to get the services again:

kubectl get services

Try to get the services again

Finally, visitĀ localhost:80Ā in your browser and you should seeĀ Hello Kubernetes!

VisitĀ localhost:80Ā in your browser

šŸ§¹ Clean up

To clean up, delete the deployment and the service:

kubectl delete -f deployment.yaml
kubectl delete -f service.yaml

Delete the deployment and the service

šŸ Conclusion

We did it! We created our first example with Kubernetes starting from scratch, using:

Video Version:

All the code is available in the GitHub repository (link in the video description): youtu.be/noJmOirhHKM

That’s all.

If you have any questions, drop a comment here: Francesco.

Did you like this article? Share it with your friends: