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 StatefulSetclusterIP: None memungkinkan 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 →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact