coderain guide

Deploying Your First Kubernetes Application: A Beginner's Walkthrough

Kubernetes (often called "K8s") has become the de facto standard for container orchestration, enabling developers to deploy, scale, and manage containerized applications with ease. If you’re new to Kubernetes, the idea of deploying your first app might seem daunting—terms like "pods," "deployments," and "services" can feel overwhelming. But fear not! This step-by-step guide will walk you through deploying a simple application on Kubernetes, using tools designed for beginners. By the end, you’ll have a working app running on a local Kubernetes cluster, and you’ll understand the core concepts behind how Kubernetes manages applications.

Table of Contents

  1. Prerequisites: What You’ll Need
  2. Setting Up a Local Kubernetes Cluster
  3. Creating a Sample Application
  4. Containerizing the Application with Docker
  5. Writing Kubernetes Manifests
  6. Deploying the Application to Kubernetes
  7. Verifying the Deployment
  8. Accessing Your Application
  9. Troubleshooting Common Issues
  10. Cleaning Up Resources
  11. References

Prerequisites: What You’ll Need

Before diving in, ensure you have the following tools installed. We’ll use these to set up a local cluster, build containers, and interact with Kubernetes:

1. kubectl

kubectl is the command-line tool for interacting with Kubernetes clusters. It lets you create, update, and delete resources like deployments and services.

  • Installation:
    • Windows: Use Chocolatey: choco install kubernetes-cli
    • macOS: Use Homebrew: brew install kubectl
    • Linux: Use curl:
      curl -LO "https://dl.k8s.io/release/v1.28.0/bin/linux/amd64/kubectl"  
      chmod +x kubectl  
      sudo mv kubectl /usr/local/bin/  
    • Verify installation: kubectl version --client

2. A Local Kubernetes Cluster

For beginners, we recommend minikube (a lightweight tool to run Kubernetes locally) or Docker Desktop (with Kubernetes enabled). We’ll use minikube in this guide.

  • Install minikube:

3. Docker

You’ll need Docker to build container images for your application.

4. A Docker Hub Account

Docker Hub is a public registry to store your container images (free for public repos). Sign up at hub.docker.com.


Setting Up a Local Kubernetes Cluster

With minikube installed, let’s start a local cluster. This cluster will run on your machine and simulate a production Kubernetes environment.

  1. Start minikube:

    minikube start  

    This downloads a Kubernetes ISO, starts a VM (or uses Docker as the driver), and initializes a single-node cluster.

  2. Verify the cluster is running:

    minikube status  

    You should see output like:

    minikube
    type: Control Plane
    host: Running
    kubelet: Running
    apiserver: Running
    kubeconfig: Configured  
  3. Check cluster nodes:

    kubectl get nodes  

    You’ll see one node (e.g., minikube) in the Ready state.


Creating a Sample Application

Let’s build a simple “Hello World” application to deploy. We’ll use Node.js (but feel free to adapt this to Python, Go, or another language).

Step 1: Set Up the App Files

Create a new directory (e.g., k8s-first-app) and add these files:

app.js (the application code):

const express = require('express');  
const app = express();  
const port = 3000;  

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

app.listen(port, () => {  
  console.log(`App running on port ${port}`);  
});  

package.json (dependencies):

{  
  "name": "k8s-first-app",  
  "version": "1.0.0",  
  "dependencies": {  
    "express": "^4.18.2"  
  }  
}  

Step 2: Test the App Locally

Before containerizing, test the app to ensure it works:

# Install dependencies  
npm install  

# Start the app  
node app.js  

Visit http://localhost:3000 in your browser—you should see “Hello from Kubernetes! 🚀“.


Containerizing the Application with Docker

Next, we’ll package the app into a Docker container. Containers ensure your app runs consistently across environments (your laptop, Kubernetes, etc.).

Step 1: Create a Dockerfile

In the k8s-first-app directory, create a file named Dockerfile (no extension) with:

# Use Node.js 18 as the base image  
FROM node:18-alpine  

# Set working directory in the container  
WORKDIR /app  

# Copy package files and install dependencies  
COPY package*.json ./  
RUN npm install  

# Copy the rest of the app code  
COPY . .  

# Expose port 3000 (the port the app runs on)  
EXPOSE 3000  

# Command to start the app  
CMD ["node", "app.js"]  

Step 2: Build the Docker Image

Build the image, tagging it with your Docker Hub username (replace YOUR_DOCKER_HUB_USERNAME with your actual username):

docker build -t YOUR_DOCKER_HUB_USERNAME/k8s-first-app:v1 .  
  • -t: Tags the image (format: registry/username/image-name:tag).
  • v1: A version tag (helps track updates).

Step 3: Push the Image to Docker Hub

Push the image to Docker Hub so Kubernetes can pull it:

  1. Log in to Docker Hub:

    docker login  

    Enter your Docker Hub username and password.

  2. Push the image:

    docker push YOUR_DOCKER_HUB_USERNAME/k8s-first-app:v1  

Kubernetes Manifests: Defining Your Application

