DEV Community

Cover image for Deploying an Application on Kubernetes: A Complete Guide!
Pavan Belagatti
Pavan Belagatti

Posted on • Updated on

Deploying an Application on Kubernetes: A Complete Guide!

Kubernetes is an open-source platform for automating the deployment, scaling, and management of containerized applications. It is a popular tool for container orchestration and provides a way to manage large numbers of containers as a single unit rather than having to manage each container individually.

Importance of Kubernetes

Kubernetes has become an essential tool for managing and deploying modern applications, and its importance lies in its ability to provide a unified platform for automating and scaling the deployment, management, and scaling of applications. With Kubernetes, organizations can achieve increased efficiency and agility in their development and deployment processes, resulting in faster time to market and reduced operational costs. Kubernetes also provides a high degree of scalability, allowing organizations to scale their applications as their business grows and evolves easily.

Additionally, Kubernetes offers robust security features, ensuring that applications are protected against potential threats and vulnerabilities. With its active community and extensive ecosystem, Kubernetes provides organizations with access to a wealth of resources, tools, and services that can help them to improve and enhance their applications continuously. Overall, the importance of using Kubernetes lies in its ability to provide a flexible, scalable, and secure platform for managing modern applications and enabling organizations to stay ahead in a rapidly evolving digital landscape.

Here's a basic overview of how to use Kubernetes:

  • Set up a cluster:

To use Kubernetes, you need to set up a cluster, which is a set of machines that run the Kubernetes control plane and the containers. You can set up a cluster on your own infrastructure or use a cloud provider such as Amazon Web Services (AWS), Google Cloud Platform (GCP), or Microsoft Azure.

  • Package your application into containers:

To run your application on Kubernetes, you need to package it into one or more containers. A container is a standalone executable package that includes everything needed to run your application, including the code, runtime, system tools, libraries, and settings.

  • Define the desired state of your application using manifests:

Kubernetes uses manifests, which are files that describe the desired state of your application, to manage the deployment and scaling of your containers. The manifests specify the number of replicas of each container, how they should be updated, and how they should communicate with each other.

  • Push your code to an SCM platform:

Push your application code to an SCM platform such as GitHub.

  • Use a CI/CD tool to automate:

Use a specialised CI/CD platform such as Harness to automate the deployment of your application. Once you set it up, done; you can easily and often deploy your application code in chunks whenever a new code gets pushed to the project repository.

  • Expose the application:

Once you deploy your application, you need to expose the application to the outside world by creating a Service with a type of LoadBalancer or ExternalName. This allows users to access the application through a stable IP address or hostname.

  • Monitor and manage your application:

After your application is deployed, you can use the kubectl tool to monitor the status of your containers, make changes to the desired state, and scale your application up or down.

These are the general steps to deploy an application on Kubernetes. Depending on the application's complexity, additional steps may be required, such as configuring storage, network policies, or security. However, this should give you a good starting point for deploying your application on Kubernetes.

Today, we will see how to automate simple application deployment on Kubernetes using Harness.

Prerequisites

Tutorial

Kubernetes deployment

We will use our sample application that is already in the GitHub repository. We will use a Kubernetes cluster to deploy our application. Next, we will use a CI/CD platform, Harness, in this tutorial to show how we can automate the software delivery process easily.

Step 1: Test the sample application locally

Fork and clone the sample notes application

Go to the application folder with the following command



cd notes-app-cicd


Enter fullscreen mode Exit fullscreen mode

Install dependencies with the following command



npm install 


Enter fullscreen mode Exit fullscreen mode

Run the application locally to see if the application works perfectly well



node app.js


Enter fullscreen mode Exit fullscreen mode

Step 2: Containerize the application

You can see the Dockerfile in the sample application repository.



FROM node:14-alpine

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD [ "npm", "start" ]


Enter fullscreen mode Exit fullscreen mode

Use the following command to build, tag and push the image to any container registry of your choice. We will push it to Docker Hub in this tutorial.

For Mac M1, use the following command



docker buildx build --platform=linux/arm64 --platform=linux/amd64  -t docker.io/$your docker hub user name/$image name:$tag name --push  -f ./Dockerfile .


Enter fullscreen mode Exit fullscreen mode

For other than Mac M1, use the below commands to build and push the image,



docker build -t $your docker hub user name/$image name .


Enter fullscreen mode Exit fullscreen mode


docker push $your docker hub user name/$image name .


Enter fullscreen mode Exit fullscreen mode

Step 3: Create or get access to a Kubernetes cluster

Make sure to have access to a Kubernetes cluster from any cloud provider. You can even use Minikube or Kind to create a cluster. In this tutorial, we are going to make use of a Kubernetes cluster from Google Cloud (GCP)

I already have an account on Google Cloud, so creating a cluster will be easy.

Step 4: Make sure the Kubernetes manifest files are neat and clean

You need deployment yaml and service yaml files to deploy and expose your application. Make sure both files are configured properly.

You can see that we have deployment.yaml and service.yaml file already present in the sample application repository.

Below is our deployment.yaml file.



