Späť na blog

CoreDNS vs NodeLocal DNS Cache: Zníženie Kubernetes DNS Latencie 10x

NodeLocal DNSCache sme benchmarkovali po DNS incidente, ktory nechceme zopakovat. “Prečo každé HTTP volanie pridáva 5ms latenciu?” Každé volanie služby vyžaduje DNS lookup. Vaše pody komunikujú s CoreDNS cez sieť. S NodeLocal DNS Cache to klesne na 0.2ms.

Testované na: Kubernetes 1.28, CoreDNS 1.11, NodeLocal DNSCache 1.22, 50-nodový cluster

DNS Bottleneck

Ako Kubernetes DNS Funguje

Bez NodeLocal DNS Cache:

Pod → kube-dns Service (ClusterIP) → CoreDNS Pod
     └─ Sieťový hop (5-20ms)        └─ Možno na inom node

DNS cesta:
1. Pod urobí DNS query (UDP)
2. Query ide na kube-dns ClusterIP (10.96.0.10)
3. kube-proxy/iptables smeruje na CoreDNS pod
4. CoreDNS resolvuje (cache hit alebo upstream query)
5. Odpoveď sa vracia rovnakou cestou

Problém

Typický web request DNS lookupy:
1. Service discovery: api.default.svc.cluster.local
2. Database: postgres.db.svc.cluster.local
3. Cache: redis.cache.svc.cluster.local
4. Externé API: api.stripe.com

4 DNS lookupy × 5ms = 20ms pridaná latencia per request!

Pri 1000 RPS:
- 4000 DNS queries/sec na CoreDNS
- CoreDNS sa stáva bottleneckom
- Tail latencia rastie

NodeLocal DNS Cache

Ako Funguje

S NodeLocal DNS Cache:

Pod → NodeLocal DaemonSet → CoreDNS (len pri cache miss)
     └─ Lokálne (0.2ms)    └─ Sieť (5ms, zriedka)

NodeLocal beží ako DaemonSet:
- Jeden pod per node
- Počúva na link-local IP (169.254.20.10)
- Cachuje odpovede lokálne
- Fallback na CoreDNS pri miss

Inštalácia

# Stiahni NodeLocal DNS manifest
kubectl apply -f https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml

# Alebo s Helm
helm install nodelocaldns stable/nodelocaldns \
  --set config.localDNS=169.254.20.10 \
  --set config.clusterDNS=10.96.0.10

Konfigurácia

# nodelocaldns-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: node-local-dns
  namespace: kube-system
data:
  Corefile: |
    cluster.local:53 {
        errors
        cache {
            success 9984 30  # Cache 30 sekúnd
            denial 9984 5    # Cache NXDOMAIN 5 sekúnd
        }
        reload
        loop
        bind 169.254.20.10
        forward . __PILLAR__CLUSTER__DNS__ {
            force_tcp
        }
        prometheus :9253
        health 169.254.20.10:8080
    }
    in-addr.arpa:53 {
        errors
        cache 30
        reload
        loop
        bind 169.254.20.10
        forward . __PILLAR__CLUSTER__DNS__ {
            force_tcp
        }
        prometheus :9253
    }
    .:53 {
        errors
        cache 30
        reload
        loop
        bind 169.254.20.10
        forward . __PILLAR__UPSTREAM__SERVERS__
        prometheus :9253
    }

Pod Konfigurácia

# Možnosť 1: Modifikuj kubelet na použitie NodeLocal
# /var/lib/kubelet/config.yaml
clusterDNS:
  - 169.254.20.10  # NodeLocal prvý
  - 10.96.0.10     # Fallback na CoreDNS

# Možnosť 2: Per-pod dnsConfig
apiVersion: v1
kind: Pod
spec:
  dnsPolicy: None
  dnsConfig:
    nameservers:
      - 169.254.20.10
    searches:
      - default.svc.cluster.local
      - svc.cluster.local
      - cluster.local
    options:
      - name: ndots
        value: "5"

Výsledky Benchmarku

Test Setup

// dns_benchmark.go
package main

import (
    "net"
    "testing"
    "time"
)

func BenchmarkDNSLookup(b *testing.B) {
    hosts := []string{
        "kubernetes.default.svc.cluster.local",
        "kube-dns.kube-system.svc.cluster.local",
    }

    for i := 0; i < b.N; i++ {
        for _, host := range hosts {
            _, err := net.LookupHost(host)
            if err != nil {
                b.Fatal(err)
            }
        }
    }
}

Výsledky

Len CoreDNS (sieťová cesta):
  Latencia p50:    5.2ms
  Latencia p99:    28.4ms
  Latencia p999:   89.2ms
  Queries/sec:     8,500

NodeLocal DNS Cache (lokálna cesta):
  Latencia p50:    0.18ms  (29x rýchlejšie)
  Latencia p99:    0.45ms  (63x rýchlejšie)
  Latencia p999:   1.2ms   (74x rýchlejšie)
  Queries/sec:     45,000  (5x vyššie)

Cache hit rate: 92% (typická produkcia)

Load Test

# Použitie dnsperf
dnsperf -s 169.254.20.10 -d queries.txt -l 60 -c 100

