Docker

Docker Compose ke Kubernetes: Panduan Migrasi Praktis untuk Developer

Docker Compose ke Kubernetes: Panduan Migrasi Praktis untuk Developer

Kalau lo udah nyaman pake Docker Compose buat development dan production di VPS — lo udah punya fondasi mental yang bener buat Kubernetes. Konsepnya mirip: define service, container, network, dan volume dalam file konfigurasi. Bedanya, Kubernetes lebih strict, lebih verbose, tapi skalanya jauh lebih gede.

Masalahnya: banyak developer yang nyoba migrasi ke Kubernetes karena FOMO ("semua pake K8s, masa gw enggak?") — padahal infrastruktur mereka cuma beberapa service di satu VPS. Hasilnya: over-engineering yang bikin maintenance makin ribet. Artikel ini breakdown kapan lo butuh Kubernetes, gimana migrasi dari Compose, dan yang paling penting — kapan lo jangan migrasi.

Kapan Lo Butuh Kubernetes (dan Kapan Tidak)

Sebelum migrasi, jawab pertanyaan ini dulu:

  • Lo jalanin >3 service yang perlu di-scale independent? Kalau cuma 1-2 service di satu VM, stay with Compose.
  • Lo butuh zero-downtime deployment? Kubernetes handle rolling update out of the box. Docker Compose bisa pake docker compose up -d --wait tapi resiko downtime lebih tinggi.
  • Tim lo lebih dari 3 orang? K8s punya RBAC, namespace isolation, dan audit logging. Buat solo developer, overhead-nya gak worth it.
  • Butuh auto-scaling? Compose gak punya horizontal scaling native — lo harus manual spin up instance baru di VPS lain.

Dari pengalaman gw di project migration client (platform e-commerce dengan ~12 microservices), sweet spot Kubernetes di sekitar 5-8 service yang jalan di 3+ node. Di bawah itu, Docker Compose di VPS mendingan — lebih simpel, maintenance lebih murah.

Mapping Compose ke K8s: Quick Reference

Docker ComposeKubernetesNote
services:Deployment + ServiceSatu service Compose = satu Deployment (untuk pod management) + satu Service (untuk networking)
ports:Service (NodePort/LB) + IngressIngress untuk HTTP/HTTPS, Service NodePort untuk port non-HTTP
volumes:PersistentVolumeClaimK8s gak punya named volumes otomatis — lo harus define PVC explicit
networks:NetworkPolicyDefault K8s allow semua pod communication — lo perlu restrict manual
environment:ConfigMap + SecretConfigMap untuk non-sensitive, Secret untuk credentials
depends_on:initContainers + readinessProbeK8s gak guarantee startup order — pake probe untuk health check
healthcheck:livenessProbe + readinessProbeDua probe beda fungsi — baca artikel HEALTHCHECK gw buat detailnya

Migrasi Step-by-Step: Dari Compose ke K8s

Step 1: Export Image dan Push ke Registry

# Build image yang sama
docker build -t myapp-api:latest .

# Tag dan push ke registry (Docker Hub / GHCR / registry lokal)
docker tag myapp-api:latest ghcr.io/username/myapp-api:v1.0
docker push ghcr.io/username/myapp-api:v1.0

# Repeat untuk tiap service di docker-compose.yml

K8s gak pull image dari local Docker daemon — semua image harus dari registry yang accessible oleh semua node.

Step 2: Convert docker-compose.yml ke K8s Manifests

Tools yang bisa lo pake:

  • Kompose (kompose convert) — auto-convert dari docker-compose.yml. Hasilnya lumayan bagus buat basic case, tapi perlu manual polish buat production.
  • Manual convert — lebih disarankan. Lo bener-bener ngerti tiap manifest.
# Install kompose
curl -L https://github.com/kubernetes/kompose/releases/latest/download/kompose-linux-amd64 -o kompose
chmod +x kompose && sudo mv kompose /usr/local/bin/

