Containerizing Microservices with Docker Swarm vs Kubernetes
1. Konteks Industri & Analisis Akar Masalah
Dalam lanskap arsitektur web modern, transisi dari monolitik ke arsitektur berbasis microservices telah memecah aplikasi web kompleks menjadi puluhan atau ratusan komponen independen. Komponen-komponen ini—mulai dari frontend berbasis React/Next.js, backend service Node.js/Go, sistem queue dengan Redis, hingga database cluster MySQL/MariaDB—membutuhkan infrastruktur yang dapat diandalkan, skalabel, dan terisolasi dengan baik. Di sinilah teknologi containerization dan orchestration menjadi fondasi mutlak.
Namun, mengelola ratusan container secara manual menggunakan perintah docker run tunggal di lingkungan produksi adalah resep bencana. Bottleneck performa, kegagalan jaringan internal (service discovery), kerentanan keamanan akibat konfigurasi izin yang salah, serta kompleksitas manajemen persistent storage sering kali menjadi momok bagi DevOps Engineer. Sebelum penerapan orkestrasi otomatis, tim infrastruktur sering menghadapi masalah seperti:
- Downtime saat rolling update karena tidak ada mekanisme health check dan traffic draining yang terintegrasi.
- Ketergantungan server tunggal (Single Point of Failure) di mana kegagalan node fisik mematikan seluruh ekosistem web.
- Konfigurasi jaringan manual menggunakan reverse proxy eksternal yang rapuh terhadap perubahan topologi dynamic IP container.
Dengan menerapkan sistem orkestrasi seperti Docker Swarm atau Kubernetes (K8s), kita beralih dari manajemen server manual ke manajemen declarative state. Sistem orkestrasi memastikan bahwa kondisi aktual infrastruktur selalu selaras dengan kondisi yang diinginkan (desired state). Artikel ini akan membedah secara mendalam, teknis, dan komprehensif perbandingan antara Docker Swarm dan Kubernetes untuk membantu Anda memilih solusi yang tepat bagi infrastruktur enterprise Anda.
2. Konsep Inti & Deep Dive Arsitektur
Untuk memahami perbedaan operasional antara Docker Swarm dan Kubernetes, kita harus melihat bagaimana arsitektur kendali (control plane) dan eksekusi (worker nodes) dirancang di balik layar.
Docker Swarm Architecture
Docker Swarm terintegrasi langsung ke dalam Docker Engine. Arsitekturnya terdiri dari:
- Manager Node: Bertanggung jawab atas cluster management, penjadwalan service (scheduling), dan menjaga cluster state menggunakan algoritma konsensus Raft.
- Worker Node: Menerima tugas dari Manager dan menjalankan container menggunakan Docker daemon lokal.
- Ingress Mesh Routing: Menggunakan IPVS (IP Virtual Server) bawaan untuk merutekan traffic eksternal ke port service yang dipublikasikan di node manapun, terlepas dari apakah node tersebut menjalankan container yang dituju atau tidak.
+-------------------------------------------------------------+
| DOCKER SWARM |
| |
| +-------------------+ +-------------------+ |
| | Manager Node | -- Raft --> | Manager Node | |
| | (Control Plane) | | (Control Plane) | |
| +-------------------+ +-------------------+ |
| | | |
| +----------------+----------------+ |
| | |
| +-----------------+ |
| | Worker Node | |
| | (Docker Daemon)| |
| +-----------------+ |
+-------------------------------------------------------------+
Kubernetes (K8s) Architecture
Kubernetes adalah platform orkestrasi yang jauh lebih kompleks dan modular:
- Control Plane: Terdiri dari
kube-apiserver(titik masuk utama),etcd(penyimpanan key-value terdistribusi untuk semua data cluster),kube-scheduler(menentukan penempatan pod), dankube-controller-manager(mengatur loop rekonsiliasi). - Worker Node: Berisi
kubelet(agen yang berkomunikasi dengan control plane),kube-proxy(mengatur aturan jaringan lokal), dan container runtime (seperti Containerd atau CRI-O). - Pod: Unit terkecil yang dapat di-deploy di K8s, dapat berisi satu atau lebih container yang berbagi network namespace dan storage volumes.
+-----------------------------------------------------------------------+
| KUBERNETES |
| |
| +---------------------------------------------------------------+ |
| | CONTROL PLANE | |
| | [kube-apiserver] <---> [etcd] | |
| | ^ ^ | |
| | v v | |
| | [kube-scheduler] <---> [kube-controller-manager] | |
| +---------------------------------------------------------------+ |
| | |
| v |
| +---------------------------------------------------------------+ |
| | WORKER NODE | |
| | [kubelet] <---> [Container Runtime (Containerd/Docker)] | |
| | [kube-proxy] <---> [Pods (Containers)] | |
| +---------------------------------------------------------------+ |
+-----------------------------------------------------------------------+
3. Perbandingan Komparatif / Analisis Pendekatan
| Parameter / Fitur | Docker Swarm | Kubernetes (K8s) | Dampak Produksi & Sumber Daya |
|---|---|---|---|
| Kurva Pembelajaran | Sangat Rendah (Native Docker CLI) | Tinggi (Konsep baru: Pod, Deployment, Ingress) | Swarm menghemat waktu setup awal tim kecil. K8s membutuhkan pelatihan intensif. |
| Resource Overhead | Minimal (< 50MB RAM tambahan per node) | Tinggi (Control plane membutuhkan minimal 2GB RAM per master) | K8s boros resource pada skala kecil/menengah. |
| Service Discovery | Built-in DNS otomatis berbasis nama service | Built-in CoreDNS dengan dukungan environment variables & DNS | Keduanya handal, K8s lebih fleksibel dengan headless services. |
| Load Balancing | Ingress mesh routing sederhana (Layer 4) | Ingress Controllers canggih (Layer 7, SSL Termination, Path-based) | K8s ideal untuk routing aplikasi web kompleks berbasis domain/path. |
| Autoscaling | Terbatas (Service scale manual atau tool eksternal) | Horizontal Pod Autoscaler (HPA) & Cluster Autoscaler native | K8s unggul dalam penanganan traffic spike otomatis. |
| Ekosistem & Ekstensi | Terbatas pada ekosistem Docker | Masif (Helm, Prometheus, Istio, ArgoCD, Operator Pattern) | K8s adalah standar industri untuk infrastruktur cloud-native modern. |
[!WARNING] Jangan pernah mencoba mengimplementasikan Kubernetes hanya untuk menjalankan aplikasi web sederhana dengan 2-3 container. Overhead operasional dan kompleksitas debugging (seperti error
CrashLoopBackOffatauImagePullBackOff) akan menghabiskan waktu produktif tim engineering Anda.
4. Prasyarat Sistem & Persiapan Lingkungan
Sebelum melakukan deployment, pastikan sistem operasi host memenuhi spesifikasi enterprise berikut:
- OS: Ubuntu Server 22.04 LTS / Debian 12 (Disarankan kernel Linux >= 5.15 untuk performa overlay network eBPF/IPVS).
- Spesifikasi Minimum Node (Docker Swarm): 1 vCPU, 2 GB RAM, 20 GB NVMe SSD.
- Spesifikasi Minimum Control Plane (Kubernetes): 2 vCPU, 4 GB RAM, 40 GB NVMe SSD.
- Jaringan: Port TCP/UDP yang wajib dibuka:
- Docker Swarm:
2377/tcp(cluster management),7946/tcp/udp(node communication),4789/udp(overlay network). - Kubernetes:
6443/tcp(API server),2379-2380/tcp(etcd server),10250/tcp(Kubelet API),30000-32767/tcp(NodePort Services).
- Docker Swarm:
Persiapan Kernel & Firewall ( dijalankan di setiap Node )
# Menonaktifkan Swap (Wajib untuk Kubernetes dan disarankan untuk Swarm)
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab
# Mengaktifkan modul kernel yang dibutuhkan untuk container networking
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# Pengaturan sysctl untuk bridging network
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
5. Panduan Implementasi Langkah demi Langkah
Berikut adalah implementasi nyata untuk mendesploy arsitektur web microservices yang terdiri dari Nginx (Web Server/Reverse Proxy), Node.js (Backend API), dan Redis (Cache) menggunakan Docker Swarm dan Kubernetes. Kita asumsikan kedua lingkungan telah terinisialisasi.
Pendekatan A: Docker Swarm Deployment (docker-stack.yml)
Simpan file ini dengan nama docker-stack.yml di server Manager.
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- nginx_logs:/var/log/nginx
deploy:
replicas: 2
restart_policy:
condition: on-failure
update_config:
parallelism: 1
delay: 10s
networks:
- webnet
api:
image: myregistry.internal/backend-api:v1.2.0
environment:
- PORT=3000
- REDIS_HOST=redis
- REDIS_PORT=6379
deploy:
replicas: 3
restart_policy:
condition: on-failure
resources:
limits:
cpus: '0.50'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
networks:
- webnet
redis:
image: redis:7-alpine
command: redis-server --appendonly yes --requirepass "SuperSecretRedisPass2023!"
volumes:
- redis_data:/data
deploy:
replicas: 1
placement:
constraints:
- node.role == worker
networks:
- webnet
volumes:
nginx_logs:
redis_data:
networks:
webnet:
driver: overlay
attachable: true
Cara deploy ke Docker Swarm:
docker stack deploy -c docker-stack.yml production_web
Pendekatan B: Kubernetes Deployment Manifests
Untuk Kubernetes, kita pecah menjadi beberapa file YAML standar industri (namespace.yaml, redis-deployment.yaml, api-deployment.yaml, nginx-deployment.yaml).
1. Namespace & Redis (redis.yaml)
apiVersion: v1
kind: Namespacemetadata:
name: production-web
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
namespace: production-web
spec:
serviceName: "redis"
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
command: ["redis-server", "--appendonly", "yes", "--requirepass", "SuperSecretRedisPass2023!"]
ports:
- containerPort: 6379
volumeMounts:
- name: redis-storage
mount-path: /data
volumeClaimTemplates:
- metadata:
name: redis-storage
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: production-web
spec:
ports:
- port: 6379
targetPort: 6379
clusterIP: None
selector:
app: redis
2. Backend API & Nginx Ingress (app.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-api
namespace: production-web
spec:
replicas: 3
selector:
matchLabels:
app: backend-api
template:
metadata:
labels:
app: backend-api
spec:
containers:
- name: api
image: myregistry.internal/backend-api:v1.2.0
ports:
- containerPort: 3000
env:
- name: REDIS_HOST
value: "redis"
- name: REDIS_PORT
value: "6379"
resources:
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "250m"
memory: "256Mi"
---
apiVersion: v1
kind: Service
metadata:
name: backend-api-svc
namespace: production-web
spec:
selector:
app: backend-api
ports:
- port: 3000
targetPort: 3000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-proxy
namespace: production-web
spec:
replicas: 2
selector:
matchLabels:
app: nginx-proxy
template:
metadata:
labels:
app: nginx-proxy
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d
volumes:
- name: nginx-config
configMap:
name: nginx-conf
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf
namespace: production-web
data:
default.conf: |
server {
listen 80;
location / {
proxy_pass http://backend-api-svc:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Cara apply ke Kubernetes:
kubectl apply -f redis.yaml
kubectl apply -f app.yaml
[!TIP] Pada Kubernetes, selalu gunakan
StatefulSetuntuk database seperti Redis atau MySQL yang memerlukan identitas jaringan yang stabil dan penyimpanan persisten yang terikat secara konsisten, bukanDeploymentbiasa.
6. Bedah Kode & Penjelasan Detail Baris Kunci
Mari kita bedah beberapa konfigurasi paling krusial dari file deployment di atas:
-
update_configpada Docker Swarm:update_config: parallelism: 1 delay: 10sParameter ini mengatur rolling update.
parallelism: 1memastikan container diperbarui satu per satu, dandelay: 10smemberikan jeda waktu 10 detik agar container baru dapat melakukan inisialisasi dan warm-up sebelum container lama dimatikan. Ini mencegah dropped requests pada tingkat aplikasi web. -
clusterIP: Nonepada StatefulSet Redis (Kubernetes): Pengaturan ini membuat Headless Service. Alih-alih memberikan satu IP virtual load-balancer, Kubernetes mengembalikan DNS record yang langsung mengarah ke IP pod individual. Ini sangat penting bagi Redis cluster atau replikasi master-slave di mana aplikasi backend perlu mengetahui alamat persis setiap node database. -
resources.limitsdanresources.reservations(Swarm) /requests&limits(K8s): Membatasi konsumsi CPU dan RAM mencegah proses runaway (seperti memori leak pada aplikasi Node.js) menghabiskan seluruh sumber daya host fisik, yang dapat memicu Kernel Out-Of-Memory (OOM) Killer dan merusak container lain di node yang sama.
7. Skenario Produksi & Studi Kasus Dunia Nyata
Studi Kasus: E-Commerce Flash Sale dengan 50.000 Concurrency
Sebuah platform e-commerce menghadapi lonjakan traffic hingga 50.000 requests per second (RPS) selama event Flash Sale.
-
Pendekatan Docker Swarm: Tim DevOps menggunakan perintah
docker service scale production_web_api=20secara manual atau melalui webhook Prometheus alert manager. Load balancing berbasis IPVS mendistribusikan traffic secara merata ke 20 instance backend. Namun, jika lonjakan traffic datang secara tiba-tiba dalam hitungan detik, penskalaan manual atau skrip kustom sering kali terlambat merespons. -
Pendekatan Kubernetes: Tim mengkonfigurasi Horizontal Pod Autoscaler (HPA) yang terhubung dengan Metrics Server:
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: api-autoscaler namespace: production-web
spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: backend-api minReplicas: 3 maxReplicas: 50 metrics:
- type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70
Ketika penggunaan CPU rata-rata pod mencapai 70%, K8s secara otomatis mendaur ulang dan menambah jumlah pod dari 3 menjadi 50 dalam waktu kurang dari 30 detik, memastikan ketersediaan layanan tanpa intervensi manual.
## 8. Common Pitfalls, Anti-Patterns & Solusi
1. **Anti-Pattern: Menyimpan State Data di dalam Container Lokal**
- *Masalah*: Container bersifat *ephemeral*. Jika container mati atau berpindah node, data yang tersimpan di dalam filesystem lokal container akan hilang selamanya.
- *Solusi*: Selalu gunakan Docker Volumes, bind mounts, atau Kubernetes Persistent Volume Claims (PVC) yang terhubung ke Network File System (NFS), AWS EBS, atau MinIO S3.
2. **Pitfall: Mengabaikan Liveness dan Readiness Probes**
- *Masalah*: Traffic tetap dikirimkan ke container yang sedang mengalami deadlock atau proses *startup* yang belum selesai.
- *Solusi*: Selalu definisikan `readinessProbe` (memastikan container siap menerima traffic) dan `livenessProbe` (memastikan container sehat; jika gagal, container akan direstart secara otomatis).
3. **Kesalahan Konfigurasi DNS / Service Discovery**
- *Masalah*: Hardcoding alamat IP database di dalam kode aplikasi web.
- *Solusi*: Manfaatkan internal DNS bawaan orkestrator (misalnya `redis` di Swarm atau `redis.production-web.svc.cluster.local` di Kubernetes).
## 9. Benchmark, Metrik Kinerja & Tuning Performa
Untuk menguji ketahanan infrastruktur web sebelum rilis ke publik, gunakan tool benchmark berkinerja tinggi seperti `k6` atau `wrk`.
### Skrip Benchmark `k6` (`load-test.js`)
```javascript
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '30s', target: 1000 }, // Ramp-up ke 1000 users
{ duration: '1m', target: 5000 }, // Beban puncak 5000 users
{ duration: '30s', target: 0 }, // Ramp-down
],
};
export default function () {
const res = http.get('http://production-cluster-ip/');
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 200ms': (r) => r.timings.duration < 200,
});
sleep(1);
}
Tuning Performa Linux Host (Sysctl Tunables)
Tambahkan parameter berikut ke /etc/sysctl.conf untuk menangani ribuan koneksi TCP konkuren:
# Meningkatkan batas port ephemeral
net.ipv4.ip_local_port_range = 1024 65535
# Mengaktifkan TCP TIME_WAIT reuse
net.ipv4.tcp_tw_reuse = 1
# Memperbesar ukuran backlog jaringan
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
10. Checklist Penerapan Produksi & Kesimpulan
Gunakan checklist berikut sebelum mendeklarasikan sistem microservices Anda siap untuk produksi:
- Semua rahasia aplikasi (API Keys, Database Passwords) dikelola melalui Docker Secrets atau Kubernetes Secrets (bukan plaintext di file YAML).
- Batasan resource (
CPU/Memory requests & limits) telah diterapkan pada seluruh pod/service. - Mekanisme backup otomatis untuk Persistent Volumes (Redis/MySQL) berjalan secara berkala.
- Centralized Logging (ELK Stack, Grafana Loki, atau Datadog) telah terhubung ke seluruh node container.
- SSL/TLS Termination dikonfigurasi dengan benar pada Ingress Controller / Reverse Proxy.
Kesimpulan
Pemilihan antara Docker Swarm dan Kubernetes sangat bergantung pada skala organisasi dan kompleksitas bisnis Anda. Docker Swarm adalah pilihan yang sempurna untuk tim kecil, startup, atau aplikasi dengan arsitektur sedang yang memprioritaskan kemudahan operasional dan kecepatan deployment tanpa overhead tinggi. Sebaliknya, Kubernetes adalah standar mutlak untuk enterprise berskala besar yang membutuhkan ekosistem luas, otomatisasi tingkat lanjut (autoscaling, custom operators), dan kontrol multi-tenant yang ketat. Pilihlah alat yang sesuai dengan kapasitas sumber daya tim Anda saat ini.