apiVersion: apps/v1
kind: Deployment
metadata:
  name: notes-app-deployment
  labels:
    app: notes-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: notes-app
  template:
    metadata:
      labels:
        app: notes-app
    spec:
      containers:
      - name: notes-app-deployment
        image: pavansa/notes-app
        resources:
          requests:
            cpu: "100m"
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 3000


Enter fullscreen mode Exit fullscreen mode

Below is our service.yaml file



apiVersion: v1
# Indicates this as a service
kind: Service
metadata:
 # Service name
 name: notes-app-deployment
spec:
 selector:
   # Selector for Pods
   app: notes-app
 ports:
   # Port Map
 - port: 80
   targetPort: 3000
   protocol: TCP
 type: LoadBalancer


Enter fullscreen mode Exit fullscreen mode

Apply the manifest files with the following commands. Starting with deployment and then service yaml file.



kubectl apply -f deployment.yaml


Enter fullscreen mode Exit fullscreen mode


kubectl apply -f service.yaml


Enter fullscreen mode Exit fullscreen mode

Verify the pods are running properly as expected after applying the kubectl apply commands.



kubectl get pods


Enter fullscreen mode Exit fullscreen mode

You should see the pods and their status.
running pods

Step 5: Let’s automate the deployment using Harness

You need a CI/CD tool to automate your continuous integration and deployment process. Harness is known for its innovation and simplicity in the CI/CD space. Hence, we will use this platform to set up automated continuous deployment of our application.

Once you sign up and verify your account, you will be presented with a welcome message and project creation set up. Proceed to create a project.
create project

Add the name to the project, save and continue.
about the project

Select the ‘Continuous Delivery’ module and start your free plan.
Harness CD module

Go to the module and start your deployment journey.
deployment pipeline

The set up is very straightforward, as shown in the above image; you can deploy your application in just four simple steps.

Select your deployment type i, e Kubernetes and click ‘Connect to Environment’.
deployment type

Connect to your Kubernetes environment with Delegate. A Delegate is a service that runs on your infrastructure to execute tasks on behalf of the Harness platform.
connect Harness

Download the Delegate YAML file and install it on your Kubernetes cluster by applying the kubectl apply command as stated in the above step.

Make sure to execute the command kubectl apply -f harness-delegate.yaml in the right path where you downloaded your delegate YAML file.

Ensure your Delegate installation is successful.

Next, configure the service and add the manifest details.
configure service

After adding all the details, click ‘Create a Pipeline’.
create pipeline

Check if all the connections are successful. Once everything looks fine, click on ‘Run Pipeline’.
run cd pipeline

Click on ‘Run Pipeline’ to see the successful deployment.
Successful Harness Pipeline

Congratulations! We successfully deployed our application successfully on Kubernetes using Harness. Now, we can easily automate the deployment using the Harness CD module.

You can automate your CD process by adding Triggers. When any authorised person pushes any new code to your repository, your pipeline should get triggered and do CD. Let’s see how to do that.

In the pipeline studio, you can click the ‘Triggers’ tab and add your desired trigger.
new trigger

all trigger related

Click on ‘Add New Trigger’ and select ‘GitHub’.
trigger list

Add the required details and continue. As you can see, we are selecting ‘Push’ as our event. So whenever any authorised push happens to our repository, the pipeline should trigger and run.
trigger settings

trigger webhook

You can see your newly created trigger in the ‘Triggers’ tab.
new trigger listed

Now, whenever any authorised person pushes any code changes to your main/master repository, the pipeline automatically gets triggered.

If you have not seen my other two articles on continuous integration and automated testing, please take a look.

Top comments (16)

Collapse
 
derlin profile image
Lucy Linder • Edited

Nice one! Just one comment: syntax highlighting for code blocks would improve readability. You can do it by specifying the language after the opening three backticks, for example (replace the single quotes with backticks in your head):

'''yaml
key: value #comment
'''
Enter fullscreen mode Exit fullscreen mode

You can use bash, javascript, yaml, etc.

Collapse
 
pavanbelagatti profile image
Pavan Belagatti

Thanks for the suggestion. That's really valuable. Yes, I will add it.

Collapse
 
star_trooper profile image
Atharva Shirdhankar

Awesome Write up Pavan✨

Collapse
 
pavanbelagatti profile image
Pavan Belagatti

Glad you liked it!

Collapse
 
taradevops profile image
TaraDevOps

Hi Pavan, Very nice hands-on content... But I have a quick question. I have set up the GKE cluster for the Hands-on. After installing the Nodejs, when when I run the command "npm install", I got this error. Please suggest me.

ganeshbhanda@cloudshell:~ (central-insight-3791)$ cd notes-app-cicd/
ganeshbhanda@cloudshell:~/notes-app-cicd (central-insight-3791)$ npm install
npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /home/ganeshbhanda/notes-app-cicd/node_modules
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, mkdir '/home/ganeshbhanda/notes-app-cicd/node_modules'
npm ERR! [Error: EACCES: permission denied, mkdir '/home/ganeshbhanda/notes-app-cicd/node_modules'] {
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'mkdir',
npm ERR! path: '/home/ganeshbhanda/notes-app-cicd/node_modules'
npm ERR! }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
npm ERR! /home/ganeshbhanda/.npm/_logs/2023-02-28T16_17_08_511Z-debug-0.log
ganeshbhanda@cloudshell:~/notes-app-cicd (central-insight-3791)$ sudo npm install
sudo: npm: command not found
ganeshbhanda@cloudshell:~/notes-app-cicd (central-insight-3791)$ sudo install npm
install: missing destination file operand after 'npm'
Try 'install --help' for more information.

