Panduan Kubernetes dan Orkestrasi Container
Pengantar praktis Kubernetes untuk tim development yang siap beralih dari manajemen container manual ke orkestrasi production-grade.
Mengapa Container Mengubah Segalanya
Sebelum container, men-deploy aplikasi berarti mengkonfigurasi server, menginstal dependensi, mengelola konflik antar versi aplikasi, dan berharap apa yang berjalan di laptop developer akan berjalan di production. Container menyelesaikan ini dengan mengemas aplikasi, dependensinya, dan runtime environment ke dalam satu unit portabel.
Docker membuat container dapat diakses. Tapi menjalankan beberapa container di satu server itu sederhana. Menjalankan puluhan atau ratusan container di beberapa server, menjaga kesehatannya, menskalakan berdasarkan permintaan, dan memperbarui tanpa downtime membutuhkan orkestrasi. Di situlah Kubernetes berperan.
Arsitektur Kubernetes
Control Plane
Kubernetes beroperasi pada model master-worker. Control plane mengelola cluster:
- API Server: Pintu depan untuk semua perintah manajemen. Setiap perintah
kubectlberkomunikasi dengan komponen ini. - etcd: Penyimpanan key-value terdistribusi yang menyimpan seluruh state cluster. Jika etcd kehilangan data, cluster kehilangan memorinya.
- Scheduler: Memutuskan worker node mana yang harus menjalankan pod baru berdasarkan ketersediaan resource, aturan affinity, dan batasan.
- Controller Manager: Menjalankan loop background yang memastikan state aktual sesuai dengan state yang diinginkan. Jika Anda meminta tiga replika dan satu mati, controller membuat penggantinya.
Worker Node
Setiap worker node menjalankan:
- kubelet: Agen yang menerima instruksi dari control plane dan mengelola pod di node
- Container runtime: Software yang benar-benar menjalankan container (containerd, CRI-O)
- kube-proxy: Menangani aturan jaringan agar pod dapat berkomunikasi satu sama lain dan dengan klien eksternal
Pod
Pod adalah unit terkecil yang dapat di-deploy di Kubernetes. Pod berisi satu atau lebih container yang berbagi networking dan storage:
apiVersion: v1
kind: Pod
metadata:
name: web-app
labels:
app: web
tier: frontend
spec:
containers:
- name: app
image: registry.example.com/web-app:1.4.2
ports:
- containerPort: 3000
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 15
Selalu set resource requests dan limits. Tanpanya, satu pod yang bermasalah bisa mengonsumsi semua resource node dan membuat yang lain kelaparan.
Objek Kubernetes Esensial
Deployment
Anda jarang membuat pod secara langsung. Sebagai gantinya, Anda membuat Deployment yang mengelola sekumpulan pod identik:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: app
image: registry.example.com/web-app:1.4.2
ports:
- containerPort: 3000
Deployment memastikan tiga replika selalu berjalan. Saat Anda memperbarui versi image, ia melakukan rolling update: menjalankan pod baru sebelum menghentikan yang lama. Setting maxUnavailable: 0 berarti zero downtime selama update.
Service
Pod mendapat alamat IP acak yang berubah saat restart. Service menyediakan endpoint jaringan yang stabil:
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
type: ClusterIP
selector:
app: web
ports:
- port: 80
targetPort: 3000
Tipe Service meliputi:
- ClusterIP: Internal saja. Pod lain dalam cluster dapat menjangkaunya.
- NodePort: Mengekspos service di IP setiap node pada port statis.
- LoadBalancer: Membuat load balancer eksternal (bekerja dengan cloud provider).
ConfigMap dan Secret
Eksternalisasi konfigurasi dari container image Anda:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DATABASE_HOST: "postgres-service"
LOG_LEVEL: "info"
CACHE_TTL: "300"
Secret bekerja serupa tapi mengenkode nilai dalam base64 dan dapat dienkripsi saat disimpan:
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
DATABASE_PASSWORD: cGFzc3dvcmQxMjM=
Jangan pernah commit manifest Secret dengan nilai asli ke version control. Gunakan tools manajemen secret eksternal seperti Sealed Secrets atau integrasikan dengan secret manager cloud provider Anda.
Scaling dan Auto-scaling
Horizontal Pod Autoscaler
Skalakan pod berdasarkan utilisasi CPU, penggunaan memori, atau metrik kustom:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Ini mempertahankan dua hingga sepuluh replika, menambah pod saat rata-rata CPU melebihi 70% dan menghapusnya saat turun.
Cluster Autoscaler
Saat pod tidak bisa dijadwalkan karena tidak ada node yang memiliki resource cukup, Cluster Autoscaler menyediakan node tambahan dari cloud provider Anda. Saat node kurang dimanfaatkan, ia menguras dan menghapusnya.
Networking
Ingress Controller
Ingress mendefinisikan akses eksternal ke service, biasanya routing HTTP/HTTPS:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- app.example.com
secretName: app-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-service
port:
number: 80
Ingress controller populer termasuk NGINX, Traefik, dan opsi cloud-native seperti AWS ALB Ingress Controller.
Network Policy
Secara default, setiap pod dapat berkomunikasi dengan setiap pod lainnya. Network Policy membatasinya:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-policy
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- podSelector:
matchLabels:
app: web
ports:
- port: 8080
Ini hanya mengizinkan pod berlabel app: web untuk terhubung ke pod API di port 8080. Semua traffic lainnya ditolak.
Observability
Tiga Pilar
Menjalankan container di production membutuhkan visibilitas ke apa yang terjadi:
- Logging: Agregasi log dari semua pod ke sistem terpusat (ELK stack, Grafana Loki)
- Metrics: Kumpulkan CPU, memori, request rate, dan error rate (Prometheus + Grafana)
- Tracing: Ikuti request melintasi beberapa service (Jaeger, Zipkin)
Health Check
Kubernetes menggunakan probe untuk menentukan kesehatan pod:
- Liveness probe: Apakah container masih berjalan? Jika gagal, Kubernetes me-restart container.
- Readiness probe: Apakah container siap menerima traffic? Jika gagal, pod dihapus dari service endpoint.
- Startup probe: Apakah container sudah selesai startup? Berguna untuk aplikasi yang lambat memulai.
Konfigurasi ketiganya untuk workload production. Pod tanpa health check adalah pod yang tidak bisa di-self-heal oleh Kubernetes.
Checklist Production Readiness
Sebelum menjalankan workload di production:
- Resource requests dan limits di-set untuk semua container
- Liveness dan readiness probe dikonfigurasi
- Pod Disruption Budget didefinisikan untuk service kritikal
- Network Policy membatasi komunikasi yang tidak perlu
- Secret dikelola secara eksternal, bukan di manifest plain text
- Logging, metrics, dan alerting sudah berjalan
- Horizontal Pod Autoscaler dikonfigurasi untuk workload variabel
- Isolasi namespace antar environment (dev, staging, production)
- Kebijakan RBAC membatasi siapa yang bisa melakukan apa di setiap namespace
- Prosedur backup dan disaster recovery sudah diuji
Memulai
Mulai dari kecil. Containerisasi satu aplikasi, deploy ke managed Kubernetes service (GKE, EKS, AKS, atau cluster lokal dengan k3s), dan pelajari workflow-nya. Tambah kompleksitas secara bertahap: service, ingress, autoscaling, monitoring.
Kubernetes memiliki learning curve yang curam, tapi manfaat operasional untuk workload production sangat substansial. Automated healing, rolling update, scaling, dan manajemen resource membebaskan tim Anda untuk fokus membangun aplikasi, bukan mengasuh server.