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-configw namespacekube-system
Mechanizm działania
- Wykrywanie usług:
- CoreDNS śledzi zmiany w API Kubernetes
- Automatycznie aktualizuje rekordy DNS dla Services i Pods
- Wykorzystuje watch mechanizm na zasobach K8s
- 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
- Format:
- Cache i wydajność:
- Wbudowany mechanizm cache’owania
- Optymalizacja zapytań poprzez TTL
- Load balancing między replikami CoreDNS
- Integracja z kubelet:
- Każdy Pod otrzymuje CoreDNS jako nameserver
- Automatyczna konfiguracja przez kubelet
- Obsługa DNS policy per Pod
- Wykrywanie Namespace źródłowego:
- CoreDNS otrzymuje informację o namespace w metadanych zapytania DNS
- Proces wygląda następująco:
- Podczas tworzenia Poda, kubelet konfiguruje jego /etc/resolv.conf
- 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)
- Pod wysyła zapytanie DNS
- 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ę
- 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
- 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
- Nazewnictwo
- Używaj krótkich, znaczących nazw serwisów
- Zachowaj spójną konwencję nazewnictwa
- Unikaj znaków specjalnych w nazwach
- Diagnostyka
- Regularnie testuj rozwiązywanie DNS
- Monitoruj działanie CoreDNS
- Weryfikuj logi pod kątem błędów DNS
- 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