Nga redaktori i blogut të Google: A keni ndonjëherë kërkuar se si inxhinierët e Zgjidhjeve Teknike të Google Cloud (TSE) trajtojnë kërkesat tuaja për mbështetje? Detyra e inxhinierëve të mbështetjes teknike TSE përfshin identifikimin dhe zgjidhjen e burimeve të problemeve të raportuara nga përdoruesit. Disa nga këto probleme janë mjaft të thjeshta, por ndonjëherë ndodhet një kërkesë që kërkon vëmendjen e disa inxhinierëve. Në këtë artikull, një nga punonjësit e TSE do të na tregojë për një problem shumë të komplikuar nga praktika e tij e fundit — . Gjatë këtij tregimi, do të shohim se si inxhinierët arritën të zgjidhnin situatën dhe çfarë të reja mësuan gjatë përpjekjeve për të zgjidhur gabimin. Shpresojmë që kjo histori jo vetëm t'ju tregojë për një defekt të thellë, por gjithashtu të ofrojë një kuptim të proceseve që ndodhin gjatë paraqitjes së një kërkese në mbështetje të Google Cloud.

Zgjidhja e problemeve është njëkohësisht shkencë dhe art. Çdo gjë fillon me ndërtimin e një hipoteze për shkakun e sjelljes jo standard të sistemit, pas së cilës testi i saj është thelbësor. Megjithatë, para se të formuloni një hipotezë, duhet të përcaktojmë qartë dhe të formulojmë saktësisht problemin. Nëse pyetja është shumë e paqartë, do t'ju duhet të bëni një analizë të thellë; kjo është pikërisht ajo që përbën "artin" e zgjidhjes së problemeve.
Në kushtet e Google Cloud, këto procese komplikohen shumë, pasi Google Cloud përpiqet të garantojë privatësinë e përdoruesve të tij. Për këtë arsye, inxhinierët TSE nuk kanë as qasje për të edituar sistemet tuaja, as mundësi për të shqyrtuar konfiguracionet po aq gjerësisht sa bëjnë përdoruesit. Prandaj, për të kontrolluar ndonjë nga hipotezat tona, ne (inxhinierët) nuk mund të modifikojmë shpejt sistemin.
Disa disa përdorues mendojnë se ne do të rregullojmë gjithçka si në një servis automjetesh, dhe thjesht na dërgojnë id e makinës virtuale, ndërkohë që në të vërtetë procesi zhvillohet në format bisedash: mbledhja e informacionit, formimi dhe konfirmimi (ose hedhja poshtë) e hipotezave, dhe, në fund, zgjidhja e problemit ndërtohet mbi komunikimin me klientin.
Problemi në shqyrtim
Sot përpara nesh është një histori me një fund të mirë. Një nga arsyet e suksesit në zgjidhjen e rastit të propozuar është përshkrimi shumë i detajuar dhe i saktë i problemit. Më poshtë mund të shihni një kopje të parë të tiketës (e redaktuar, për të fshehur informacionin konfidencial):