# Výsledky s NodeLocal:
# Queries sent:       2,812,456
# Queries completed:  2,812,456
# Queries lost:       0 (0.00%)
# Response codes:     NOERROR 2,812,456 (100.00%)
# Average latency:    0.21ms
# Maximum latency:    2.34ms

Monitoring

Prometheus Metriky

# Cache hit rate
sum(rate(coredns_cache_hits_total{server="dns://:53"}[5m]))
/
sum(rate(coredns_dns_requests_total{server="dns://:53"}[5m]))

# DNS latencia (NodeLocal)
histogram_quantile(0.99,
  sum(rate(coredns_dns_request_duration_seconds_bucket[5m])) by (le)
)

# Upstream forward latencia (CoreDNS)
histogram_quantile(0.99,
  sum(rate(coredns_forward_request_duration_seconds_bucket[5m])) by (le)
)

Alert Rules

groups:
- name: dns
  rules:
  - alert: DNSLatencyHigh
    expr: |
      histogram_quantile(0.99, sum(rate(coredns_dns_request_duration_seconds_bucket[5m])) by (le))
      > 0.01
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "DNS p99 latencia > 10ms"

  - alert: NodeLocalDNSDown
    expr: |
      up{job="nodelocaldns"} == 0
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "NodeLocal DNS nebeží na {{ $labels.node }}"

Troubleshooting

DNS Nepoužíva NodeLocal

# Skontroluj resolv.conf v pode
kubectl exec -it mypod -- cat /etc/resolv.conf

# Malo by ukázať:
# nameserver 169.254.20.10

# Ak ukazuje 10.96.0.10, skontroluj kubelet config

NodeLocal Pod Crashuje

# Skontroluj logy
kubectl logs -n kube-system -l k8s-app=node-local-dns

# Bežné problémy:
# - Port konflikt (iný proces na 53)
# - Link-local IP už používaná
# - Nedostatočné oprávnenia (potrebuje NET_ADMIN)

Cache Nefunguje

# Skontroluj cache štatistiky
kubectl exec -n kube-system node-local-dns-xxxxx -- \
  wget -qO- http://localhost:9253/metrics | grep cache

# Hľadaj:
# coredns_cache_hits_total
# coredns_cache_misses_total

Produkčná Konfigurácia

Optimalizované Nastavenia

# nodelocaldns-configmap.yaml
data:
  Corefile: |
    cluster.local:53 {
        errors
        cache {
            success 9984 60    # Cache success 60 sekúnd
            denial 9984 10     # Cache NXDOMAIN 10 sekúnd
            prefetch 10 1m 10% # Prefetch populárnych entries
        }
        reload
        loop
        bind 169.254.20.10
        forward . __PILLAR__CLUSTER__DNS__ {
            force_tcp
            max_concurrent 1000  # Vyššia konkurencia
        }
        prometheus :9253
        health 169.254.20.10:8080
        ready 169.254.20.10:8181
    }

Resource Limity

# DaemonSet resource limity
resources:
  requests:
    cpu: 25m
    memory: 32Mi
  limits:
    cpu: 100m
    memory: 128Mi

ndots Optimalizácia

Problém

# Default ndots=5 v Kubernetes
# Query: api.stripe.com

# DNS search poradie:
1. api.stripe.com.default.svc.cluster.local (NXDOMAIN)
2. api.stripe.com.svc.cluster.local (NXDOMAIN)
3. api.stripe.com.cluster.local (NXDOMAIN)
4. api.stripe.com. (SUCCESS)

# 4 DNS queries pre jedno externé meno!

Riešenie

# Pod spec so zníženým ndots
spec:
  dnsConfig:
    options:
      - name: ndots
        value: "2"  # Znížené z 5

# Alebo pridaj trailing bodku pre externé mená
# api.stripe.com. (absolútne meno, žiadne search)

Checklist

## NodeLocal DNS Cache Setup

### Inštalácia
- [ ] Deploy NodeLocal DaemonSet
- [ ] Nakonfiguruj kubelet clusterDNS
- [ ] Over že pody používajú 169.254.20.10

### Konfigurácia
- [ ] Nastav vhodné cache TTL
- [ ] Povoľ prefetch pre populárne entries
- [ ] Nakonfiguruj resource limity

### Monitoring
- [ ] Dashboard s cache hit rate
- [ ] Alert na DNS latenciu > 10ms
- [ ] Alert na zlyhania NodeLocal podu

### Optimalizácia
- [ ] Zváž zníženie ndots
- [ ] Použi absolútne DNS mená pre externé služby
- [ ] Monitoruj cache hit rates

Záver

DNS je skrytý Kubernetes bottleneck:

  1. Každé volanie služby potrebuje DNS lookup
  2. CoreDNS cez sieť pridáva 5-20ms per query
  3. NodeLocal cache znižuje na 0.2ms (29x rýchlejšie)
  4. 92% cache hit rate v produkcii

Nainštaluj NodeLocal DNS Cache a zníž svoju tail latenciu.


Súvisiace články

Súvisiace články

Citujte tento článok

Ak na článok odkazujete, pridajte pôvodnú URL a uveďte autora.

Michal Drozd. "CoreDNS vs NodeLocal DNS Cache: Zníženie Kubernetes DNS Latencie 10x". https://www.michal-drozd.com/sk/blog/coredns-nodelocal-benchmark/ (Publikované 8. mája 2025).