# Convert docker-compose.yml
kompose convert -o ./k8s-manifests/
# Hasil: deployment.yaml, service.yaml, dll

Step 3: Define Deployment

# api-deployment.yaml ��� analog dari service: api di docker-compose
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 2  # Scale horizontally
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api
        image: ghcr.io/username/myapp-api:v1.0
        ports:
        - containerPort: 3000
        envFrom:
        - configMapRef:
            name: app-config
        - secretRef:
            name: app-secrets
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 10
          periodSeconds: 15
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"

Step 4: Expose Service dengan Ingress

# api-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: api
spec:
  selector:
    app: api
  ports:
  - port: 3000
    targetPort: 3000

# ingress.yaml — untuk HTTPS + domain
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  rules:
  - host: api.toolkuy.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api
            port:
              number: 3000
  tls:
  - hosts:
    - api.toolkuy.com
    secretName: api-tls

Gotcha yang Gw Temuin Pas Migrasi

Volume Data Loss

Ini trap paling gede. Di Docker Compose, lo define volumes: - data:/var/lib/data dan data persist di Docker volume. Di Kubernetes, kalau lo delete Pod, data ilang — kecuali lo pake PersistentVolumeClaim (PVC) yang terikat ke persistent storage.

Solusi: buat PVC dulu, baru mount di Deployment. Buat database stateful, pake StatefulSet, bukan Deployment.

Startup Order

Compose punya depends_on yang guarantee container A mulai setelah container B. Kubernetes gak guarantee startup order. Dependency lo handle via initContainers yang nunggu service siap:

initContainers:
- name: wait-for-db
  image: busybox:1.36
  command: ['sh', '-c', 'until nc -z db 5432; do sleep 1; done']

Resource Request vs Limit

Di Docker Compose lo maybe gak pernah pake deploy.resources. Di K8s, selalu set request & limit. Request itu janji ke scheduler soal minimal resource yang dibutuhin. Limit itu batas maksimal. Tanpa ini, scheduler gak tau harus naruh pod di mana — hasilnya Pod bisa pending forever.

Testing Lokal: Kind vs Minikube

Sebelum deploy ke production, testing lokal dulu. Dua opsi:

  • Kind (Kubernetes in Docker) — jalan di Docker, setup cepet, cocok buat CI/CD. Startup time ~1 menit.
  • Minikube — VM-based, fitur lebih komplit, support addons kayak dashboard dan ingress controller. Butuh ~2GB RAM tambahan.

Gw prefer Kind buat testing migration karena bisa langsung pake image dari local Docker daemon tanpa push ke registry. Setup-nya:

# Install Kind
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.24.0/kind-linux-amd64
chmod +x ./kind && sudo mv ./kind /usr/local/bin/kind

# Create cluster
kind create cluster --name migration-test

# Load local image
kind load docker-image myapp-api:latest

# Apply manifests
kubectl apply -f ./k8s-manifests/

Kesimpulan: Migrasi atau Tidak?

Kalau lo masih pake 1-2 VPS dan service lo <10, jangan migrasi ke Kubernetes. Overhead operasionalnya gak sebanding. Tapi kalau lo udah di titik di mana:

  • Manual restart service karena VPS kehabisan resource jadi rutinitas
  • Zero-downtime deployment butuh script bash yang makin kompleks
  • Butuh auto-scaling yang prediktif

...maka Kubernetes jawabannya. Mulai dari Kind buat testing, deploy ke cluster kecil (3 node cukup), dan jangan lupa setup monitoring sebelum production.

Buat yang masih di fase optimasi Docker di VPS, artikel Docker multi-stage build dan BuildKit optimization lebih relevan — maksimalin dulu yang udah ada sebelum pindah ke K8s.

💬 Komentar (0)

Belum ada komentar. Jadilah yang pertama! 💬

Komentar akan muncul setelah moderasi.