Në këtë mesazh ka shumë informacion të dobishëm për ne:
- Është caktuar VM konkrete
- Është caktuar vetë problemi – DNS nuk funksionon
- Është caktuar ku shfaqet problemi – VM dhe kontejner
- Janë caktuar hapat që ka ndjekur përdoruesi për të përcaktuar problemin
Ankimi është regjistruar si «P1: Ndikim Kritike – Shërbimi i Pasishtëm në prodhim», që do të thotë mbikëqyrje të vazhdueshme të situatës 24/7 sipas skemës «Follow the Sun» (në lidhje mund të lexoni më shumë mbi ), me kalimin e saj nga një ekip mbështetje në tjetrin me çdo ndryshim të zonave kohet. Në thelb, deri në momentin që problemi arriti tek ekipi ynë në Cyrih, ai kishte bërë një rrethim të globit. Në këtë moment, përdoruesi kishte marrë masa për të reduktuar pasojat, por ishte i shqetësuar për një përsëritje të situatës në prodhim, pasi arsyeja kryesore ende nuk ishte zbuluar.
Në momentin që bileta arriti në Cyrih, ne kishim tashmë informacionin e mëposhtëm:
- Përmbajtja
/etc/hosts - Përmbajtja
/etc/resolv.conf - Përfundim
iptables-save - Të grumbulluara nga ekipi
ngrepskedari pcap
Me këto të dhëna ishim gati për të filluar fazën e 'hetimit' dhe diagnostikimit.
Hapat tanë të parë
Së pari, ne kontrolluam regjistrat dhe statusin e serverit të të dhënave dhe u siguruam që ai punonte siç duhet. Serveri i të dhënave përgjigjet në adresën IP 169.254.169.254 dhe, përveç të tjerave, është përgjegjës për menaxhimin e emrave të domeneve. Ne gjithashtu konfirmuam se firewalli funksiononte siç duhet me VM-në dhe nuk bllokonte paketat.
Ishte një problem i çuditshëm: kontrolli i nmap e hodhi poshtë hipotezën tonë kryesore për humbjen e paketave UDP, kështu që mendërisht nxorrëm disa mundësi dhe mënyra për t'i kontrolluar ato:
- A po shfaqen paketet përzgjedhshëm? => Kontrolloni rregullat e iptables
- A nuk është shumë e vogël ? => Проверить вывод
ip a shfaq - A e ndikon problemi vetëm paketat UDP ose edhe TCP? => Kryeni testimin
dig +tcp - A kthehen paketat e gjeneruara nga dig? => Kryeni testimin
tcpdump - A punon saktë libdns? => Kryeni testimin
stracepër të verifikuar transmetimin e paketave në të dy drejtimet
Këtu ne vendosim të telefonojmë përdoruesin për të zgjidhur problemet live.
Gjatë telefonatës, ne arrijmë të verifikojmë disa gjëra:
- Pas disa kontrolleve, ne përjashtojmë rregullat e iptables nga lista e shkaqeve
- Ne kontrollojmë ndërfaqet e rrjetit dhe tabelat e rrugës, dhe rishikojmë saktësinë e MTU
- Ne zbulojmë që
dig +tcp google.com(TCP) funksionon siç duhet, pordig google.com(UDP) nuk funksionon - Kryesimi i testimit
tcpdumpderi tani po punondig, ne zbulojmë që paketat UDP kthehen - Ne kryejmë testimin
strace dig google.comdhe shohim se dig thërret saktësendmsg()dherecvmsg(), megjithatë e dyta ndërpritet nga skadimi
Për fat të keq, përfundon ndërrimi dhe ne jemi të detyruar ta kalojmë problemin në zonën tjetër të kohës. Sidoqoftë, kontakti shkaktoi interes në ekipin tonë, dhe kolegu sugjeron të krijojmë paketën DNS origjinale me modulin python scrapy.
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())Ky kyç është krijimi i një paketi DNS dhe dërgimi i kërkesës tek serveri i metadata-ve.
Përdoruesi ekzekuton kodin, përgjigjja DNS kthehet, dhe aplikacioni e merr atë, duke konfirmuar se nuk ka probleme në nivelin e rrjetit.
Pas një 'rrethimi të botës' tjetër, kërkesa kthehet tek ekipi ynë, dhe unë e përgjithësoj plotësisht, duke menduar se do të ishte më e lehtë për përdoruesin nëse kërkesa nuk do të vazhdonte të qarkullonte.
Ndërkohë, përdoruesi pranon me mirësjellje të ofrojë një fotografi të imazhit të sistemit. Kjo është një lajm shumë i mirë: mundësia për të testuar sistemin vetë e përshpejton ndjeshëm zgjidhjen e problemeve, pasi nuk nevojitet më të kërkoj nga përdoruesi të ekzekutojë komanda, të më dërgojë rezultatet dhe t'i analizoj, unë mund ta bëj gjithçka vetë!
Kolegët fillojnë të më kenë pak zili. Gjatë drekës diskutojmë për incidentin, megjithatë askush nuk ka ide se çfarë po ndodh. Fatmirësisht, vetë përdoruesi ka marrë masa për të zbutur pasojat dhe nuk ka nxitim, kështu që kemi kohë për të analizuar problemin. Dhe që kemi një imazh, mund të realizojmë çdo test që na intereson. Kjo është shkëlqyer!
Kthehemi një hap mbrapa
Një nga pyetjet më të zakonshme në intervistat për pozitën e inxhinierit të sistemit është: "Çfarë ndodh kur ju pingoni ?» Вопрос шикарный, так как кандидату необходимо описать пусть от оболочки до пользовательского пространства, до ядра системы и далее к сети. Я улыбаюсь: иногда вопросы с интервью оказываются полезны и в реальной жизни…
Unë vendos të aplikoj këtë pyetje të HR-it në problemin aktual. Thjesht, kur përpiqeni të përcaktoni një emër DNS, ndodh e mëposhtme:
- Aplikacioni thërret bibliotekën sistemore, për shembull libdns
- libdns kontrollon konfigurimin e sistemit se në cilin server DNS duhet të drejtohet (në diagram është 169.254.169.254, serveri i metadonave)
- libdns përdor thirrje sistemore për të krijuar një soket UDP (SOKET_DGRAM) dhe për të dërguar paketa UDP me kërkesën DNS në të dy drejtimet
- Përmes ndërfaqes sysctl mund të konfigurohet staku UDP në nivelin e bërthamës
- Bërthama bashkëpunon me harduerin për të dërguar paketa në rrjet përmes ndërfaqes rrjet
- Hipervizori kap të kapë dhe të dërgojë paketën te serveri i metadatave kur ka kontakt me të
- Serveri i metadatave me magjinë e tij përcakton emrin DNS dhe në të njëjtën mënyrë kthen përgjigjen

