Google'i blogi toimetajalt: Kas olete kunagi mõelnud, kuidas Google Cloud Technical Solutions (TSE) insenerid tegelevad teie tugiteenuse päringutega? TSE tehnilise toe inseneride vastutusalas on kasutajate kirjeldatud probleemide allika tuvastamine ja kõrvaldamine. Mõned neist probleemidest on üsna lihtsad, kuid aeg-ajalt võib ette tulla päring, mis nõuab mitme inseneri tähelepanu. Selles artiklis räägib üks TSE töötaja meile ühest väga keerulisest probleemist, millega ta hiljuti kokku puutus — . Selles loos näeme, kuidas insenerid olukorra lahendasid ja mida uut nad vea kõrvaldamise käigus õppisid. Loodame, et see lugu mitte ainult ei räägi teile sügavalt juurdunud veast, vaid annab ka ülevaate protsessidest, mis toimuvad Google Cloudi tugiteenusesse pöördumise käigus.

Vea ja probleemide lahendamine on samaaegselt nii teadus kui kunst. Kõik algab hüpoteesi loomisest süsteemi ebatavalise käitumise põhjuse kohta, millele järgneb selle katsetamine. Kuid enne hüpoteesi formuleerimist peame selgelt määratlema ja täpselt sõnastama probleemi. Kui küsimus kõlab liiga ähmaselt, peate kõik korralikult analüüsima; just sellega seondubki probleemide lahendamise "kunst".
Google Cloudi keskkonnas keerustuvad sarnased protsessid kümme korda keerulisemaks, kuna Google Cloud püüab kõikidest jõududest tagada oma kasutajate privaatsust. Selle tõttu pole TSE inseneridel juurdepääsu teie süsteemide redigeerimisele ega ka võimalust vaadata konfigureerimisi nii vabalt nagu seda teevad kasutajad. Seetõttu ei saa me (insenerid) meie hüpoteeside testimiseks kiiresti süsteemi muuta.
Mõned kasutajad arvavad, et me lahendame kõik nagu autoremonditöökoda, ja saadavad meile lihtsalt virtuaalmasina ID, samas kui tegelikult toimub protsess vestluse vormis: teabe kogumine, hüpoteeside koostamine ja kinnitamine (või ümberlükkamine) ning lõpuks probleemide lahendamine toimub kliendiga suhtlemise kaudu.
Samuti probleem
Täna on meil hea lõpuga lugu. Üks edu põhjus käesoleva juhtumi lahendamisel seisneb väga detailse ja täpse probleemikirjelduse koostamises. Allpool on esitatud esimese piletipäringu koopia (redigeeritud, et varjata konfidentsiaalset teavet):