Collapse
 
pavanbelagatti profile image
Pavan Belagatti

Are you on the right path and running the command?
Have you installed the Node.js and npm properly?

I see the error that says 'sudo: npm: command not found'. So you have not installed npm I believe.

use this command
npm install -g npm

Check the version of Node.js and npm with the following commands (verify you have installed properly)

node -v
npm -v

Try and let me know

Collapse
 
taradevops profile image
TaraDevOps

I just checked it. Here are the outputs.

ganeshbhanda@cloudshell:~/notes-app-cicd (central-insight-3791)$ npm install -g npm

changed 25 packages in 10s

16 packages are looking for funding
run npm fund for details
ganeshbhanda@cloudshell:~/notes-app-cicd (central-insight-3791)$ node -v
v18.12.1
ganeshbhanda@cloudshell:~/notes-app-cicd (central-insight-3791)$ npm -v
9.5.1
ganeshbhanda@cloudshell:~/notes-app-cicd (central-insight-3791)$ npm install
npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /home/ganeshbhanda/notes-app-cicd/node_modules
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, mkdir '/home/ganeshbhanda/notes-app-cicd/node_modules'
npm ERR! [Error: EACCES: permission denied, mkdir '/home/ganeshbhanda/notes-app-cicd/node_modules'] {
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'mkdir',
npm ERR! path: '/home/ganeshbhanda/notes-app-cicd/node_modules'
npm ERR! }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
npm ERR! /home/ganeshbhanda/.npm/_logs/2023-02-28T17_28_26_878Z-debug-0.log
ganeshbhanda@cloudshell:~/notes-app-cicd (central-insight-3791)$

Thread Thread
 
taradevops profile image
TaraDevOps

Hi Pavan,

Can you please help me on this issue?

Thread Thread
 
pavanbelagatti profile image
Pavan Belagatti

Please check this link - stackoverflow.com/questions/252909...

Thread Thread
 
taradevops profile image
TaraDevOps

Thank you Pavan, this link helped me to move forward but when I ran the below command,
docker buildx create --use unix:///var/run/docker.sock --platform=linux/arm64 --platform=linux/arm64 -t docker.io/dockerisimage/node:14-alpine --push -f ./Dockerfile .

IT GAVE ME THE ERROR. Please help me on this.
ganeshbhanda@cloudshell:~/notes-app-cicd (central-insight-3791)$ docker buildx create --use unix:///var/run/docker.sock --platform=linux/arm64 --platform=linux/arm64 -t docker.io/mydockerisimages/node:14-alpine --push -f ./Dockerfile .
unknown shorthand flag: 't' in -t
See 'docker buildx create --help'.
ganeshbhanda@cloudshell:~/notes-app-cicd (central-insight-3791)$

Thread Thread
 
pavanbelagatti profile image
Pavan Belagatti

The command you used is for Mac M1, use the below commands to build and push your image.

docker build -t $your docker hub user name/$image name .
Enter fullscreen mode Exit fullscreen mode
docker push $your docker hub user name/$image name .
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
taradevops profile image
TaraDevOps

Thank you for your help Pavan. But when I am authorizing GitHub (Using GitHub username and GitHub token) with Harness, I encountered this error:

Illegal character in path at index 50: github.com/TaraGithub/notes-app-ci... app cicd/info/refs?service=git-upload-pack

Please help me on this.

Collapse
 
richard_knowlden_df9a501a profile image
Richard Knowlden

Thank you and a clean implementation. Kudos to you

2 missing steps for completion. Hope you could add them for any future readers:

The below line is needed so that the browser works

kubectl port-forward service/node-service 32729:8000
Enter fullscreen mode Exit fullscreen mode

_* 32729 is the default assigned by KIND when you wont provide one. Otherwise you can provide one in the service.yaml _

apiVersion: v1
kind: Service
metadata:
  name: node-service
  namespace: default
spec:
  type: LoadBalancer
  selector:
    app: node-app
  ports:
  - port: 80
    targetPort: 8000
    nodePort: 30252
Enter fullscreen mode Exit fullscreen mode

Another thing missing in the dockerfile to expose the port 8000. Also, you code is pointing to port 8004

apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-app
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: node-app
  template:
    metadata:
      labels:
        app: node-app
    spec:
      containers:
      - name: node-app
        image: <DOCKER_REPO_USER_NAME_HERE>/node-image
        imagePullPolicy: Always
        ports:
        - containerPort: 8000

Enter fullscreen mode Exit fullscreen mode
Collapse
 
stumbinocodes profile image
stumbinocodes • Edited

Roughly how much is it to run a basic kubernetes stack in google cloud? Need to know for creating a basic blog post site.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.