15: DNS w Kubernetes

DNS w Kubernetes: Praktyczny przewodnik z nslookup

Cel zadania

Celem zadania jest zrozumienie jak działa system DNS w Kubernetes poprzez praktyczne wykorzystanie narzędzia nslookup do badania rozwiązywania nazw w klastrze.

Teoria

Jak działa CoreDNS w Kubernetes

Architektura CoreDNS

  • Pod systemowy: CoreDNS działa jako Pod w namespace kube-system
  • Wysoka dostępność: Domyślnie uruchamiane są dwie repliki dla redundancji
  • Service kube-dns: Dostępny pod stałym IP w klastrze (zazwyczaj 10.96.0.10)
  • ConfigMap: Konfiguracja poprzez coredns-config w namespace kube-system

Mechanizm działania

  1. Wykrywanie usług:
    • CoreDNS śledzi zmiany w API Kubernetes
    • Automatycznie aktualizuje rekordy DNS dla Services i Pods
    • Wykorzystuje watch mechanizm na zasobach K8s
  2. Rozwiązywanie nazw:
    • Format: <service>.<namespace>.svc.cluster.local
    • Obsługa zapytań DNS typu:
      • A/AAAA rekordy dla services
      • SRV rekordy (tylko dla headless services)
      • PTR rekordy (reverse DNS)
    • Format SRV: _port-name._port-protocol.service-name.namespace.svc.cluster.local
    • Wsparcie dla wildcards i subdomen
  3. Cache i wydajność:
    • Wbudowany mechanizm cache’owania
    • Optymalizacja zapytań poprzez TTL
    • Load balancing między replikami CoreDNS
  4. Integracja z kubelet:
    • Każdy Pod otrzymuje CoreDNS jako nameserver
    • Automatyczna konfiguracja przez kubelet
    • Obsługa DNS policy per Pod
  5. Wykrywanie Namespace źródłowego:
    • CoreDNS otrzymuje informację o namespace w metadanych zapytania DNS
    • Proces wygląda następująco:
      1. Podczas tworzenia Poda, kubelet konfiguruje jego /etc/resolv.conf
      2. W /etc/resolv.conf ustawiane są:
        • nameserver (IP serwera CoreDNS)
        • search (lista domen w kolejności:
          • test-XX.svc.cluster.local
          • svc.cluster.local
          • cluster.local)
        • options ndots:5 (domyślna konfiguracja K8s)
      3. Pod wysyła zapytanie DNS
      4. System DNS w Podzie, bazując na konfiguracji resolv.conf:
        • Jeśli nazwa ma mniej niż 5 kropek (ndots:5), kolejno dodaje sufiksy z search
        • Jeśli nazwa ma 5 lub więcej kropek, najpierw próbuje rozwiązać pełną nazwę
      5. Zapytanie trafia do CoreDNS, który:
        • Otrzymuje pełną nazwę DNS do rozwiązania
        • Bazując na strukturze nazwy (np. service.namespace.svc.cluster.local) wie jakiego zasobu dotyczy zapytanie
      6. CoreDNS rozwiązuje nazwę bazując na swojej cache i/lub odpytując API Kubernetes

Diagram: Flow rozwiązywania nazw DNS

graph LR
    POD["Pod"] -->|"1. nslookup nginx-dns"| RESOLV["/etc/resolv.conf<br/>nameserver: 10.96.0.10<br/>search: test-XX.svc.cluster.local"]
    RESOLV -->|"2. nginx-dns.test-XX.svc.cluster.local"| DNS["CoreDNS<br/>(kube-system)"]
    DNS -->|"3. Sprawdź w cache/API"| API["API Server"]
    API -->|"4. Service IP"| DNS
    DNS -->|"5. Odpowiedź: 10.96.x.x"| POD

    style POD fill:#e8f5e9
    style DNS fill:#e3f2fd,stroke:#1976d2
    style API fill:#fff3e0

Zadanie 1: Przygotowanie środowiska testowego

1.1. Utwórz plik deployment-dns-XX.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-dns-XX
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-dns-XX
  template:
    metadata:
      labels:
        app: nginx-dns-XX
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

1.2. Utwórz plik service-dns-XX.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-dns-XX
spec:
  type: ClusterIP
  selector:
    app: nginx-dns-XX
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80

1.3. Wdróż zasoby:

kubectl apply -f deployment-dns-XX.yaml
kubectl apply -f service-dns-XX.yaml

Zadanie 2: Badanie DNS z użyciem nslookup

2.1. Utwórz pod diagnostyczny:

kubectl run dns-test-XX -n test-XX --rm -it --image=busybox -- sh

2.2. Sprawdź podstawowe zapytanie DNS:

# W podzie testowym:
nslookup nginx-dns-XX

# Oczekiwany wynik:
# Server:    10.96.0.10
# Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
#
# Name:      nginx-dns-XX
# Address 1: 10.100.45.123 nginx-dns-XX.test-XX.svc.cluster.local

2.3. Sprawdź pełną nazwę domenową (FQDN):

# W podzie testowym:
nslookup nginx-dns-XX.test-XX.svc.cluster.local

# Ten sam wynik co powyżej

2.4. Sprawdź reverse DNS lookup:

# W podzie testowym (użyj IP z poprzedniego wyniku):
nslookup 10.100.45.123

# Powinien zwrócić nazwę serwisu

Zadanie 3: Zaawansowane zapytania DNS

3.1. Sprawdź rekordy SRV:

# W podzie testowym:
nslookup -type=srv _http._tcp.nginx-dns-XX.test-XX.svc.cluster.local

# Oczekiwany wynik:
# _http._tcp.nginx-dns-XX.test-XX.svc.cluster.local  service = 0 50 80 nginx-dns-XX.test-XX.svc.cluster.local

Najczęstsze problemy

Problem Rozwiązanie
nslookup nie działa Sprawdź działanie CoreDNS
Brak rozwiązania nazwy Weryfikuj poprawność FQDN
Timeout zapytania Sprawdź polityki sieciowe

Dobre praktyki DNS w K8s

  1. Nazewnictwo
    • Używaj krótkich, znaczących nazw serwisów
    • Zachowaj spójną konwencję nazewnictwa
    • Unikaj znaków specjalnych w nazwach
  2. Diagnostyka
    • Regularnie testuj rozwiązywanie DNS
    • Monitoruj działanie CoreDNS
    • Weryfikuj logi pod kątem błędów DNS
  3. Konfiguracja
    • Upewnij się, że CoreDNS ma wystarczające zasoby
    • Skonfiguruj odpowiednie TTL
    • Rozważ cachowanie DNS

Podsumowanie

  • DNS w Kubernetes działa automatycznie dla Services
  • Każdy Service ma unikalną nazwę FQDN
  • CoreDNS zapewnia niezawodne rozwiązywanie nazw
  • nslookup jest przydatnym narzędziem diagnostycznym

Przydatne komendy debugowania DNS

# Sprawdź status CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns

# Zobacz logi CoreDNS
kubectl logs -n kube-system -l k8s-app=kube-dns

# Sprawdź konfigurację CoreDNS
kubectl get configmap -n kube-system coredns -o yaml

# Zweryfikuj Service DNS
kubectl get svc -n kube-system kube-dns

results matching ""

    No results matching ""