Më kujtojnë se cilat hipoteza kemi shqyrtuar deri tani:
Hipoteza: Bibliotekat janë dëmtuar
- Testi 1: të kalojmë në sistemin strace, të kontrollojmë se çfarë thirrjesh të sakta sistemore bën dig
- Rezultati: thirrjet e sakta sistemore janë bërë
- Testi 2: përmes srapy të kontrollojmë nëse mund të përcaktojmë emrat përveç bibliotekave sistemore
- Rezultati: mund të përcaktojmë
- Testi 3: të kalojmë rpm –V në paketën libdns dhe md5sum të skedave të bibliotekës
- Rezultati: kodi i bibliotekës është plotësisht identik me kodin në sistemin e punës
- Testi 4: të montojmë imazhin e sistemit të rrënjës së përdoruesit në VM pa këtë sjellje, të kalojmë chroot, të shohim nëse funksionon DNS
- Rezultati: DNS funksionon siç duhet
Përfundimi nga testet: problemi nuk është te bibliotekat
Hipoteza: Ka një gabim në konfigurimin e DNS
- Testi 1: të shqyrtojmë tcpdump dhe të vëzhgojmë nëse paketat DNS dërgohen dhe kthehen siç duhet pas aktivizimit të dig
- Rezultati: paketat dërgohen siç duhet
- Testi 2: të rikonfirmojmë në server
/etc/nsswitch.confdhe/etc/resolv.conf - Rezultati: gjithçka është në rregull
Përfundimi nga testet: problemi nuk është në konfigurimin e DNS
Hipoteza: bërthama e dëmtuar
- Testi: instaloni një bërthamë të re, kontrolloni nënshkrimin, ri-nisni
- Rezultati: sjellje e ngjashme
Përfundimi nga testet: bërthama nuk është e dëmtuar
Hipoteza: sjellje e papërshtatshme e rrjetit të përdoruesit (ose ndërfaqes së rrjetit të hipervizorit)
- Testi 1: kontrolloni cilësimet e firewall-it
- Rezultati: firewall-i kalon paketat DNS në host dhe në GCP
- Testi 2: kapni trafikun dhe ndjekni saktësinë e transmetimit dhe kthimit të kërkesave DNS
- Rezultati: tcpdump konfirmon marrjen e paketave kthimi nga hosti
Përfundimi nga testet: problemi nuk është në rrjet
Hipoteza: serveri i metadatas nuk funksionon
- Testi 1: kontrolloni logjet e serverit të metadatas për anomalitë
- Rezultati: nuk ka anomalish në logje
- Testi 2: kaloni serverin e metadatas përmes
dig @8.8.8.8 - Rezultati: zgjidhja prishet edhe pa përdorur serverin e metadatas
Përfundimi nga testet: problemi nuk është në serverin e metadatas
Përfundimi: ne testuam të gjitha nën-sistemat përveç cilësimeve të mjedisit të ekzekutimit!
Duke u zhytur në cilësimet e mjedisit të ekzekutimit të bërthamës
Për të konfiguruar mjedisin e ekzekutimit të bërthamës mund të përdorni opsionet e komandave (grub) ose ndërfaqen sysctl. Kam hedhur një sy në /etc/sysctl.conf dhe të mendosh, zbulova disa cilësime të personalizuara. Ndjehesha sikur kisha kapur diçka, prandaj e hodha poshtë çdo cilësim që nuk ishte rrjetësor ose jo-tcp, duke mbetur me një grumbull cilësimesh net.core. Pastaj shkova atje ku VM ka lejet e mikpritësit dhe fillova të aplikoj një pas një cilësimet nga VM-ja e prishur, deri sa arrita te fajtorja:
net.core.rmem_default = 2147483647Ja, ky është konfigurimi që prish DNS-in! Gjeta armën e krimit. Por pse ndodh kjo? Më duhej ende një motiv.
Cilësimi i madhësisë bazë të njësive DNS bëhet nëpërmjet net.core.rmem_default. Vlera tipike shkon diku rreth 200KiB, por nëse serveri juaj merr shumë njësitë DNS, mund të rritni madhësinë e njësisë. Nëse në momentin e marrjes së një njësie të re, e gjithë njësia është e mbushur, për shembull, sepse aplikacioni nuk e proceson mjaft shpjet, atëherë do të filloni të humbni paketa. Klienti ynë e rriti saktësisht madhësinë e njësisë sepse kishte frikë se do të humbiste të dhëna, pasi përdorte një aplikacion për mbledhjen e metrikave përmes njësive DNS. Vlera që ai vendosi ishte maksimumi i mundshëm: 231-1 (nëse vendosni 231, bërthama do të kthejë "ARGUMENT I PABESUESHËM").
Papritëm papritur se pse nmap dhe scapy funksiononin siç duhej: ato përdornin soket të gjallë! Soket të gjallë janë ndryshe nga ata normalë: ata punojnë përtej iptables dhe nuk buferohen!
Por pse ‘buferi shumë i madh’ shkakton probleme? Ai duket se nuk funksionon siç duhej.
Në këtë pikë, unë mund të riprodhoja problemin në disa bërthama dhe shumë distribucione. Problemi kishte shfaqur tashmë në bërthamën 3.x dhe tani shfaqej gjithashtu në bërthamën 5.x.
Në të vërtetë, kur ekzekutova
sysctl -w net.core.rmem_default=$((2**31-1))DNS ndaloi së funksionuari.
Nisa të kërkoja vlera funksionale përmes një algoritmi të thjeshtë të kërkimit binar dhe zbulova se me 2147481343 sistemi funksiononte, megjithatë ky numër ishte për mua një grup numrash pa kuptim. I propozuam klientit ta provonte këtë numër dhe ai u përgjigj se sistemi pati sukses me google.com, por ende jepte gabim me domain të tjerë, prandaj vazhdova hetimin tim.
Instalova , një mjet që do e doja të kisha përdorur më parë: ai tregon se ku saktësisht në bërthamë arrin paketi. Faji doli të ishte funksioni udp_queue_rcv_skb. E shkarkova kodin burimor të bërthamës dhe shtova disa për të ndjekur se ku përfundon konkretisht paketa. I kisha zbuluar shpejt kushtin e duhur nëse, dhe për një kohë të shkurtër thjesht e shikoja atë, sepse pikërisht atëherë gjithçka përfundimisht u bashkua në një tabllo të plotë: 231-1, një numër pa kuptim, një domen që nuk funksionon… Problemi ishte në një pjesë kodi në __udp_enqueue_schedule_skb:
nëse (rmem > (size + sk->sk_rcvbuf))
shko te uncharge_drop;Vini re:
rmemka tip intsizeka tip u16 (një int i gjashtëmbëdhjetë bitësh të pandashëm) dhe ruan madhësinë e paketëssk->sk_rcybufka tip int dhe ruan madhësinë e bufere që sipas definicionit është e barabartë me vlerën nënet.core.rmem_default
Kur sk_rcvbuf duke iu afruar 231, përllogaritja e madhësisë së paketës mund të çojë në . Dhe meqenëse është int, vlera e tij bëhet negative, kështu që kushti bëhet i vërtetë kur duhet të jetë i gabuar (mund të mësoni më shumë për këtë në ).
Gabimi korrigjohet në mënyrë triviale: përmes konvertimit në unsigned int. E aplikoha korrigjimin dhe ripërtheva sistemin, pas së cilës DNS rifilloi të funksionojë.
Shija e fitores
I dërgova gjetjet e mia klientit dhe dërgova patch kernel. Jam i kënaqur: çdo copë nga enigmat përputhet në një tërësi, mund të shpjegoj saktësisht pse panë atë që panë, dhe ajo që është më e rëndësishmja, arritëm të gjenim zgjidhjen për problemin falë punës së bashku!
Duhet pranuar se rasti ishte i rrallë dhe, fatmirësisht, nuk kemi marrë shpesh kërkesa të tilla kaq komplekse nga përdoruesit.
Burimi: habr.com
