DNS & Service Discovery #

Setiap cluster Kubernetes menjalankan DNS server internal — secara default bernama CoreDNS — yang memungkinkan Pod menemukan service lain berdasarkan nama tanpa perlu tahu IP-nya. Ini adalah mekanisme service discovery utama di Kubernetes: bukan IP hardcode, bukan environment variable manual, tapi DNS yang secara otomatis diperbarui saat service dibuat atau dihapus.

CoreDNS: DNS Server Cluster #

CoreDNS berjalan sebagai Deployment di namespace kube-system dan diekspos melalui Service dengan ClusterIP stabil. Saat Pod dibuat, kubelet mengonfigurasi /etc/resolv.conf di dalam Pod untuk mengarahkan semua DNS query ke CoreDNS.

# Lihat CoreDNS deployment
kubectl get pods -n kube-system | grep coredns

# Lihat Service yang mengekspos CoreDNS
kubectl get service -n kube-system kube-dns

# Output:
# NAME       TYPE        CLUSTER-IP   PORT(S)
# kube-dns   ClusterIP   10.96.0.10   53/UDP,53/TCP
Isi /etc/resolv.conf di dalam Pod:

nameserver 10.96.0.10        ← IP CoreDNS Service
search production.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

Konfigurasi search ini memungkinkan short name resolution — Pod bisa query api-service dan DNS akan mencoba beberapa domain secara berurutan sebelum memberikan hasil.


Format DNS untuk Service #

Setiap Service mendapat DNS record dengan format terstandarisasi:

Format FQDN (Fully Qualified Domain Name):
  <service-name>.<namespace>.svc.<cluster-domain>

Cluster domain default: cluster.local

Contoh Service "api" di namespace "production":
  api.production.svc.cluster.local

Contoh Service "redis" di namespace "default":
  redis.default.svc.cluster.local

Short Name vs FQDN #

Pod bisa menggunakan nama pendek berkat konfigurasi search domain:

Pod di namespace "production" query untuk "api":

CoreDNS mencoba secara berurutan:
  1. api.production.svc.cluster.local  → FOUND ✓ → kembalikan IP

Jika tidak ketemu di namespace sendiri:
  2. api.svc.cluster.local
  3. api.cluster.local

Pod di namespace "staging" query untuk "api":
  1. api.staging.svc.cluster.local     → NOT FOUND
  2. api.svc.cluster.local             → NOT FOUND
  3. api.cluster.local                 → NOT FOUND
  → Gagal (harus gunakan FQDN atau pindah namespace)

Ini punya implikasi penting: short name hanya bekerja dalam namespace yang sama. Untuk mengakses service di namespace lain, gunakan format <service>.<namespace> minimal, atau FQDN lengkap.

Cara mengakses service di namespace berbeda:

# Pod di namespace "frontend" akses API di namespace "backend"
http://api-service.backend                     # minimal
http://api-service.backend.svc                 # lebih eksplisit
http://api-service.backend.svc.cluster.local  # FQDN penuh (paling aman)

DNS Records yang Dibuat Kubernetes #

Saat Service dibuat, CoreDNS secara otomatis membuat DNS record yang sesuai:

Service "api" (ClusterIP):
  A record: api.production.svc.cluster.local → 10.96.45.12

Headless Service "postgres" (clusterIP: None):
  A record per Pod:
    postgres-0.postgres.production.svc.cluster.local → 10.244.1.5
    postgres-1.postgres.production.svc.cluster.local → 10.244.2.3
  A record Service: postgres.production.svc.cluster.local → 10.244.1.5, 10.244.2.3 (semua Pod)

Service "api" dengan port name:
  SRV record: _http._tcp.api.production.svc.cluster.local → port 80

Environment Variable sebagai Service Discovery (Legacy) #

Sebelum DNS menjadi default, Kubernetes menggunakan environment variable untuk service discovery. Ini masih berfungsi tapi bukan cara yang direkomendasikan:

# Di dalam Pod, semua Service yang ada saat Pod dibuat tersedia sebagai env var
kubectl exec -it api-pod -- env | grep SERVICE

