
When your application grows, simply running containers with docker run or docker-compose up is no longer enough. You need a system that distributes load automatically, restarts crashed containers on its own, and deploys updates without downtime — that is exactly what Kubernetes does.
This article explains Kubernetes from the ground up. Whether you are a developer just learning about containers or a DevOps engineer ready to experiment on a VPS, you will find a clear path forward here.
Prerequisites: Basic familiarity with Docker and the concept of containers is helpful. If you are brand new to Docker, read What is Docker? first.
What is Kubernetes?
Kubernetes (pronounced "koo-ber-net-eez") — also known as K8s — is an open-source Container Orchestration Platform originally developed by Google and now maintained by the Cloud Native Computing Foundation (CNCF).
In simple terms, Kubernetes acts as a "container manager" that decides which machine your containers run on, how many copies should be running, and ensures they are always ready to handle traffic.
Name origin: "Kubernetes" comes from Greek, meaning "helmsman" or "captain" — reflecting its role in steering all containers in the right direction.
Problems Kubernetes Solves
Imagine you have a web app running across 3 containers on a single VPS. Suddenly traffic spikes and one container crashes because it ran out of RAM:
- Docker Compose cannot help — the container stays down until you manually restart it.
- Scaling up to 5 containers requires manual intervention — no automation.
- Deploying a new version without downtime requires careful manual coordination.
Kubernetes solves all of these with:
- Self-healing: If a container crashes, Kubernetes restarts it immediately.
- Auto-scaling: Automatically adds or removes containers based on CPU/Memory load.
- Rolling Updates: Updates containers one at a time with zero downtime.
- Load Balancing: Spreads incoming traffic evenly across all running containers.
Core Concepts You Need to Know
1. Cluster
A Cluster is a group of machines (Nodes) working together under Kubernetes. Every cluster has a Control Plane (the central brain) and one or more Worker Nodes (where containers actually run).
2. Node
A Node is a single machine in the cluster — this can be a VPS or a physical server. There are two types:
- Control Plane Node: Manages the entire cluster and decides which Node each Pod runs on.
- Worker Node: Executes the Pods as instructed by the Control Plane.
3. Pod
A Pod is the smallest deployable unit in Kubernetes. It contains one or more containers (typically one container per Pod). Each Pod gets its own IP address and all containers within the same Pod share a network namespace.
4. Deployment
A Deployment is a template that tells Kubernetes: "I need exactly X copies of this Pod running at all times." If a Pod crashes, the Deployment immediately creates a replacement Pod.
5. Service
A Service provides a stable IP address and DNS name to reach your Pods. Because Pod IPs can change, Services act as the consistent entry point that routes incoming traffic to the correct running Pods.
Kubernetes vs Docker Compose — Key Differences
Most Docker users start with Docker Compose. Both tools manage containers, but they are suited for very different scales:
| Feature | Docker Compose | Kubernetes |
|---|---|---|
| Machines | Single machine | Multiple machines (multi-node) |
| Self-healing | No (only restart: always) | Yes — new Pod created automatically |
| Auto-scaling | No | Yes (HPA) |
| Rolling Updates | Must stop and restart | Zero-downtime rolling updates |
| Load Balancing | Basic (manual Nginx) | Built-in |
| Complexity | Low | High (learning curve) |
| Best for | Dev/Test, small production | Medium-to-large production |
Helm: The Package Manager for Kubernetes
Helm is the package manager for Kubernetes — similar to apt on Ubuntu or pip in Python. Instead of writing dozens of YAML files to deploy an application, Helm lets you install complex applications with a single command.
How Helm Works
Helm uses the concept of "Charts" — packaged sets of YAML templates with configurable default values:
| Concept | Description | Analogy |
|---|---|---|
| Chart | Set of YAML templates for an application | Package (.deb/.rpm) |
| Release | A running instance of a Chart on the cluster | Installed process |
| Repository | Community collection of Charts | apt-get repository |
| values.yaml | File for customizing Chart settings | Configuration file |
Install Helm and Get Started
# Install Helm on Linux
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Add the official Helm repository
helm repo add stable https://charts.helm.sh/stable
helm repo update
# Install Nginx Ingress Controller with a single command
helm install my-nginx ingress-nginx/ingress-nginx
# List installed releases
helm list
# Uninstall
helm uninstall my-nginx
Helm saves substantial time when deploying applications with many components. For example, deploying WordPress on Kubernetes requires a Deployment, Service, PersistentVolume, ConfigMap, and Secret — Helm handles all of that in one command.
Who Should Use Kubernetes?
Kubernetes is not the right tool for every project. It makes sense when you have:
- Microservices architecture: An app split into many independent services (API, Auth, Notifications, etc.).
- Unpredictable traffic: Need to scale up or down automatically based on load.
- High availability requirements: Cannot tolerate downtime even if one machine fails.
- Frequent CI/CD deployments: Need to release updates often without affecting production.
- Multiple environments: Dev, Staging, and Production on the same infrastructure.
⚠️ Not recommended for: Small projects or apps running just 1–3 containers. The operational overhead of Kubernetes is significantly higher than Docker Compose. If you do not genuinely need it, Docker Compose is the better choice.
Managing Secrets and ConfigMaps Securely
Kubernetes provides two dedicated resource types for managing configuration separately from your container images. This keeps your applications secure and flexible without baking credentials into Docker images.
ConfigMap — For Non-Sensitive Configuration
Use ConfigMaps to store configuration values like service URLs, feature flags, and database names that do not need to be kept secret:
# Create a ConfigMap from literal values
kubectl create configmap app-config \
--from-literal=DB_HOST=mysql-service \
--from-literal=APP_ENV=production \
--from-literal=MAX_CONNECTIONS=100
# Inspect the ConfigMap
kubectl describe configmap app-config
Secret — For Sensitive Credentials
Use Secrets to store passwords, API keys, and tokens that should never appear in source code. Kubernetes stores Secrets Base64-encoded (enable Encryption at Rest for stronger protection):
# Create a Secret
kubectl create secret generic db-credentials \
--from-literal=DB_PASSWORD=MyStr0ngP@ss \
--from-literal=DB_USER=appuser
# Inspect (values will be Base64-encoded)
kubectl get secret db-credentials -o yaml
Using ConfigMap and Secret Inside a Pod
# Deployment example using both ConfigMap and Secret
spec:
containers:
- name: myapp
image: myapp:latest
envFrom:
- configMapRef:
name: app-config # Load all keys from ConfigMap
- secretRef:
name: db-credentials # Load secrets as environment variables
Security warning: Never commit Secret values directly to a Git repository. Create Secrets through kubectl directly on the cluster, or use an external Secret Manager such as HashiCorp Vault integrated with Kubernetes for production workloads.
Getting Started with k3s on a VPS
k3s is a lightweight, production-grade Kubernetes distribution developed by Rancher Labs. It uses only ~512MB of RAM and installs in a single command — perfect for experimenting on a VPS.
System Requirements
- VPS running Ubuntu 20.04 or 22.04 (≥1GB RAM recommended)
- Root or sudo access
- Port 6443 open for the Kubernetes API
Step 1 — Install k3s
Run a single command to install k3s and start your first Control Plane node:
curl -sfL https://get.k3s.io | sh -
Verify the installation:
sudo systemctl status k3s sudo kubectl get nodes
If your Node shows a status of Ready, k3s is running successfully.
Step 2 — Deploy a Test Application (Nginx)
Create a Deployment YAML file:
# nginx-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-demo spec: replicas: 3 # keep 3 Pods running at all times selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80
sudo kubectl apply -f nginx-deployment.yaml
Check that all three Pods are running:
sudo kubectl get pods
You should see 3 Pods with a Running status.
Step 3 — Expose the App with a Service
# nginx-service.yaml apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: NodePort selector: app: nginx ports: - port: 80 targetPort: 80 nodePort: 30080 # accessible at http://YOUR_VPS_IP:30080
sudo kubectl apply -f nginx-service.yaml
Open a browser and navigate to http://YOUR_VPS_IP:30080. The response is automatically served by one of the 3 running Pods.
Step 4 — Test Self-healing
Delete a Pod manually and watch Kubernetes recreate it:
# List pods and copy a pod name sudo kubectl get pods # Delete one pod (replace with actual pod name) sudo kubectl delete pod nginx-demo-xxxxxxx-xxxxx # Watch the replacement pod being created sudo kubectl get pods
Within seconds, Kubernetes brings the Pod count back to 3. This is self-healing in action.
What is kubectl? kubectl (pronounced "kube-control") is the command-line tool for managing everything in Kubernetes — deploying apps, scaling, inspecting logs, and deleting resources.
Monitoring Kubernetes with Prometheus and Grafana
Monitoring is essential for any production Kubernetes cluster. Prometheus (for collecting metrics) and Grafana (for visualizing them) form the most widely adopted monitoring stack in the Kubernetes ecosystem.
Key Metrics to Monitor in Kubernetes
- Pod CPU/Memory Usage: Identify Pods consuming excessive resources or being OOMKilled.
- Node Resource Utilization: CPU, RAM, and disk usage per Node.
- Pod Restart Count: Frequent restarts usually signal an underlying problem.
- API Server Latency: Response time of the Kubernetes control plane.
- Network I/O: Inbound and outbound traffic volume per Pod.
Install kube-prometheus-stack with Helm
The fastest way to get a complete monitoring setup is using the community Helm Chart that bundles Prometheus, Grafana, and AlertManager with pre-built Kubernetes dashboards:
# Add the Prometheus community Helm repository
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# Install kube-prometheus-stack
helm install monitoring prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace
# Verify Pods are running
kubectl get pods -n monitoring
# Access Grafana via port-forward
kubectl port-forward -n monitoring \
svc/monitoring-grafana 3000:80
Open http://localhost:3000 in a browser. Log in with username admin and the password retrieved from the Secret:
kubectl get secret -n monitoring monitoring-grafana \
-o jsonpath="{.data.admin-password}" | base64 --decode
k3s compatibility note: When running on k3s, add these flags to the install command: --set kubeEtcd.enabled=false --set kubeScheduler.enabled=false --set kubeControllerManager.enabled=false. k3s bundles these components differently from standard Kubernetes.
Kubernetes Architecture at a Glance
A Kubernetes Cluster is made up of several key components:
- kube-apiserver: The front door of the cluster — all requests pass through it.
- etcd: A key-value database that stores the entire state of the cluster.
- kube-scheduler: Decides which Node a new Pod should run on.
- kube-controller-manager: Ensures Deployments always have the correct number of Pods.
- kubelet: The agent on each Worker Node that carries out Control Plane instructions.
- kube-proxy: Manages network routing rules on each Worker Node.
Rolling Updates and Safe Rollbacks
One of Kubernetes' most powerful features is the ability to update applications without any downtime and roll back to a previous version within seconds if something goes wrong.
Performing a Rolling Update
To update the container image to a new version:
# Update the Deployment image
kubectl set image deployment/nginx-demo \
nginx=nginx:1.25 \
--record
# Watch rollout status in real time
kubectl rollout status deployment/nginx-demo
# View full rollout history
kubectl rollout history deployment/nginx-demo
During a rolling update, Kubernetes replaces Pods one at a time (according to the configured strategy). It waits for each new Pod to become Ready before removing the old one, ensuring continuous service availability.
Rolling Back When Something Goes Wrong
# Immediately roll back to the previous version
kubectl rollout undo deployment/nginx-demo
# Roll back to a specific revision (e.g., revision 2)
kubectl rollout undo deployment/nginx-demo --to-revision=2
# Verify the rollback succeeded
kubectl get pods -l app=nginx
Configuring the Update Strategy
Control update behavior through the strategy field in your Deployment YAML:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # Max Pods that can be unavailable simultaneously
maxSurge: 1 # Max extra Pods allowed above the replica count
Best practice: Always test deployments on a Staging cluster before promoting to Production. Use the --record flag to maintain rollout history, giving your team visibility into who deployed what and when.
Recommended Learning Path
If you are just getting started, follow these steps in order:
- Master Docker first — understand Containers, Images, Volumes, and Networks.
- Try k3s on a single VPS — follow the hands-on steps in this article.
- Learn YAML Manifests: Deployment, Service, ConfigMap, Secret.
- Graduate to Managed Kubernetes: When ready, platforms like EKS, GKE, or AKS manage the Control Plane for you automatically.
VPS for Kubernetes: k3s requires a minimum of ~512MB RAM, but 1–2GB is recommended for comfortable experimentation. For a multi-node cluster in real production, plan for at least 2GB RAM per Node.
Full Root Access VPS — Ready for Kubernetes
Install k3s, Docker, and any DevOps tool you need with complete server control. VPS plans starting from 500 THB/month. Locations: Thailand, Singapore.
View VPS Plans