DNS vardų sistema yra labai svarbi bet kurios kompiuterinių tinklų sistemos dalis, įskaitant ir „Kubernetes“. Vidiniam tinklo adresų valdymui „Kubernetes“ naudoja „CoreDNS“ vardų sistemos serverį, kuris puikiai susitvarko su konteinerių tinklo sistemos ypatumais. Vienas jų - vidinių „Kubernetes“ tarnybų ir konteinerių adresų valdymas. Kiekvienas „Service“ tipo objektas „Kubernetes“ tinkle gauna savo DNS įrašą ir jį galima pasiekit tiek pirmojo lygio vardu: „serviso_vardas“, tiek antrojo: „serviso_vardas.vardu_sritis“, tiek ir „pilnu“ (FQDN vardo gale turi būti taškas) vardu: „serviso_vardas.vardu_sritis.svc.cluster.local“. Taip supaprastinamas „Kubernetes“ pritaikytų programinių sistemų kūrimas, nes pakanka žinoti sukurto serviso vardą ir programa galės naudotis tos tinklo tarnybos paslaugomis, nes „CoreDNS“ pasirūpins IP adreso suradimu ir bus galima užmegzti tinklo ryšį.
Tačiau prireikus rasti išorinės sistemos IP adresą, pavyzdžiui, konteineriui prireikus atlikti paiešką „Google“ paieškos sistemoje, pasireiškia tinklo vardų radimo subtilybės. Gavęs „google.com“ užklausą, konteineris nieko nežino apie „Google“, nes jo požiūriu tai yra bandymas rasti „google“ „Service“ tipo objekto adresą, „com“ vardų srityje. Tik nepavykus rasti tokio įrašo visuose klasterio „search domains“ domenų aprašuose, ši užklausa bus siunčiama į išorinius DNS vardų serverius, vienas kurių gali būti vietinio tinklo DNS serveris. Ir štai čia vietinio tinklo DNS serveris gali „pakišti kiaulę“, įtraukdamas savo vietinio tinklo domeno, pavyzdžiui, „home.lan“ į „Kubernetes“ „search domains“ sąrašą. Nepavykus rasti „google.com“ „Kubernetes“ tinkle, suformuojama užklausa rasti „google.com.home.lan“ adresą. Savaime suprantama, kad namų tinkle tokio adreso nėra. Tačau užuot atsiuntusi „NXDOMAIN“ atsakymą, nurodantį, kad įrašo rasti nepavyko ir reikia bandyti toliau, t.y. ieškoti tikro išorinio adreso, tinklo maršrutizatoriaus „DNSMasq“ tarnyba kažkodėl gražindavo „NODATA“ atsakymą. Tai sutrikdydavo vardų paieškos bandymų seką, konteineris nebeieškodavo „google.com“ domeno, nuspręsdamas, kad toks vardas neegzistuoja.
Tingintiems skaityti toliau - problemą pavyko išspręsti tinklo maršrutizatoriaus „DNSMasq“ programoje išjungus „Do not cache negative replies, e.g. for non existing domains“ nuostatą. Ją išjungus, „DNSMasq“ ėmė teisingai gražinti NXDOMAIN atsakymą ne tik neegzistuojantis.home.lan adresui, bet ir antro.lygio.home.lan ar google.com.home.lan adresams. Tiesa, gali būti, kad buvo kažkoks laikinas sutrikimas, nes dabar net ir įjungus šią nuostatą, DNS sistema gražina teisingą NXDOMAIN atsakymą. Na, o besidomintys DNS viduriais, gali skaityti toliau.
Bėdų galima išvengti, aiškiai nurodant pilną domeno adresą (FQDN), pasibaigiantį tašku: „google.com.“ Tokiu atveju yra nėra abejonių, kad tai yra išorinis DNS vardas. Bėda ta, kad paprastai niekas paskutinio taško nenaudoja, o įprastinėse OS nuostatose nurodyta, kad jei domeno vardas turi 1 ar daugiau taškų (ndots), tai šį vardą reikia laikyti absoliučiu ir neieškoti jo kombinacijos turimame domenų paieškos sąraše. Taigi teko ieškoti, kodėl DNS sistema neveikia, taip, kaip priklauso.
Problema buvo pastebėta „Transmission“ duomenų persiuntimo programos konteineryje, nes ši programa užsispyrusiai rašė, jog tinklo prievadas yra uždarytas, nors https://canyouseeme.org/ ar https://portchecker.co/ aiškiai rodė, kad tinklo prievado peradresavimas yra tinkamas ir paslauga yra pasiekiama. Pradėjus kapstyti giliau, paaiškėjo, kad „Transmission“ naudoja savą prievado peradresavimo tikrinimo svetainę http://portcheck.transmissionbt.com/, kuriai kaip URL lauką, nurodomas programoje nustatytas porto numeris.
Pirmas įtarimas (neteisingas) kilo, pamačius konteineryje paleistos curl programos klaidos pranešimą „curl: (6) Could not resolve host: portcheck.transmissionbt.com“, bandant atverti „Transmission“ prievadų tikrinimo paslaugą. Dalis programų, pavyzdžiui, „apt-get“ gavusios ir A ir AAAA įrašus, prioritetą teikia IPv6 adresui, nepaisant to, kad sistema gali neturėti IPv6 suderinamumo. Ypač, jei programa dar aptinka ir aktyvų IPv6 adresą, priskirtą tinko sąsajai. Tarp skliaustų esantis "6" pastūmėjo paieškas netinkama linkme. Tačiau atidžiai patikrinus visą TCP/IP konfigūraciją nuo konteinerio iki „Kubernetes“ serverio, IPv6 užuominų aptikti nepavyko, nes tikrai stengiausi išjungti IPv6.
Tuomet buvo sutelktas dėmesys į DNS tarnybų ataskaitas ir klaidų pranešimus. Tarp kitų klaidų, buvo aptiktas ir jau nebeveikiančios tarnybinės stoties adresas, kuri buvo išjungta baigus migraciją į naujai įsigytą tinklo saugyklą (apie tai bus atskira rašliava), tačiau net ir pataisius DNS tarnybų adresus, „curl“, o tuo pačiu ir „Transmission“ teberodė klaidų pranešimus, randant portcheck.transmissionbt.com adresą, nors pati DNS tarnyba puikiai surasdavo šios svetainės ir IPv4, ir IPv6 adresus. Tuomet buvo pradėta eksperimentuoti su konteinerio resolv.conf failo turiniu.
Tokiai klaidų paieškai labai patogu naudotis Kubernetes derinimo konteineriu, kurį galima prikabinti prie netinkamai veikiančios programos konteinerio (https://kubernetes.io/docs/tasks/debug/debug-application/debug-running-pod/). O tinklo problemoms spręsti kol kas nieko geriau, nei „Nicolaka Netshoot“ (https://github.com/nicolaka/netshoot) aptikti nepavyko. Taigi terminale paleidau derinimo konteinerį ir ėmiausi eksperimentų:
~ $ kubectl -n transmission debug -it transmission-55897f46dc-6lzq4 --image=nicolaka/netshoot
Defaulting debug container name to debugger-trzgx.
transmission-55897f46dc-6lzq4 ~ cat /etc/resolv.conf
search transmission.svc.cluster.local svc.cluster.local cluster.local home.lan
nameserver 10.1.0.10
options ndots:5
Pabandžius pašalinti „home.lan“ domeną iš paieškos sąrašo, pavyko prisijungti prie http://portcheck.transmissionbt.com sveitainės. Tas pats nutiko ir sumažinus „ndots“ parametro reikšmę iki 1. Tai leido suprasti, kad problema yra su vietinio tinklo DNS tarnyba. Pradėjus kapstytis po DNS sistemų ataskaitas, „OpenWRT“ ataskaitoje pastebėjau, kad ieškant „portcheck.transmissionbt.com.home.lan“ adreso, nurodomas ne NXDOMAIN atsakas, bet NODATA. Tai pasirodė keista, nes tikrai tokio DNS nėra ir negali būti mano vietiniame "home.lan" domene. Pradėjus našyt interneto platybes, teko aptikti įvairių diskusijų ir straipsnių ta tema, tačia po akimis pakliuvo „GitHub“ kodo saugykloje registruota „Pi-Hole“ projekto problema, kurioje siūloma „DNSMasq“ neleisti įsiminti neigiamų atsakymų. Panaršius „OpenWRT“ nuostatas, pavyko aptikri tokią nuostatą, uždraudžiančią įsiminti neigiamus atsakymus ir paskui juos pateikti iš podėlio. Ir vualia... Išjungus „Network->DHCP and DNS->Advanced Settings“ esančią „Do not cache negative replies, e.g. for not existing domains“ nuostatą, DNS adresų aptikimas pradėjo veikti, kaip priklauso.
Tiesa pasakius, kitą dieną pabandžius pasinagrinėti situaciją iš naujo - jos atkartoti nepavyko. Kiekvienas bandymas rasti kokį nors nesąmoningą adresą „home.lan“ domene baigdavosi teisingu NXDOMAIN atsakymu. Taigi, tikėtina, kad tai buvo kažkoks užstrigęs kažkoks nesąmoningas įrašas, kuris išsilaikė net ir po „OpenWRT“ maršrutizatoriaus perkrovimo. Bet bent jau šiokia tokia patirtis kapstantis po DNS veikimą buvo.