# Output (contoh):
# API_SERVICE_SERVICE_HOST=10.96.45.12
# API_SERVICE_SERVICE_PORT=80
# REDIS_SERVICE_HOST=10.96.78.34
# REDIS_SERVICE_PORT=6379

Masalah dengan pendekatan ini: environment variable hanya mencerminkan Service yang ada saat Pod dibuat. Service baru yang dibuat setelah Pod tidak akan muncul sebagai env var. DNS selalu up-to-date.


Troubleshooting DNS #

Cek DNS dari dalam Pod #

# Masuk ke Pod
kubectl exec -it <pod-name> -- sh

# Cek resolv.conf
cat /etc/resolv.conf

# Resolve nama service
nslookup api-service
nslookup api-service.production.svc.cluster.local

# Jika nslookup tidak ada, gunakan curl
curl -v http://api-service:80 2>&1 | grep DNS

# Test dengan dig (jika tersedia)
dig api-service.production.svc.cluster.local

Debug Pod Khusus untuk DNS #

# Jalankan pod debug dengan tools networking
kubectl run dns-debug --image=busybox:1.35 --restart=Never -it --rm -- sh

# Di dalam pod:
nslookup kubernetes.default
nslookup api-service.production.svc.cluster.local

Masalah Umum DNS #

"NXDOMAIN" atau "server can't find":
  → Service tidak ada atau salah namespace
  → Cek: kubectl get svc -n <namespace>

Resolusi lambat (>100ms):
  → ndots:5 menyebabkan 5 lookup sebelum FQDN
  → Solusi: gunakan FQDN lengkap, atau turunkan ndots
  → Atau tambahkan titik di akhir nama: "api-service."

"connection refused" setelah resolve berhasil:
  → Service ada tapi tidak ada Pod yang sehat di belakangnya
  → Cek: kubectl get endpoints <service-name>

DNS works tapi timeout dari Pod:
  → Kemungkinan NetworkPolicy memblokir traffic ke CoreDNS (port 53)
  → Pastikan NetworkPolicy tidak memblokir egress ke kube-system

Kustomisasi DNS Pod #

Kamu bisa mengkustomisasi konfigurasi DNS per Pod jika diperlukan:

spec:
  dnsPolicy: ClusterFirst   # default: gunakan CoreDNS
  dnsConfig:
    options:
    - name: ndots
      value: "1"            # turunkan ndots untuk kurangi lookup tidak perlu
    - name: timeout
      value: "5"
    searches:
    - my-custom-domain.local

DNS policy options:

ClusterFirst (default):
  → Query ke CoreDNS dulu, lalu upstream DNS jika tidak ketemu

ClusterFirstWithHostNet:
  → Sama seperti ClusterFirst, untuk Pod yang pakai hostNetwork: true

Default:
  → Gunakan konfigurasi DNS dari node (bukan CoreDNS)

None:
  → Tidak ada DNS konfigurasi default, harus fully manual via dnsConfig

Ringkasan #

  • CoreDNS adalah DNS server internal cluster — berjalan di kube-system, dikonfigurasi otomatis di setiap Pod via /etc/resolv.conf.
  • Format DNS Service: <name>.<namespace>.svc.cluster.local — FQDN lengkap selalu bekerja; short name hanya bekerja dalam namespace yang sama.
  • Gunakan <service>.<namespace> untuk lintas namespace — cukup api-service.production tanpa .svc.cluster.local; lebih pendek dan masih jelas.
  • DNS selalu up-to-date, env var tidak — service discovery via DNS adalah cara yang benar; env var hanya mencerminkan kondisi saat Pod dibuat.
  • ndots:5 bisa menyebabkan DNS lookup lambat — untuk performa maksimal, gunakan FQDN lengkap atau tambahkan titik di akhir nama DNS.
  • kubectl exec ke Pod dan jalankan nslookup — cara paling langsung untuk debug masalah DNS dari perspektif Pod yang bermasalah.

← Sebelumnya: Service   Berikutnya: Ingress →

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