September 27, 2026
Pengenalan Kubernetes.
Kenapa Kubernetes ada, objek dasarnya (Pod, Deployment, Service, Ingress/Gateway, ConfigMap, Secret), perintah kubectl sehari-hari, cluster lokal (kind, minikube, k3s), dan kapan Kubernetes justru berlebihan dibanding Docker Compose.
Docker menjawab pertanyaan “bagaimana mengemas dan menjalankan satu container?”. Kubernetes (K8s) menjawab pertanyaan berikutnya: “bagaimana menjalankan ratusan container di banyak server, tetap hidup ketika ada yang mati, dan bisa di-update tanpa downtime?”. Catatan ini adalah peta dasar untuk mulai, bukan panduan produksi.
1. Kenapa Kubernetes?
Dengan Docker/Compose di satu server, kamu yang bertanggung jawab atas:
- Restart container yang crash (sebagian bisa dengan
restart: always). - Memindahkan aplikasi ketika server mati.
- Menambah replika saat trafik naik dan membagi beban.
- Rolling update tanpa downtime dan rollback kalau versi baru rusak.
Kubernetes mengambil alih tugas tersebut dengan model deklaratif: kamu menulis keadaan yang diinginkan (“jalankan 3 replika image app:1.4”), lalu control plane terus-menerus membandingkan keadaan nyata dengan keinginan itu dan memperbaikinya (reconciliation loop).
Arsitektur singkat
| Komponen | Peran |
|---|---|
| Control plane | Otak cluster: kube-apiserver, etcd (penyimpanan state), scheduler, controller-manager |
| Node | Mesin (VM/fisik) tempat container berjalan |
| kubelet | Agen di tiap node yang menjalankan Pod sesuai perintah |
| Container runtime | containerd / CRI-O. Image hasil docker build tetap jalan karena formatnya standar OCI |
| kubectl | CLI untuk berbicara dengan API server |
2. Objek Dasar
| Objek | Analogi di Compose | Fungsi |
|---|---|---|
| Pod | Satu container (bisa lebih) | Unit terkecil; satu IP, berbagi network & volume. Jarang dibuat langsung |
| Deployment | services.app + deploy.replicas | Mengelola ReplicaSet → jumlah Pod, rolling update, rollback |
| Service | Nama service + DNS internal | IP & DNS stabil untuk sekumpulan Pod (Pod bisa mati dan berganti IP) |
| Ingress / Gateway API | Reverse proxy (Nginx/Caddy) | Routing HTTP(S) dari luar berdasarkan host/path |
| ConfigMap | environment: / file config | Konfigurasi non-rahasia |
| Secret | .env berisi password | Data sensitif (base64, bukan enkripsi secara default) |
| PersistentVolumeClaim | Named volume | Permintaan storage persisten |
| Namespace | Nama project Compose | Pengelompokan & isolasi resource |
Jenis Service:
| Type | Akses |
|---|---|
ClusterIP (default) | Hanya dari dalam cluster |
NodePort | Port tinggi (30000–32767) di setiap node |
LoadBalancer | IP publik dari cloud provider (atau MetalLB di bare-metal) |
3. Contoh Manifest
Satu file app.yaml berisi ConfigMap, Secret, Deployment, dan Service:
apiVersion: v1
kind: ConfigMap
metadata:
name: web-config
data:
APP_ENV: production
LOG_LEVEL: info
---
apiVersion: v1
kind: Secret
metadata:
name: web-secret
type: Opaque
stringData: # ditulis plain, disimpan sebagai base64
DB_PASSWORD: rahasia123
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginxdemos/hello:latest
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: web-config
- secretRef:
name: web-secret
resources:
requests: { cpu: 100m, memory: 64Mi }
limits: { memory: 128Mi }
readinessProbe:
httpGet: { path: /, port: 80 }
periodSeconds: 5
livenessProbe:
httpGet: { path: /, port: 80 }
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web # harus cocok dengan label Pod
ports:
- port: 80
targetPort: 80
Kuncinya adalah label & selector: Deployment dan Service menemukan Pod lewat label app: web, bukan lewat nama.
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
spec:
ingressClassName: traefik # sesuaikan dengan controller yang terpasang
rules:
- host: web.localtest.me
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
Ingress butuh Ingress controller yang terpasang di cluster (k3s membawa Traefik). Catatan penting: controller populer ingress-nginx sudah pensiun per Maret 2026 (tidak ada rilis & patch keamanan lagi). Untuk setup baru, pertimbangkan Gateway API (Gateway + HTTPRoute), yang kini menjadi arah resmi Kubernetes untuk routing trafik.
4. kubectl Dasar
kubectl apply -f app.yaml # buat/update resource secara deklaratif
kubectl get pods -o wide # daftar pod + node + IP
kubectl get deploy,svc,ingress
kubectl describe pod web-xxxx # detail + Events (paling berguna saat debug)
kubectl logs -f deploy/web # log
kubectl exec -it deploy/web -- sh # masuk ke container
kubectl port-forward svc/web 8080:80 # akses service dari laptop: localhost:8080
kubectl scale deploy/web --replicas=5
kubectl set image deploy/web web=nginxdemos/hello:plain-text
kubectl rollout status deploy/web
kubectl rollout undo deploy/web # rollback
kubectl delete -f app.yaml
kubectl config get-contexts # cluster mana yang sedang aktif
kubectl config use-context kind-dev
Status Pod yang sering muncul:
| Status | Penyebab umum |
|---|---|
Pending | Tidak ada node dengan resource cukup, atau PVC belum ter-bind |
ImagePullBackOff | Nama/tag image salah, registry privat tanpa imagePullSecrets |
CrashLoopBackOff | Aplikasi exit terus — cek kubectl logs --previous |
Running tapi tidak menerima trafik | readinessProbe gagal atau selector Service tidak cocok |
5. Cluster Lokal untuk Belajar
| Tool | Cara kerja | Cocok untuk |
|---|---|---|
| kind | Node K8s sebagai container Docker | CI, testing cepat, multi-node di laptop |
| minikube | VM atau container, banyak addon (minikube addons enable ingress) | Belajar, dashboard bawaan |
| k3s | Distribusi K8s ringan, satu binary | Home lab , VPS kecil, Raspberry Pi, edge |
| Docker Desktop | Kubernetes bawaan (aktifkan di Settings) | Coba cepat tanpa install apa pun |
Contoh dengan kind:
brew install kind kubectl
kind create cluster --name dev
kubectl cluster-info --context kind-dev
kubectl apply -f app.yaml
kubectl port-forward svc/web 8080:80
kind load docker-image myapp:dev --name dev # pakai image lokal tanpa push ke registry
kind delete cluster --name dev
Contoh k3s di server Linux (misal VM/LXC di Proxmox — lihat LXD dan Proxmox ):
curl -sfL https://get.k3s.io | sh -
sudo k3s kubectl get nodes
6. Kapan Kubernetes Berlebihan?
| Situasi | Pilihan wajar |
|---|---|
| Satu VPS, beberapa aplikasi, tim kecil | Docker Compose + reverse proxy |
| Side project, portofolio, aplikasi internal kantor | Compose, atau PaaS (Laravel Cloud, Fly, Render) |
| Butuh auto-scaling, banyak service, banyak server, zero-downtime deploy rutin | Kubernetes (sebaiknya managed: GKE, EKS, AKS, DOKS) |
| Ingin belajar skill DevOps/cloud-native | Kubernetes lokal (kind/k3s) |
Biaya tersembunyi Kubernetes: kurva belajar, YAML yang banyak, monitoring, upgrade cluster, storage & networking yang lebih rumit. Kalau docker compose up -d di satu server sudah cukup, tetaplah di Compose. Migrasi nanti relatif mudah karena image-nya sama; tool seperti Kompose
bahkan bisa mengonversi compose.yaml jadi manifest awal.
7. Pitfalls
- Secret bukan enkripsi. Base64 bisa dibaca siapa saja yang punya akses. Aktifkan encryption at rest / pakai Sealed Secrets atau External Secrets untuk produksi, dan jangan commit Secret ke Git.
- Tag
latestmembuat rollout tidak deterministik. Pakai tag versi atau digest. - Tanpa
resources.requests, scheduler tidak tahu kebutuhan Pod → node bisa overload. - Tanpa readiness probe, trafik dikirim ke Pod yang belum siap saat rolling update.
- Salah context →
kubectl deletedi cluster produksi. Cekkubectl config current-contextatau pakai tool sepertikubectx. - Data di Pod tanpa PVC hilang saat Pod dijadwal ulang. Database stateful di K8s butuh perhatian ekstra; sering lebih aman memakai managed database.
Catatan terkait: Docker Compose untuk Dev Environment , Docker Network , Docker Volume .
Referensi: Kubernetes Concepts , kubectl Quick Reference , Ingress NGINX Retirement , Gateway API , kind , k3s .

Hey! I’m Fanny, the software engineer tending to this digital garden. You can read more about me, or subscribe by email.