Deploying software to a real cluster is the fastest way to move from Kubernetes theory to hands-on mastery. If you’ve read about Pods, Deployments, or Services but haven’t felt the thrill of watching a deleted Pod spring back to life automatically, now is the time to bridge that gap.
In this beginner-friendly walkthrough, you’ll containerize a simple Node.js app, spin up a local Kubernetes environment, and launch three replicas behind a load-balancing service. You can choose between Minikube and Kind, two popular tools that provide a lightweight cluster inside your laptop. By the end, you’ll have a working app, a Deployment that keeps it alive, and a Service that routes traffic across Pods—plus firsthand experience with self-healing and scaling.
Choose your cluster setup: Minikube vs. Kind
Both Minikube and Kind give you a fully featured Kubernetes control plane on your computer, but they take different approaches.
- Minikube bundles a virtual machine with a built-in registry and an easy browser launcher, making the onboarding process smoother for newcomers.
- Kind runs nodes as Docker containers, so it starts in seconds and feels lighter if Docker is already on your machine.
Pick one and install only the prerequisites for that path.
Prerequisites checklist
Before you begin, confirm you have the following installed:
- Docker – required by both Minikube and Kind to run containerized nodes
- kubectl – the standard command-line interface for interacting with Kubernetes clusters
- Either Minikube or Kind, depending on your preference
Part 1: Spin up a local Kubernetes cluster
Follow the steps for the tool you selected. Each path ends with the same verification step: a healthy control-plane node ready for workloads.
Option A: Launch Minikube in 5 minutes
Install Minikube using your system’s package manager, then start the cluster.
macOS (Homebrew):
brew install minikubeLinux:
curl -LO
sudo install minikube-linux-amd64 /usr/local/bin/minikubeWindows (via winget):
winget install Kubernetes.minikubeStart the cluster and verify the node status:
minikube start
kubectl get nodesYou should see output similar to:
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 15s v1.28.3Option B: Spin up Kind in seconds
Install Kind, create a cluster, and confirm it’s ready.
macOS (Homebrew):
brew install kindLinux:
curl -Lo ./kind
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kindWindows (via Chocolatey):
choco install kindCreate a single-node cluster named hello-cluster:
kind create cluster --name hello-cluster
kubectl get nodesThe output confirms the node is Ready and ready to accept workloads.
Part 2: Build a minimal Node.js application
Create a new project directory and write a tiny web server that reports its Pod name.
mkdir k8s-hello && cd k8s-helloAdd app.js:
const http = require('http');
const os = require('os');
const server = http.createServer((req, res) => {
res.end(`Hello from Pod: ${os.hostname()}\n`);
});
server.listen(3000, () => console.log('Running on port 3000'));This server responds with the hostname of the Pod serving the request, proving load balancing later.
Next, create a Dockerfile to containerize the app:
FROM node:18-alpine
WORKDIR /app
COPY app.js .
CMD ["node", "app.js"]Part 3: Create and load the container image
The build step differs depending on your cluster choice because Minikube and Kind handle local images differently.
For Minikube users
Point your local Docker CLI at Minikube’s internal Docker daemon so images land inside the cluster automatically.
eval $(minikube docker-env)
docker build -t hello-app:v1 .From now on, Minikube can pull hello-app:v1 without accessing Docker Hub.
For Kind users
Build the image using your host Docker, then explicitly import it into the cluster.
docker build -t hello-app:v1 .
kind load docker-image hello-app:v1 --name hello-clusterSkipping the kind load command is the most common beginner mistake; without it, Pods stall in ImagePullBackOff because the image doesn’t exist inside Kind’s nodes.
Part 4: Define the Kubernetes resources
Create a single YAML file that declares a Deployment, a ReplicaSet, and a Service.
Save it as deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deployment
spec:
replicas: 3
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello
image: hello-app:v1
imagePullPolicy: Never
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: hello-service
spec:
type: NodePort
selector:
app: hello
ports:
- port: 80
targetPort: 3000
nodePort: 30080Key takeaways:
- The Deployment keeps exactly three Pods running at all times and manages automatic restarts.
- The ReplicaSet is generated automatically to enforce the replica count.
- The Service uses the
app: hellolabel selector to route traffic to matching Pods. imagePullPolicy: Neverensures Kubernetes uses the local image instead of pulling from a registry.
Part 5: Deploy the stack and verify
Apply the configuration and watch the system spring to life:
kubectl apply -f deployment.yamlCheck that everything deployed successfully:
kubectl get pods
kubectl get replicaset
kubectl get service hello-serviceWait until all three Pods show Running before moving on.
Part 6: Open the app and see load balancing in action
With Minikube
Launch the service in your default browser with one command:
minikube service hello-serviceWith Kind
Kind doesn’t expose NodePort services directly, so forward a local port and open the URL manually:
kubectl port-forward service/hello-service 8080:80Then visit ` in your browser and refresh a few times. Each response prints the Pod name, proving the Service is distributing traffic across all three replicas.
Part 7: Experiment to solidify your understanding
Now that the app is live, try these quick tests to see Kubernetes behaviors firsthand:
- Self-healing: Delete a Pod with
kubectl delete pod <pod-name>and watch the Deployment immediately create a replacement. - Scaling: Change the replica count in
deployment.yamland reapply it to see more Pods spin up in seconds. - Rolling update: Edit the image tag to
hello-app:v2, rebuild, reload into the cluster, update the YAML, and observe the zero-downtime rollout.
Each exercise reveals a core principle of Kubernetes, turning abstract concepts into concrete experience.
The next time you read Kubernetes documentation, you’ll recognize the moving parts you’ve already worked with in your own cluster. From here, explore Ingress for routing rules or Helm for packaging your apps—your local Kubernetes playground is ready whenever you are.
AI summary
Learn how to deploy your first Node.js app on a local Kubernetes cluster using Minikube or Kind. Step-by-step tutorial with commands and tips.