Kubernetes untuk Pemula: Konsep Dasar Pod, Service, dan Deployment

Container dengan Docker mengubah cara kita membangun dan mendistribusikan aplikasi — tapi begitu aplikasi Anda berkembang dari satu container menjadi puluhan atau ratusan container yang saling berkomunikasi, pertanyaan baru muncul: siapa yang memastikan container tetap berjalan jika crash? Bagaimana melakukan scaling otomatis saat traffic melonjak? Bagaimana melakukan update aplikasi tanpa downtime? Menjawab pertanyaan-pertanyaan inilah Kubernetes hadir, dan menjadi salah satu teknologi paling berpengaruh dalam dunia infrastruktur modern.
Bagi banyak developer, Kubernetes (sering disingkat K8s — angka 8 mewakili delapan huruf antara "K" dan "s") terasa menakutkan karena terminologinya yang banyak dan konsepnya yang berlapis. Artikel ini akan membedah konsep-konsep dasar Kubernetes secara sistematis, dimulai dari Pod sebagai unit terkecil, hingga Deployment dan Service yang membuat aplikasi Anda benar-benar bisa diakses dan diandalkan di production.
Apa Itu Kubernetes dan Mengapa Dibutuhkan?
Kubernetes adalah platform orkestrasi container open-source yang mengotomatisasi deployment, scaling, dan manajemen aplikasi yang di-container-kan. Kubernetes lahir dari pengalaman Google mengelola sistem internal bernama Borg selama lebih dari satu dekade untuk menjalankan hampir semua layanan Google dalam skala masif. Pada tahun 2014, Google merilis Kubernetes sebagai proyek open-source, dan sejak 2015 pengelolaannya diserahkan ke Cloud Native Computing Foundation (CNCF).
Tanpa orkestrator seperti Kubernetes, mengelola container secara manual di banyak server akan sangat merepotkan: Anda harus memantau sendiri container mana yang mati dan perlu di-restart, mendistribusikan container secara manual ke server yang tersedia, mengatur load balancing sendiri, dan melakukan update aplikasi dengan risiko downtime signifikan. Kubernetes mengotomatisasi seluruh proses ini melalui pendekatan deklaratif: Anda mendeskripsikan state yang diinginkan (misalnya "saya ingin 3 replika aplikasi ini selalu berjalan"), dan Kubernetes secara terus-menerus bekerja untuk memastikan kondisi aktual sesuai dengan yang diinginkan.
Arsitektur Dasar Kubernetes
Sebuah cluster Kubernetes terdiri dari dua komponen utama: Control Plane dan Node (worker).
Control Plane
- kube-apiserver — pintu masuk utama untuk semua interaksi dengan cluster, baik dari
kubectl, dashboard, maupun komponen internal lainnya. - etcd — database key-value terdistribusi yang menyimpan seluruh state cluster, mulai dari konfigurasi hingga status setiap objek.
- kube-scheduler — bertugas menentukan Node mana yang paling cocok untuk menjalankan Pod baru, berdasarkan ketersediaan resource dan aturan penempatan (affinity/anti-affinity).
- kube-controller-manager — menjalankan berbagai controller yang terus memantau state cluster dan mengambil tindakan agar sesuai dengan state yang diinginkan, misalnya membuat Pod baru jika ada yang mati.
Node (Worker)
- kubelet — agen yang berjalan di setiap Node, bertanggung jawab memastikan container yang didefinisikan dalam Pod benar-benar berjalan sesuai spesifikasi.
- kube-proxy — mengatur aturan jaringan di setiap Node agar komunikasi antar Pod dan Service berjalan dengan benar.
- Container runtime — software yang benar-benar menjalankan container, misalnya containerd atau CRI-O (Docker Engine sendiri sudah tidak dipakai langsung sejak Kubernetes 1.24, meski image Docker tetap kompatibel penuh).
Pod: Unit Terkecil di Kubernetes
Pod adalah unit terkecil yang bisa di-deploy di Kubernetes — bukan container itu sendiri. Satu Pod bisa membungkus satu atau lebih container yang berbagi network namespace (jadi bisa saling komunikasi lewat localhost) dan storage volume yang sama. Dalam praktiknya, mayoritas Pod hanya berisi satu container utama, dengan pola "sidecar container" tambahan yang cukup umum untuk kebutuhan seperti logging atau proxy.
# pod.yaml - contoh definisi Pod sederhana
apiVersion: v1
kind: Pod
metadata:
name: web-app-pod
labels:
app: web-app
spec:
containers:
- name: web-app
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
# Menjalankan dan memeriksa Pod
kubectl apply -f pod.yaml
kubectl get pods
kubectl describe pod web-app-pod
kubectl logs web-app-pod
Perlu dicatat, Pod bersifat ephemeral (sementara) — jika Pod mati, ia tidak akan dihidupkan kembali secara otomatis oleh dirinya sendiri, dan IP address-nya akan berubah jika dibuat ulang. Karena itulah, dalam praktik nyata, Pod hampir tidak pernah dibuat secara langsung, melainkan dikelola oleh objek tingkat lebih tinggi seperti Deployment.
Deployment: Mengelola Pod secara Deklaratif
Deployment adalah objek Kubernetes yang mengelola sekumpulan Pod identik (disebut ReplicaSet di baliknya), memastikan jumlah replika yang diinginkan selalu berjalan, dan menangani proses update aplikasi secara terkendali.
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: web-app
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: registrycontoh.id/web-app:v1.2.0
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 15
periodSeconds: 20
Fitur Penting Deployment
- Self-healing — jika salah satu dari 3 Pod mati atau Node tempatnya berjalan gagal, Deployment otomatis membuat Pod pengganti agar jumlah replika tetap sesuai yang diinginkan.
- Rolling update — saat image di-update ke versi baru, Kubernetes secara bertahap mengganti Pod lama dengan yang baru, memastikan selalu ada Pod yang siap melayani traffic sehingga tidak terjadi downtime.
- Rollback — jika versi baru bermasalah, Anda bisa langsung kembali ke revisi sebelumnya.
- Readiness dan Liveness Probe — readiness probe menentukan apakah Pod siap menerima traffic, sedangkan liveness probe menentukan apakah Pod perlu di-restart karena dianggap "macet" atau tidak sehat.
# Perintah dasar mengelola Deployment
kubectl apply -f deployment.yaml
kubectl get deployments
kubectl rollout status deployment/web-app-deployment
# Update image ke versi baru
kubectl set image deployment/web-app-deployment web-app=registrycontoh.id/web-app:v1.3.0
# Melihat riwayat rollout dan rollback jika diperlukan
kubectl rollout history deployment/web-app-deployment
kubectl rollout undo deployment/web-app-deployment
Service: Membuat Pod Bisa Diakses Secara Stabil
Karena Pod bersifat sementara dan IP-nya bisa berubah kapan saja (misalnya saat di-restart atau dipindah Node), kita membutuhkan cara yang stabil untuk mengakses sekumpulan Pod. Di sinilah Service berperan — menyediakan satu titik akses tetap (stable endpoint) yang secara otomatis mengarahkan traffic ke Pod-Pod yang sehat, menggunakan label selector untuk menentukan Pod mana yang menjadi target.
Jenis-Jenis Service
- ClusterIP (default) — memberikan IP internal yang hanya bisa diakses dari dalam cluster, cocok untuk komunikasi antar service internal, misalnya backend mengakses database service.
- NodePort — membuka port statis pada setiap Node di cluster, memungkinkan akses dari luar cluster melalui
<IP-Node>:<NodePort>, umumnya dipakai untuk keperluan development atau testing. - LoadBalancer — meminta load balancer eksternal dari cloud provider (AWS ELB, GCP Load Balancer, dsb.), paling umum dipakai untuk expose service ke internet di lingkungan production pada cloud managed Kubernetes.
- ExternalName — memetakan Service ke nama DNS eksternal, berguna untuk mengakses resource di luar cluster dengan cara yang konsisten dengan Service internal lainnya.
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
type: LoadBalancer
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 80
Perhatikan bagian selector: app: web-app — ini yang membuat Service secara otomatis menemukan semua Pod dengan label app: web-app, tanpa peduli berapa kali Pod tersebut dibuat ulang atau berpindah Node. Inilah kekuatan pendekatan berbasis label di Kubernetes: dekopling antara "siapa yang menyediakan layanan" dan "siapa yang mengonsumsi layanan".
ConfigMap dan Secret: Memisahkan Konfigurasi dari Kode
Selain Pod, Deployment, dan Service, dua objek yang sangat sering dipakai adalah ConfigMap dan Secret, yang memungkinkan konfigurasi aplikasi dipisahkan dari image container agar tidak perlu build ulang image hanya karena perubahan konfigurasi.
# configmap.yaml - untuk data non-sensitif
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: "production"
MAX_UPLOAD_SIZE: "10485760"
---
# Digunakan dalam Pod/Deployment
spec:
containers:
- name: web-app
envFrom:
- configMapRef:
name: app-config
Untuk data sensitif seperti password database atau API key, Kubernetes menyediakan objek Secret, yang secara default disimpan dalam format base64 (bukan enkripsi kuat, sehingga di production sebaiknya dikombinasikan dengan solusi tambahan seperti Sealed Secrets, HashiCorp Vault, atau fitur encryption-at-rest dari cloud provider).
Namespace: Mengisolasi Resource dalam Satu Cluster
Namespace adalah cara untuk membagi satu cluster Kubernetes menjadi beberapa "ruang" virtual yang terisolasi secara logis. Ini sangat berguna untuk memisahkan environment (development, staging, production) atau memisahkan resource antar tim dalam satu cluster yang sama, sekaligus memudahkan penerapan resource quota dan access control per namespace.
kubectl create namespace staging
kubectl apply -f deployment.yaml --namespace=staging
kubectl get pods --namespace=staging
Perintah kubectl yang Wajib Diketahui Pemula
| Perintah | Fungsi |
|---|---|
kubectl get pods | Melihat daftar Pod yang berjalan |
kubectl describe pod <nama> | Melihat detail dan event terkait sebuah Pod |
kubectl logs <nama-pod> | Melihat log dari container di dalam Pod |
kubectl exec -it <nama-pod> -- /bin/sh | Masuk ke dalam shell container yang berjalan |
kubectl apply -f <file.yaml> | Menerapkan konfigurasi dari file YAML |
kubectl delete -f <file.yaml> | Menghapus resource yang didefinisikan file YAML |
kubectl scale deployment <nama> --replicas=5 | Mengubah jumlah replika secara manual |
kubectl get events --sort-by=.metadata.creationTimestamp | Melihat event cluster terbaru, berguna untuk debugging |
Alur Kerja Lengkap: Dari YAML hingga Aplikasi Berjalan
- Anda menulis file YAML yang mendeskripsikan state yang diinginkan (Deployment dengan 3 replika, image tertentu, Service tipe LoadBalancer).
- Perintah
kubectl applymengirimkan definisi ini ke kube-apiserver, yang menyimpannya di etcd. - kube-scheduler melihat ada permintaan Pod baru yang belum ditempatkan, lalu memilih Node yang paling sesuai berdasarkan resource yang tersedia.
- kubelet di Node terpilih menerima instruksi dan meminta container runtime untuk menjalankan container sesuai spesifikasi image.
- kube-controller-manager terus memantau apakah jumlah Pod yang berjalan sesuai dengan yang diinginkan di Deployment, dan akan membuat Pod baru jika ada yang mati.
- Service secara otomatis mendeteksi Pod-Pod baru melalui label selector dan mulai mengarahkan traffic begitu Pod dinyatakan "ready" oleh readiness probe.
Seluruh proses ini berjalan secara otomatis dan berkelanjutan (disebut sebagai "reconciliation loop") — Kubernetes terus-menerus membandingkan state aktual dengan state yang diinginkan, dan mengambil tindakan korektif kapan pun terjadi penyimpangan, tanpa perlu campur tangan manual dari operator.
Kapan Sebaiknya (dan Belum Perlu) Menggunakan Kubernetes
Meski sangat powerful, Kubernetes bukan solusi untuk semua kasus. Beberapa pertimbangan:
- Untuk aplikasi kecil dengan traffic rendah dan tim kecil, platform yang lebih sederhana seperti Heroku, Railway, atau layanan container serverless (Cloud Run, AWS Fargate) sering kali jauh lebih hemat waktu dan biaya operasional.
- Kubernetes memberikan nilai nyata ketika Anda mengelola banyak service (arsitektur microservices), membutuhkan scaling otomatis yang kompleks, atau perlu portabilitas antar cloud provider.
- Kurva belajar Kubernetes cukup curam — pertimbangkan menggunakan managed Kubernetes (GKE, EKS, AKS) agar tim tidak perlu mengelola Control Plane secara manual, terutama di tahap awal adopsi.
Horizontal Pod Autoscaler: Scaling Otomatis Berdasarkan Beban
Menentukan jumlah replika secara manual di Deployment cukup baik untuk beban yang stabil, tapi aplikasi dunia nyata sering menghadapi traffic yang naik-turun, misalnya melonjak saat jam sibuk atau saat ada kampanye promosi. Horizontal Pod Autoscaler (HPA) menyelesaikan masalah ini dengan menambah atau mengurangi jumlah Pod secara otomatis berdasarkan metrik tertentu, paling umum penggunaan CPU atau memori.
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app-deployment
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
kubectl apply -f hpa.yaml
kubectl get hpa
kubectl describe hpa web-app-hpa
Dengan konfigurasi di atas, Kubernetes akan terus memantau rata-rata penggunaan CPU seluruh Pod pada Deployment tersebut. Jika rata-rata melebihi 70% dari resource request yang didefinisikan, HPA otomatis menambah jumlah Pod (hingga maksimal 20) untuk mendistribusikan beban. Sebaliknya, saat traffic menurun, jumlah Pod dikurangi kembali (hingga minimal 3) agar tidak memboroskan resource cluster yang berarti juga menghemat biaya. Untuk kasus yang lebih canggih, HPA juga bisa dikonfigurasi berdasarkan metrik custom, misalnya jumlah request per detik atau panjang antrean pesan, menggunakan adapter seperti Prometheus Adapter.
Ingress: Mengatur Routing HTTP ke Banyak Service
Service tipe LoadBalancer sangat praktis, tapi jika Anda memiliki banyak service yang masing-masing butuh diakses dari internet, membuat satu LoadBalancer terpisah untuk tiap service akan menjadi mahal dan sulit dikelola (setiap LoadBalancer di cloud provider biasanya dikenakan biaya tersendiri). Ingress menyelesaikan masalah ini dengan menyediakan satu titik masuk HTTP/HTTPS yang bisa merutekan traffic ke banyak Service berbeda berdasarkan hostname atau path URL.
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: app.contoh.id
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-app-service
port:
number: 80
Dengan definisi di atas, request ke app.contoh.id/api/* akan diarahkan ke api-service, sementara request lainnya diarahkan ke web-app-service — semuanya melalui satu titik masuk yang sama. Ingress membutuhkan Ingress Controller (misalnya NGINX Ingress Controller atau Traefik) yang benar-benar berjalan di cluster untuk mengimplementasikan aturan routing ini, karena objek Ingress sendiri hanyalah deklarasi aturan, bukan komponen yang menjalankan proxy secara langsung. Ingress juga umumnya menjadi tempat mengatur terminasi TLS/HTTPS secara terpusat, sehingga sertifikat tidak perlu dikonfigurasi terpisah di setiap Service.
StatefulSet: Ketika Pod Butuh Identitas dan Storage yang Persisten
Deployment sangat cocok untuk aplikasi stateless — Pod bisa dibuat ulang kapan saja tanpa peduli identitasnya, karena semua Pod dianggap identik dan tidak menyimpan data unik secara lokal. Namun untuk aplikasi stateful seperti database, message queue, atau sistem terdistribusi yang butuh identitas jaringan stabil (misalnya cluster Kafka atau Elasticsearch), Kubernetes menyediakan objek terpisah bernama StatefulSet.
Perbedaan utama StatefulSet dibanding Deployment:
- Identitas jaringan yang stabil — setiap Pod dalam StatefulSet mendapat nama yang konsisten dan dapat diprediksi, misalnya
db-0,db-1,db-2, bukan nama acak seperti pada Deployment. - Urutan startup dan shutdown yang terjamin — Pod dibuat dan dimatikan secara berurutan (
db-0selalu dibuat sebelumdb-1), penting untuk sistem yang punya dependensi urutan seperti node primary sebelum replica. - Persistent storage per Pod — setiap Pod mendapat volume penyimpanan (PersistentVolume) miliknya sendiri yang tetap terhubung ke Pod yang sama meskipun Pod tersebut dibuat ulang, sehingga data tidak hilang.
# statefulset.yaml (disederhanakan)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres-cluster
spec:
serviceName: postgres-headless
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
Sebagai pedoman umum: gunakan Deployment untuk aplikasi stateless seperti web server atau API backend yang tidak menyimpan data unik di setiap Pod, dan gunakan StatefulSet untuk sistem yang benar-benar butuh identitas dan penyimpanan persisten per instance. Dalam banyak kasus praktis, database justru lebih sering dijalankan sebagai managed service di luar cluster Kubernetes (misalnya RDS atau Cloud SQL) untuk mengurangi kompleksitas operasional, dan StatefulSet lebih sering dipakai untuk komponen seperti message broker atau search engine terdistribusi yang memang didesain untuk berjalan di Kubernetes.
Kesimpulan
Kubernetes memang terlihat rumit di permukaan, tapi begitu Anda memahami blok bangunan dasarnya — Pod sebagai unit terkecil, Deployment yang menjaga jumlah replika dan mengelola update, serta Service yang menyediakan akses stabil ke sekumpulan Pod yang selalu berubah — konsep-konsep lain yang lebih lanjut (Ingress, StatefulSet, Horizontal Pod Autoscaler, Helm) akan jauh lebih mudah dipahami karena semuanya dibangun di atas fondasi yang sama.
Kunci untuk benar-benar menguasai Kubernetes adalah praktik langsung. Mulailah dengan cluster lokal menggunakan Minikube atau Kind, coba deploy aplikasi sederhana, sengaja matikan Pod untuk melihat bagaimana self-healing bekerja, dan lakukan rolling update untuk merasakan sendiri bagaimana Kubernetes menjaga aplikasi tetap berjalan tanpa downtime. Pemahaman konsep yang kuat dikombinasikan dengan praktik langsung akan membuat Anda jauh lebih percaya diri saat suatu hari harus mengelola aplikasi production yang sesungguhnya di atas Kubernetes.

Ditulis oleh
@nopal
Ruang Iklan Tersedia
Hubungi Admin untuk menempatkan banner iklan atau Adsense Anda di sini.
Bagaimana pendapat Anda tentang artikel ini?
Komentar Pembaca (0)
Belum ada komentar. Jadilah yang pertama!