Service #
Pod punya IP yang berubah setiap kali ia dibuat ulang. Jika kamu menjalankan tiga replica aplikasi, ketiga Pod itu punya IP yang berbeda. Saat rolling update, Pod lama diganti yang baru dengan IP baru. Service adalah solusi untuk semua ini — ia menyediakan satu titik akses yang stabil, tidak peduli berapa banyak Pod di belakangnya atau seberapa sering Pod tersebut berganti.
Apa Itu Service? #
Service adalah resource Kubernetes yang mendefinisikan cara mengakses sekumpulan Pod. Ia menyediakan:
Service memberikan:
✓ IP yang stabil (ClusterIP) — tidak berubah selama Service ada
✓ DNS name yang stabil — bisa digunakan dalam konfigurasi
✓ Load balancing — mendistribusikan traffic ke semua Pod yang sehat
✓ Discovery — Pod lain bisa menemukan Service via DNS
Service tidak peduli:
→ Berapa banyak Pod yang ada di belakangnya (1, 10, atau 100)
→ IP Pod apa yang digunakan Pod tersebut
→ Di node mana Pod tersebut berjalan
Cara Service Menemukan Pod: Selector #
Service menemukan Pod yang akan dilayaninya melalui label selector — sama seperti Deployment menemukan Pod-nya. Service tidak terikat ke Pod secara langsung; ia terikat ke semua Pod yang punya label yang cocok.
apiVersion: v1
kind: Service
metadata:
name: api-service
namespace: production
spec:
selector:
app: api # Service ini melayani semua Pod berlabel app=api
tier: backend
ports:
- protocol: TCP
port: 80 # port yang di-expose Service (ClusterIP:80)
targetPort: 8080 # port di dalam container
Service "api-service" dengan selector app=api:
ClusterIP: 10.96.45.12 (stabil, tidak berubah)
Pod A: 10.244.1.5 (app=api) ─┐
Pod B: 10.244.1.9 (app=api) ─┼─ semua dilayani Service
Pod C: 10.244.2.3 (app=api) ─┘
Traffic ke 10.96.45.12:80
→ di-forward ke salah satu Pod secara acak
Endpoints: Daftar IP Pod di Belakang Service #
Di balik layar, Kubernetes membuat Endpoints object yang berisi daftar IP:Port dari semua Pod yang cocok dengan selector. Endpoints diperbarui secara otomatis saat Pod dibuat, dihapus, atau kondisinya berubah.
# Lihat Endpoints untuk sebuah Service
kubectl get endpoints api-service
# Output:
# NAME ENDPOINTS
# api-service 10.244.1.5:8080,10.244.1.9:8080,10.244.2.3:8080
# Ketika Pod gagal readiness probe, IP-nya dihapus dari Endpoints
# → Traffic tidak dikirim ke Pod yang tidak sehat
Empat Tipe Service #
ClusterIP (default) #
Service hanya bisa diakses dari dalam cluster. Ini adalah tipe paling umum untuk komunikasi antar service internal.
spec:
type: ClusterIP # atau tidak perlu ditulis, ini default
selector:
app: api
ports:
- port: 80
targetPort: 8080
Akses dari dalam cluster:
curl http://api-service.production.svc.cluster.local
curl http://api-service (jika di namespace yang sama)
curl http://10.96.45.12 (via ClusterIP langsung)
Tidak bisa diakses dari luar cluster.
NodePort #
Membuka port tertentu di setiap node dalam cluster, dan traffic ke port tersebut di-forward ke Service. Memungkinkan akses dari luar cluster tanpa load balancer.
spec:
type: NodePort
selector:
app: api
ports:
- port: 80 # ClusterIP port (akses internal)
targetPort: 8080 # port di container
nodePort: 30080 # port di setiap node (30000-32767)
Topologi NodePort:
Client → Node-1:30080 ──► Service ──► Pod A atau Pod B atau Pod C
Client → Node-2:30080 ──► Service ──► (load balanced)
Client → Node-3:30080 ──► Service ──►
Bisa diakses dari luar cluster via: <node-ip>:30080
Keterbatasan: hanya satu Service per nodePort number; rentang port terbatas (30000-32767); client harus tahu IP node.
LoadBalancer #
Membuat external load balancer di cloud provider dan mengarahkan traffic ke NodePort. Ini cara paling umum untuk expose service ke internet di cluster cloud.
spec:
type: LoadBalancer
selector:
app: api
ports:
- port: 80
targetPort: 8080
Kubernetes meminta cloud provider membuat load balancer.
Cloud provider mengalokasikan IP publik.
External IP yang didapat:
kubectl get service api-service
NAME TYPE CLUSTER-IP EXTERNAL-IP
api-service LoadBalancer 10.96.45.12 203.0.113.42
Client → 203.0.113.42:80 → Load Balancer → Node → Service → Pod
Biaya: setiap LoadBalancer Service membuat satu cloud load balancer — bisa mahal jika banyak service yang perlu di-expose. Untuk expose banyak service, gunakan Ingress.
ExternalName #
Memetakan Service ke nama DNS eksternal. Tidak ada proxy atau load balancing — hanya CNAME DNS alias.
spec:
type: ExternalName
externalName: database.external-service.com
# Tidak perlu selector
Penggunaan ExternalName:
Pod query: db-service.production.svc.cluster.local
→ DNS mengembalikan CNAME: database.external-service.com
→ Koneksi langsung ke database.external-service.com
Berguna untuk: migrasi bertahap dari external service ke internal,
atau untuk memberi "nama lokal" pada service eksternal.
Headless Service #
Terkadang kamu tidak butuh load balancing — kamu butuh DNS yang mengembalikan IP semua Pod secara langsung. Ini berguna untuk StatefulSet di mana Pod perlu saling menemukan satu sama lain berdasarkan nama.
spec:
clusterIP: None # ← ini yang menjadikannya headless
selector:
app: postgres
ports:
- port: 5432
Headless Service "postgres":
DNS query: postgres.production.svc.cluster.local
→ Mengembalikan: 10.244.1.5, 10.244.2.3, 10.244.3.7
(IP semua Pod, bukan IP tunggal)
DNS query: postgres-0.postgres.production.svc.cluster.local
→ Mengembalikan: 10.244.1.5 (IP Pod postgres-0 spesifik)
Service tanpa Selector #
Service bisa dibuat tanpa selector untuk kasus khusus, dengan Endpoints yang didefinisikan manual:
# Service tanpa selector
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
ports:
- port: 5432
---
# Endpoints manual
apiVersion: v1
kind: Endpoints
metadata:
name: external-db # nama harus sama dengan Service
subsets:
- addresses:
- ip: 192.168.1.100 # IP database eksternal
ports:
- port: 5432
Berguna untuk proxy ke service di luar cluster, atau selama migrasi.
Ringkasan #
- Service = IP stabil + DNS + load balancing — titik akses yang tidak berubah meskipun Pod di belakangnya berganti, crash, atau di-scale.
- Selector menentukan Pod yang dilayani — semua Pod yang label-nya cocok dengan selector secara otomatis menjadi bagian dari Service; Endpoints diperbarui real-time.
- ClusterIP untuk komunikasi internal — default dan paling umum; hanya bisa diakses dari dalam cluster.
- NodePort untuk akses luar tanpa cloud — membuka port di setiap node; berguna untuk on-premise atau testing, tapi tidak ideal untuk produksi internet-facing.
- LoadBalancer untuk expose ke internet di cloud — satu load balancer per Service; gunakan Ingress jika banyak service perlu di-expose untuk menghindari cost yang besar.
- Headless Service untuk StatefulSet —
clusterIP: Nonememungkinkan DNS per-Pod; wajib untuk database cluster yang node-nya perlu saling menemukan satu sama lain.
← Sebelumnya: Pod-to-Pod Communication Berikutnya: DNS & Service Discovery →