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 — cukupapi-service.productiontanpa.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 execke Pod dan jalankannslookup— cara paling langsung untuk debug masalah DNS dari perspektif Pod yang bermasalah.