Selles teadetes on palju kasulikku teavet meie jaoks:
- On märgitud konkreetne VM
- On märgitud probleem — DNS ei tööta
- On näidatud, kus probleem avaldub — VM ja konteiner
- On kirjeldatud samme, mida kasutaja tegi probleemi määratlemiseks
Pöördumine registreeriti kui „P1: Kritiline mõju — teenus ei tööta tootmises“, mis tähendab pidevat olukorra jälgimist 24/7 päikesejälgimise süsteemi kohaselt (lisainfo leiate lingilt Kuna iga kord, kui probleem jõuab meie Zürichi meeskonda, on see juba üle maailma rännanud, kuna seda edastatakse ühe tehnilise toe meeskonnalt teisele igas ajavööndis. Sel hetkel oli kasutaja juba astunud samme olukorra leevendamiseks, kuid kartis sarnaste olukordade kordumist tootmises, kuna peamine põhjus ei olnud endiselt tuvastatud.
Kuna pilet jõudis Zürichi, oli meil juba järgmine teave:
- Sisu
/etc/hosts - Sisu
/etc/resolv.conf - Kokkuvõte
iptables-save - Meeskonna kogutud
ngreppcap fail
Selle teabega olime valmis minema järgmisele etapile, "uurimine" ja tõrkeotsing.
Meie esimesed sammud
Esmalt kontrollisime logisid ja metaandmete serveri staatust ning veendusime, et see töötab õigesti. Metaandmete server vastab IP-aadressile 169.254.169.254 ja vastutab muu hulgas domeeninimede haldamise eest. Kontrollisime ka, et tulemüür töötab VM-iga õigesti ja ei blokeeri pakette.
See oli mingi kummaline probleem: nmapi kontroll lükkas ümber meie peamise hüpoteesi UDP-pakettide kadumisest, seetõttu mõtlesime välja veel mõned võimalused ja viisid nende kontrollimiseks:
- Kas pakettide kadumine on juhuslik? => Kontrolli iptables reegleid
- Ei ole liiga väike ? => Проверить вывод
ip a show - Kas probleem mõjutab ainult UDP pakette või ka TCP? => Käivita
dig +tcp - Kas genereeritud dig paketid naasevad? => Käivita
tcpdump - Kas libdns töötab korrektselt? => Käivita
stracepakettide edastamise kontrollimiseks mõlemal suunal
Siin otsustame kasutajaga helistada, et probleeme elavalt lahendada.
Kõne käigus suudame kontrollida mitmeid asju:
- Pärast mitmeid kontrollimisi välistame iptables reeglid põhjuste hulgast
- Kontrollime võrgu liideseid ja marsruuditabeleid ning kontrollime MTU õigsust
- Avastame, et
dig +tcp google.com(TCP) töötab nagu peab, kuiddig google.com(UDP) ei tööta - Käivitades
tcpdumptoimib praegudig, avastame, et UDP paketid naasevad - Käivitame
strace dig google.comja näeme, kuidas dig õigesti kutsubsendmsg()jarecvms(), kuid teine katkeb ajaülevaate tõttu
Kahjuks lõppeb vahetus ja peame edastama probleemi järgmisse ajavööndisse. Sellegipoolest tekitas pöördumine meie meeskonnas huvi, ning kolleeg soovitab luua algse DNS paketi Python'i mooduli scrapy abil.
from scapy.all import *
answer = sr1(IP(dst="169.254.169.254")/UDP(dport=53)/DNS(rd=1,qd=DNSQR(qname="google.com")),verbose=0)
print ("169.254.169.254", answer[DNS].summary())See lõik loob DNS paketi ja saadab päringu metadata serverile.
Kasutaja käivitab koodi, DNS vastus tagastatakse ja rakendus selle vastu võtab, kinnitades, et võrgu tasandil ei esine probleeme.
Pärast järjekordset „maailmareisi“ pöördumine naaseb meie meeskonda ja ma võtan selle täielikult enda peale, uskudes, et kasutajale on mugavam, kui pöördumine lõpetab ringlemise.
Samas nõustub kasutaja lahkelt jagama süsteemi pildifaili. Need on väga head uudised: võimalus ise süsteemi katsetada kiirendab tõrgete lahendamist, kuna mul ei ole enam vaja paluda kasutajal käivitada käske, saata mulle tulemusi ja analüüsida neid, saan kõik ise teha!
Kolleegid hakkavad mind vaikselt kadestama. Lõunal arutame juhtumit, kuid kedagi ei paista olema ideed, mis toimub. Õnneks on kasutaja ise juba astunud samme tagajärgede leevendamiseks ja ei ole kuhugi kiirustamas, nii et meil on aega probleemi analüüsida. Ja kuna meil on pilt, saame teha kõiki huvitavaid teste. Suurepärane!
Astudes sammu tagasi
Üks kõige populaarsemaid küsimusi süsteemitehniku tööintervjuul kõlab nii: „Mis juhtub, kui te pingite ?» Вопрос шикарный, так как кандидату необходимо описать пусть от оболочки до пользовательского пространства, до ядра системы и далее к сети. Я улыбаюсь: иногда вопросы с интервью оказываются полезны и в реальной жизни…
Otsustan kasutada seda värbamis küsimust praeguse probleemi juures. Üldiselt, kui te proovite määratleda DNS nime, juhtub järgmist:
- Rakendus kutsub üles süsteemi teeki, näiteks libdns
- libdns kontrollib süsteemi konfiguratsiooni, et teada saada, millisele DNS-serverile pöörduda (diagrammil on see 169.254.169.254, metadata server)
- libdns kasutab süsteemi kutsungite abil UDP soketi (SOCK_DGRAM) loomist ja UDP pakettide edastamist DNS päringuga mõlemale poole
- Sysctl liidese kaudu saab UDP steki seadistada tuuma tasemel
- Tuumal suheldakse riistvara kaudu pakettide edastamiseks võrku läbi võrguliidese
- Hüpervisoor jälgib ja edastab paketi metateabe serverile, kui see temaga kontakti saab.
- Metateabe server oma võlujõududega määrab DNS nime ja tagastab vastuse samamoodi.

Tuletan meelde, milliseid hüpoteese oleme juba arutanud:
Hüpotees: Raamatukogud on purunenud.
- Test 1: käia süsteemis strace'iga, kontrollida, kas dig kutsub üles õiged süsteemi kutsed.
- Tulemus: õiged süsteemi kutsed kutsutakse üles.
- Test 2: kontrollida srapy kaudu, kas suudame nimesid määrata, vältides süsteemi raamatukogusid.
- Tulemus: suudame.
- Test 3: käia rpm –V paketi libdns ja md5sum raamatukogu failide peal.
- Tulemus: raamatukogu kood on täielikult identne koodiga töötavas operatsioonisüsteemis.
- Test 4: mountida kasutaja root-süsteemi pilt VM-is ilma sarnase käitumiseta, käia chroot'iga, vaadata, kas DNS töötab.
- Tulemus: DNS töötab õigesti.
Katsed põhjal tehtud järeldus: probleem ei ole raamatukogudes.
Hüpotees: DNS seadetesse on tehtud viga.
- Test 1: kontrollida tcpdump'i ja jälgida, kas DNS paketid saadetakse ja tagastatakse õigesti pärast dig'i kasutamist.
- Tulemus: paketid edastatakse õigesti.
- Test 2: kontrollida serveris uuesti.
/etc/nsswitch.confja/etc/resolv.conf - Tulemus: kõik on õigesti.
Katsed põhjal tehtud järeldus: probleem ei ole DNS-i konfiguratsioonis
Hüpotees: tuum on rikutud
- Test: installige uus tuum, kontrollige allkirja, taaskäivitage
- Tulemus: sarnane käitumine
Katsed põhjal tehtud järeldus: tuum ei ole rikutud
Hüpotees: kasutaja võrgu (või hüperviisori võrgu liidese) vale käitumine
- Test 1: kontrollige tulemüüriseadeid
- Tulemus: tulemüür laseb DNS-paketid mööda nii hostis kui ka GCP-s
- Test 2: peidake liiklust ja jälgige DNS-päringute edastamise ja vastuse õigsust
- Tulemus: tcpdump kinnitab hosti vastuspakettide vastuvõtmist
Katsed põhjal tehtud järeldus: probleem ei ole võrkus
Hüpotees: metandmete server ei tööta
- Test 1: kontrollige metandmete serveri logisid anomaaliate osas
- Tulemus: logides ei ole anomaaliaid
- Test 2: ümber minna metandmete serverist läbi
dig @8.8.8.8 - Tulemus: lahendamine katkestatakse isegi ilma metandmete serverit kasutamata
Katsed põhjal tehtud järeldus: probleem ei ole metandmete serveris
Kokkuvõte: oleme testinud kõiki alamsüsteeme, välja arvatud täidesaatva keskkonna seadistusi!
Süvenedes tuuma täidesaatva keskkonna seadistustesse
Tuumapunkti täidesaatva keskkonna seadistamiseks saate kasutada käsurea (grub) või sysctl liidese valikuid. Ma piilusin sisse /etc/sysctl.conf ja mõtlesin, et leidisin mõned kohandatud seaded. Tundub, et olen millegi kallal kinni, jätsin kõrvale kõik mitte-vervõrgu või mitte-tcp seaded, jäädes vaid väikese grupi seadmeteni. net.core. Siis suundusin sinna, kus VM-id asuvad hosti õigused, ning hakkasin järk-järgult rakendama seadistusi katki läinud VM-iga, kuni jõudsin kurjategijani:
net.core.rmem_default = 2147483647Siin on see, mis rikub DNS konfiguratsiooni! Leidsin kuriteovahendi. Kuid miks see juhtub? Mul oli endiselt vaja motiivi.
DNS pakettide põhikoguse seadistus käib järgmise kaudu net.core.rmem_default. Tüüpiline väärtus varieerub umbes 200KiB vahel, kuid kui teie server saab palju DNS pakette, võite suurendada puhvri suurust. Kui uue paketi saabumise ajal on puhver täis, näiteks seetõttu, et rakendus ei töötle seda piisavalt kiiresti, hakkate pakette kaotama. Meie klient suurendas õigesti puhvri suurust, kuna kartis andmete kadu, kuna kasutas DNS pakettide kaudu metrikate kogumise rakendust. Väärtus, mille ta seadis, oli maksimaalne võimalik: 231-1 (kui seada 231, tagastab tuum «INVALID ARGUMENT»).
Äkitselt taipasin, miks nmap ja scapy töötasid korrektselt: nad kasutasid tooreid sokette! Toored soketid erinevad tavalisest: need töötavad iptables'i ringi ning neid ei puhverdata!
Aga miks «liialt suur puhverdus» tekitab probleeme? See ei toimi ilmtingimata nii, nagu oli kavandatud.
Selleks ajaks olin ma suutnud probleemi paljude kernelite ja distributsioonide peal paljundada. Probleem avaldus juba kernelis 3.x ja nüüd ka kernelis 5.x.
Tõepoolest, kui käivitada
sysctl -w net.core.rmem_default=$((2**31-1)), DNS lakkas töötamast.
Hakkasin otsima töötavaid väärtusi lihtsa binaarotsingu algoritmi abil ja leidsin, et 2147481343 juures töötab süsteem, kuid see number oli minu jaoks mõttetu numbrikombinatsioon. Soovitasin kliendil proovida seda numbrit ja ta vastas, et süsteem töötas google.com-i puhul, kuid siiski andis teistel domeenidel vea, seega jätkasin oma uurimistööd.
Installisin , tööriista, mida oleks pidanud varem kasutama: see näitab, kuhu täpselt tuumale pakett jõuab. Süüdlaseks osutus funktsioon udp_queue_rcv_skb. Laadisin alla tuuma allikakoodid ja lisasin paar et jälgida, kuhu täpselt pakett läheb. Leidsin kiiresti vajaliku tingimuse if, ja mõnda aega lihtsalt jõllitasin seda, sest just siis kõik lõpuks klappis: 231-1, mõtetu number, mitte_functioning domeen… Probleem oli koodijupis __udp_enqueue_schedule_skb:
if (rmem > (size + sk->sk_rcvbuf))
goto uncharge_drop;Palun pange tähele:
rmemon tüüpi intsizeon tüüpi u16 (mitte-allkirjastatud kuueteistbitine int) ja salvestab paketi suurusesk->sk_rcybufon tüüp int ja salvestab puhversuuruse, mis definitsiooni kohaselt on võrdne väärtuseganet.core.rmem_default
Kui sk_rcvbuf läheneva 231, paketi suuruse summamine võib viia . Ja kuna see on int, muutub selle väärtus negatiivseks, nii et tingimus muutub tõeliseks, kui see peaks olema vale (rohkem selle kohta saab lugeda ).
Viga parandatakse triviaalsete meetoditega: tüübimuutmine unsigned int. Rakendasin paranduse ja käivitasin süsteemi uuesti, pärast mida DNS hakkas jälle töötama.
Võidu maitse
Saatsin oma leiud kliendile ja saatsin kerniparand. Olen rahul: iga pusletükk mõistatusest klappis kokku, suudan täpselt selgitada, miks me nägime seda, mida nägime, ja mis kõige tähtsam, suutsime leida lahenduse probleemile tänu koostööle!
Peab tunnistama, et juhtum on haruldane ning õnneks ei saa me kasutajatelt nii keerulisi päringuid sageli.
Allikas: habr.com
