A mai modern, mikroservice alapú alkalmazások világában a Kubernetes vált a konténer-orchestráció de facto szabványává. Egy ilyen dinamikus és elosztott rendszerben elengedhetetlen, hogy az egyes komponensek – a Podok – hatékonyan és megbízhatóan megtalálják egymást, valamint a külső erőforrásokat. Ennek a létfontosságú feladatnak a középpontjában áll a DNS (Domain Name System) feloldás. De hogyan is működik pontosan a DNS feloldás egy Kubernetes fürtön belül? Miért kritikus ez a rendszer stabilitása és teljesítménye szempontjából? Merüljünk el együtt a Kubernetes DNS feloldásának mélységeibe!
A Kubernetes nemcsak a konténerek futtatásáért felel, hanem egy kifinomult hálózati réteget is biztosít, amely lehetővé teszi a Podok közötti kommunikációt. Ennek a hálózati rétegnek a DNS feloldás az egyik legfontosabb sarokköve. Képzeljük el, hogy egy webalkalmazás (egy Pod) adatbázishoz (egy másik Podhoz) szeretne csatlakozni. A Podok IP-címei rendkívül dinamikusak lehetnek: egy Pod bármikor leállhat, újraindulhat, vagy átköltözhet egy másik Node-ra, miközben új IP-címet kap. Ahelyett, hogy az alkalmazások keményen kódolt IP-címeket használnának, egy stabil, emberi nyelven olvasható nevekkel operáló rendszerre van szükségük, ami képes ezeket a neveket dinamikusan IP-címekre fordítani. Ez a feladat a Kubernetes DNS-szolgáltatásáé.
A központi elem: CoreDNS
A Kubernetes kezdetben a kube-dns nevű szolgáltatást használta a DNS feloldásra, de mára a CoreDNS vált a szabványos és alapértelmezett megoldássá. A CoreDNS egy rugalmas, bővíthető DNS szerver, amelyet kifejezetten konténeres környezetekre optimalizáltak. A Kubernetesben a CoreDNS egy vagy több Pod formájában fut, általában a kube-system
névtérben, és egy Service-en keresztül érhető el. Ez a Service garantálja, hogy a CoreDNS Podok meghibásodása esetén is folyamatosan elérhető marad a DNS szolgáltatás, mivel a Service automatikusan átirányítja a kéréseket az egészséges Podokhoz.
A CoreDNS konfigurációja egy ConfigMap
objektumban található, amely a Corefile
nevű fájlt tartalmazza. Ez a fájl határozza meg, hogy a CoreDNS hogyan dolgozza fel a DNS kéréseket, milyen zónákat felügyel, és hogyan továbbítja az ismeretlen kéréseket. Egy tipikus Corefile
a Kubernetes fürtön belüli nevek feloldására vonatkozó szabályokat, valamint a külső nevek feloldására szolgáló továbbítási (forwarding) szabályokat is tartalmazza. Ez a rugalmasság lehetővé teszi a rendszergazdák számára, hogy finomhangolják a DNS viselkedését a fürt specifikus igényeihez, például belső privát zónák kezeléséhez vagy a külső DNS szerverek preferenciáihoz.
Hogyan oldják fel a Podok a belső szolgáltatásokat? (Szolgáltatásfelfedezés)
A Kubernetes DNS-szolgáltatásának egyik legfontosabb funkciója a szolgáltatásfelfedezés (Service Discovery) a fürtön belül. Amikor egy alkalmazás Pod egy másik szolgáltatást szeretne elérni, nem az adott szolgáltatást futtató Podok IP-címét használja közvetlenül, hanem a Kubernetes Service absztrakcióját. A Service egy stabil hálózati névvel és IP-címmel (a ClusterIP-vel) látja el a Podok egy csoportját, amelyek ugyanazt a funkciót látják el. Ez az absztrakció kritikus, mivel a Podok életciklusa rövid, IP-címeik dinamikusak, de a Service neve és ClusterIP-je stabil marad.
Minden egyes Kubernetes Service-hez a CoreDNS automatikusan létrehoz egy DNS bejegyzést. A leggyakoribb formátum a következő:
<service-name>.<namespace>.svc.cluster.local
Például, ha van egy my-app
nevű Service a default
névtérben, akkor az a my-app.default.svc.cluster.local
néven érhető el. A Podok többsége azonban egyszerűbben is hivatkozhat ezekre a nevekre, köszönhetően a kubelet által konfigurált search
tartományoknak.
Amikor egy Pod elindul, a kubelet – a Node-on futó ügynök – beállítja a Pod resolv.conf
fájlját. Ez a fájl tartalmazza a DNS szerverek IP-címét (amely a CoreDNS Service ClusterIP-je), valamint a keresési tartományokat (search domains
). Egy tipikus resolv.conf
fájl így nézhet ki egy Podban:
nameserver 10.96.0.10 # A CoreDNS Service ClusterIP-je
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
Ez a konfiguráció lehetővé teszi, hogy a Podok rövid nevekkel is hivatkozhassanak Service-ekre:
my-app
: Ezt a nevet asearch
tartományok kiegészítik, így próbálja feloldani amy-app.default.svc.cluster.local
nevet. Ha a Pod és a Service ugyanabban a névtérben vannak, ez elegendő.my-app.other-namespace
: Ezt a nevet asearch
tartományok kiegészítik, így próbálja feloldani amy-app.other-namespace.svc.cluster.local
nevet.
Amikor egy Pod DNS kérést indít (pl. ping my-app
), a kérés a nameserver
bejegyzésben megadott IP-címre, azaz a CoreDNS Service-re kerül. A CoreDNS ekkor kikeresi a hozzá tartozó Service-t és annak Endpoints objektumát. Az Endpoints objektum tartalmazza azoknak a Podoknak az IP-címeit, amelyek az adott Service mögött állnak. A CoreDNS visszaküldi a kérésre az egyik Endpoints Pod IP-címét, és a Pod felépítheti a kapcsolatot.
Különleges Service típusok és DNS bejegyzéseik
A Kubernetes különböző típusú Service-eket kínál, amelyek mindegyike eltérő DNS viselkedéssel bír:
- ClusterIP Services: Ahogy fentebb említettük, ezekhez a Service-ekhez egy stabil ClusterIP és egy A-rekord tartozik:
<service-name>.<namespace>.svc.cluster.local
->ClusterIP
(A record)
A CoreDNS általában terheli meg a forgalmat (round-robin) az Endpoints Podok között, de a tényleges terheléselosztást a kube-proxy végzi a Node-okon.
- Headless Services: Ez egy különleges Service típus, amely nem kap ClusterIP-t. Ehelyett, amikor egy Headless Service-re hivatkoznak, a CoreDNS közvetlenül az összes mögöttes Pod IP-címét visszaadja. Ez különösen hasznos, ha az alkalmazásnak közvetlen hozzáférésre van szüksége az egyes Podokhoz (pl. állapotfüggő (stateful) alkalmazások, mint az adatbázisok). A Headless Service-ekhez a következő DNS rekordok generálódnak:
<service-name>.<namespace>.svc.cluster.local
-> Több A-rekord, minden mögöttes Pod IP-címével.<pod-name>.<service-name>.<namespace>.svc.cluster.local
-> Egy A-rekord, az adott Pod IP-címével (ha a Pod neve be van állítva ahostname
mezőben, ami gyakori a StatefulSet-eknél).
Ez utóbbi lehetővé teszi az egyes állapotfüggő Podok egyedi, stabil nevekkel történő elérését, ami kritikus lehet például egy
StatefulSet
által kezelt adatbázis klaszter tagjainak azonosításánál. - ExternalName Services: Ezek a Service-ek nem mutatnak Podokra a fürtön belül, hanem egy külső DNS névre (CNAME). Amikor egy Pod egy ilyen Service-re hivatkozik, a CoreDNS egyszerűen visszaadja az
ExternalName
értékét CNAME rekordként, átirányítva a kérést egy külső DNS feloldóhoz.<service-name>.<namespace>.svc.cluster.local
-><external-name>
(CNAME record)
Ez hasznos lehet, ha egy külső adatbázist, vagy más szolgáltatást szeretnénk elérni egy stabil, belső Kubernetes néven keresztül.
Hogyan oldják fel a Podok a külső DNS neveket?
Amikor egy Pod olyan tartománynevet próbál feloldani, amely nem tartozik a Kubernetes belső tartományai közé (pl. google.com
, api.example.com
), a CoreDNS Corefile
-jában található továbbítási (forwarding) szabályok lépnek életbe. Ezek a szabályok általában a CoreDNS-t arra utasítják, hogy a külső kéréseket továbbítsa a Node-ok resolv.conf
fájljában megadott DNS szerverekre, vagy előre definiált, külső DNS szerverekre (pl. Google DNS: 8.8.8.8, 8.8.4.4).
Ez biztosítja, hogy a Podok ne csak a fürtön belüli erőforrásokat, hanem az interneten elérhető szolgáltatásokat is képesek legyenek elérni. A CoreDNS képes intelligensen kezelni ezeket a kéréseket, optimalizálva a teljesítményt a válaszidők csökkentésével és a megbízhatóság növelésével.
Pod szintű DNS konfiguráció: DNSPolicy és dnsConfig
A Kubernetes rendkívül rugalmas a Podok DNS konfigurációjában. Bár a kubelet alapértelmezetten beállítja a resolv.conf
fájlt, ezt felül lehet írni a Pod definíciójában a dnsPolicy
és dnsConfig
mezők segítségével. Ez a rugalmasság lehetővé teszi, hogy egyedi hálózati igényekkel rendelkező Podok is hatékonyan működjenek a fürtön belül.
dnsPolicy
: Meghatározza, hogyan kezeli a Pod a DNS feloldást.ClusterFirst
(alapértelmezett): A Pod először a fürt DNS-ére (CoreDNS) küldi a kéréseket. Ha nem találja a nevet, továbbítja a Node-on beállított DNS szerverek felé. Ez a leggyakoribb és ajánlott beállítás a legtöbb alkalmazáshoz.Default
: A Pod közvetlenül a Noderesolv.conf
fájljában szereplő DNS szervereket használja. Ez ritkán használt a legtöbb alkalmazásnál, mivel elveszíti a Kubernetes belső szolgáltatásfelfedezési képességeit, és nem tudja feloldani a fürtön belüli Service neveket.None
: Ez a házirend lehetővé teszi a teljesen egyedi DNS konfigurációt adnsConfig
mező segítségével. A Kubernetes figyelmen kívül hagyja a Node alapértelmezett DNS beállításait, és adnsConfig
által megadott beállításokat alkalmazza. Ez a leghatékonyabb módja a finomhangolásnak.ClusterFirstWithHostNet
: Hasznos, ha a Pod a Host hálózati névteret használja (hostNetwork: true
). Ebben az esetben a Pod a CoreDNS-t fogja használni a fürtön belüli nevekhez, majd a Node DNS-ét a külső nevekhez, ugyanúgy, mint aClusterFirst
, de a Host hálózati beállításokat figyelembe véve.
dnsConfig
: Csak akkor használható, ha adnsPolicy
értékeNone
. Lehetővé teszi, hogy expliciten megadjuk anameservers
,searches
ésoptions
beállításokat a Podresolv.conf
fájljához. Ez rendkívül hasznos lehet speciális esetekben, például ha egy Podnak egy adott DNS szervert kell használnia egy belső hálózaton belül, amely nem része a Kubernetes fürtnek, vagy ha egyedi keresési tartományokra van szükség.
Példa dnsConfig
használatára:
apiVersion: v1
kind: Pod
metadata:
name: my-custom-dns-pod
spec:
containers:
- name: my-container
image: nginx
dnsPolicy: None
dnsConfig:
nameservers:
- 192.168.1.100 # Egyedi DNS szerver
- 8.8.8.8
searches:
- mydomain.local
- default.svc.cluster.local
options:
- name: ndots
value: "2"
- name: edns0
Ez a konfiguráció felülírja a Pod alapértelmezett DNS beállításait, és a megadott szervereket, keresési tartományokat és opciókat használja. Fontos megjegyezni, hogy az ndots
opció befolyásolja, hogy hány pontot kell tartalmaznia egy névnek ahhoz, hogy abszolút névnek tekintsék, mielőtt a keresési tartományokat hozzáadva próbálnák feloldani. Egy túl magas ndots
érték lassíthatja a feloldást, mivel a DNS kliensnek több felesleges lekérdezést kell indítania a keresési tartományokkal, mielőtt a globális DNS-hez fordulna. Az alapértelmezett érték 5 Kubernetesben.
A DNS feloldás teljesítménye és hibaelhárítása
A DNS feloldás kritikus fontosságú a Kubernetes alkalmazások teljesítménye szempontjából. Lassú DNS feloldás jelentősen növelheti a kérések késleltetését (latency), ami az alkalmazás lassulásához vagy akár hibáihoz vezethet. A CoreDNS konfigurációjának optimalizálása, a megfelelő caching beállítások és elegendő erőforrás (CPU, memória) biztosítása a CoreDNS Podok számára elengedhetetlen a jó teljesítményhez. A CoreDNS több plugin-t is kínál, amelyekkel a teljesítmény tovább növelhető, például a cache
plugin bekapcsolásával.
Gyakori DNS hibaelhárítási tippek Kubernetesben:
- Ellenőrizd a CoreDNS Podokat: Győződj meg róla, hogy a CoreDNS Podok futnak és egészségesek (
kubectl get pods -n kube-system -l k8s-app=kube-dns
). Ellenőrizd a logokat (kubectl logs -n kube-system -l k8s-app=kube-dns
) a lehetséges hibákért. - Ellenőrizd a CoreDNS Service-t: Győződj meg róla, hogy a CoreDNS Service létezik és a megfelelő ClusterIP-vel rendelkezik (
kubectl get svc -n kube-system -l k8s-app=kube-dns
). Győződj meg arról is, hogy a Service Endpoints-jei a CoreDNS Podokra mutatnak. - Teszteld a DNS feloldást egy Podból: Indíts egy debug Podot (pl.
busybox
vagyalpine
image-el) és próbálj meg feloldani belső és külső neveket anslookup
vagydig
parancsokkal.kubectl run -it --rm --image=busybox:1.28 dns-test -- nslookup kubernetes.default
kubectl run -it --rm --image=busybox:1.28 dns-test -- nslookup my-app.default.svc.cluster.local
(cseréld le a Service nevet és névtért)kubectl run -it --rm --image=busybox:1.28 dns-test -- nslookup google.com
Ezek a tesztek segítenek elkülöníteni, hogy a probléma a belső vagy a külső DNS feloldással van-e.
- Ellenőrizd a Pod
resolv.conf
fájlját: Lépj be egy Podba (kubectl exec -it <pod-name> -- sh
) és nézd meg a/etc/resolv.conf
tartalmát. Győződj meg róla, hogy anameserver
a CoreDNS Service IP-jére mutat, és asearch
tartományok helyesek a Pod névtér beállításai szerint. - Hálózati szabályok és tűzfalak: Győződj meg róla, hogy nincsenek olyan hálózati szabályok (pl.
NetworkPolicy
vagy külső tűzfalak), amelyek blokkolják a DNS kéréseket a Podok és a CoreDNS Service között.
Következtetés
A DNS feloldás egy Kubernetes fürtön belül sokkal több, mint egyszerű névtől IP-címre fordítás. Ez a rendszer lelke, amely lehetővé teszi a szolgáltatásfelfedezést, a dinamikus komponensek közötti kommunikációt és az alkalmazások robusztus működését. A CoreDNS, mint központi szolgáltatás, a Service-ekkel és Endpoints-okkal együtt egy kifinomult mechanizmust biztosít, amely a Podok számára átlátszóan kezeli a hálózati topológia változásait.
A dnsPolicy
és dnsConfig
révén a fejlesztők és üzemeltetők finomhangolhatják a DNS viselkedést, biztosítva az optimális teljesítményt és a speciális igények kielégítését. A Kubernetes DNS megértése kulcsfontosságú ahhoz, hogy hatékonyan diagnosztizálhassuk a hálózati problémákat és stabil, nagy teljesítményű alkalmazásokat futtathassunk ebben a komplex környezetben. A megfelelő konfiguráció és a rendszeres ellenőrzés garantálja, hogy a szolgáltatások mindig megtalálják egymást, és az alkalmazások zökkenőmentesen működjenek, hozzájárulva a modern, elosztott architektúrák sikeréhez.
Leave a Reply