Kubernetes uses YAML manifests to define how to run your application. We’ll create two manifests:

  1. Deployment: Manages a set of identical pods (the smallest deployable units in Kubernetes) and ensures they stay running.
  2. Service: Exposes your deployment to the outside world (or other apps in the cluster).

5.1 Deployment Manifest

A Deployment ensures your app has a specified number of replicas (pods) running. If a pod fails, the Deployment replaces it.

Create a file named deployment.yaml:

apiVersion: apps/v1  
kind: Deployment  
metadata:  
  name: k8s-first-app-deployment  
spec:  
  replicas: 2  # Run 2 pods  
  selector:  
    matchLabels:  
      app: k8s-first-app  # Matches labels on pods  
  template:  
    metadata:  
      labels:  
        app: k8s-first-app  # Label for pods  
    spec:  
      containers:  
      - name: k8s-first-app-container  
        image: YOUR_DOCKER_HUB_USERNAME/k8s-first-app:v1  # Your Docker Hub image  
        ports:  
        - containerPort: 3000  # Port the container exposes  

Key Fields Explained:

  • replicas: 2: Runs 2 copies of your app (for redundancy).
  • selector.matchLabels: Tells the Deployment which pods to manage (must match template.metadata.labels).
  • containers.image: The Docker image to run (replace with your Docker Hub image!).

5.2 Service Manifest

A Service exposes your Deployment so you can access the app. We’ll use a NodePort service, which opens a port on every cluster node to route traffic to the pods.

Create a file named service.yaml:

apiVersion: v1  
kind: Service  
metadata:  
  name: k8s-first-app-service  
spec:  
  selector:  
    app: k8s-first-app  # Matches pods with this label  
  ports:  
    - protocol: TCP  
      port: 80  # Service port (internal to the cluster)  
      targetPort: 3000  # Port on the pod to forward to  
      nodePort: 30080  # Port on the node (30000-32767 range)  
  type: NodePort  # Expose on a node port  

Key Fields Explained:

  • selector: Routes traffic to pods with label app: k8s-first-app.
  • nodePort: 30080: The port on the cluster node you’ll use to access the app (must be between 30000–32767).

Deploying the Application to Kubernetes

Now, let’s deploy the app using kubectl and the manifests.

Step 1: Apply the Deployment

Run:

kubectl apply -f deployment.yaml  

Output:

deployment.apps/k8s-first-app-deployment created  

Step 2: Apply the Service

Run:

kubectl apply -f service.yaml  

Output:

service/k8s-first-app-service created  

Verifying the Deployment

Let’s check if everything is running correctly.

1. Check Deployments

kubectl get deployments  

Output (look for READY: 2/2):

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE  
k8s-first-app-deployment   2/2     2            2           1m  

2. Check Pods

kubectl get pods  

Output (you’ll see 2 pods, status Running):

NAME                                        READY   STATUS    RESTARTS   AGE  
k8s-first-app-deployment-7f9b6c5d8-abc123   1/1     Running   0          2m  
k8s-first-app-deployment-7f9b6c5d8-def456   1/1     Running   0          2m  

3. Check the Service

kubectl get services  

Output (look for k8s-first-app-service):

NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE  
kubernetes                 ClusterIP   10.96.0.1       <none>        443/TCP        10m  
k8s-first-app-service      NodePort    10.102.235.78   <none>        80:30080/TCP   3m  

4. Check Pod Logs

Ensure the app is running inside the pod:

kubectl logs <POD_NAME>  # Replace with a pod name from `kubectl get pods`  

Output:

App running on port 3000  

Accessing Your Application

Now, let’s access the app from your local machine!

Step 1: Get the Cluster Node IP

Minikube runs the cluster in a VM, so we need its IP:

minikube ip  

Output (example): 192.168.49.2

Step 2: Access the App

Use the node IP and the nodePort (30080) from the service:

curl http://<MINIKUBE_IP>:30080  

Or open http://<MINIKUBE_IP>:30080 in your browser. You’ll see:

Hello from Kubernetes! 🚀  

Pro Tip: Use minikube service

For convenience, minikube can open the app automatically:

minikube service k8s-first-app-service  

Troubleshooting Common Issues

If things aren’t working, here are fixes for common problems:

Pod Not Starting?

Check pod details to see errors:

kubectl describe pod <POD_NAME>  

Service Not Accessible?

  • Labels Mismatch: Ensure service.spec.selector matches deployment.spec.template.metadata.labels (both should be app: k8s-first-app).
  • Incorrect NodePort: Use a port in the 30000–32767 range (e.g., 30080).

App Crashes Immediately?

Check pod logs:

kubectl logs <POD_NAME>  

Common issues: Missing dependencies (ensure npm install ran in the Docker build) or port conflicts.


Cleaning Up Resources

When you’re done, delete the deployment and service to free resources:

kubectl delete deployment k8s-first-app-deployment  
kubectl delete service k8s-first-app-service  

Stop the minikube cluster:

minikube stop  

(Optional) Delete the minikube VM:

minikube delete  

References

Congratulations! You’ve deployed your first Kubernetes application. 🎉 This is just the start—next, explore scaling, rolling updates, or deploying to a cloud Kubernetes service like EKS, GKE, or AKS.