Debugging lìonra latency ann an Kubernetes

Debugging lìonra latency ann an Kubernetes

O chionn beagan bhliadhnaichean Kubernetes air a dheasbad mu thràth air blog oifigeil GitHub. Bhon uairsin, tha e air a thighinn gu bhith na theicneòlas àbhaisteach airson a bhith a’ cleachdadh sheirbheisean. Tha Kubernetes a-nis a’ riaghladh cuid mhath de sheirbheisean a-staigh agus poblach. Mar a dh’ fhàs na cruinneachaidhean againn agus riatanasan coileanaidh a’ fàs nas cruaidhe, thòisich sinn a’ mothachadh gu robh cuid de sheirbheisean air Kubernetes bho àm gu àm a’ fulang latency nach b’ urrainnear a mhìneachadh le eallach an tagraidh fhèin.

Gu bunaiteach, bidh tagraidhean a ’faighinn eòlas air latency lìonra air thuaiream suas ri 100ms no barrachd, a’ leantainn gu amannan ùine no ath-chuingean. Bhathar an dùil gum biodh e comasach do sheirbheisean freagairt a thoirt do iarrtasan fada nas luaithe na 100ms. Ach tha seo do-dhèanta ma bheir an ceangal fhèin uimhir de ùine. Air leth, chunnaic sinn ceistean MySQL gu math luath a bu chòir milliseconds a ghabhail, agus chrìochnaich MySQL ann am milliseconds, ach bho shealladh an tagraidh a bha ag iarraidh, ghabh am freagairt 100 ms no barrachd.

Dh'fhàs e soilleir sa bhad nach do thachair an duilgheadas ach nuair a cheangladh tu ri nód Kubernetes, eadhon ged a thàinig an gairm bho thaobh a-muigh Kubernetes. Tha an dòigh as fhasa air an duilgheadas ath-chruthachadh ann an deuchainn Vegeta, a bhios a’ ruith bho neach-aoigheachd sam bith a-staigh, a’ dèanamh deuchainn air seirbheis Kubernetes air port sònraichte, agus a’ clàradh latency àrd bho àm gu àm. San artaigil seo, seallaidh sinn mar a b’ urrainn dhuinn adhbhar na trioblaid seo a lorg.

A 'cur às do iom-fhillteachd neo-riatanach san t-seine a' leantainn gu fàilligeadh

Le bhith ag ath-riochdachadh an aon eisimpleir, bha sinn airson fòcas na trioblaid a chaolachadh agus sreathan iom-fhillteachd neo-riatanach a thoirt air falbh. An toiseach, bha cus eileamaidean anns an t-sruth eadar Vegeta agus na pods Kubernetes. Gus duilgheadas lìonra nas doimhne a chomharrachadh, feumaidh tu cuid dhiubh a chuir às.

Debugging lìonra latency ann an Kubernetes

Bidh an neach-dèiligidh (Vegeta) a’ cruthachadh ceangal TCP le nód sam bith sa bhuidheann. Tha Kubernetes ag obair mar lìonra ath-chòmhdach (a bharrachd air an lìonra ionad dàta a th’ ann mar-thà) a bhios a’ cleachdadh IPIP, is e sin, bidh e a’ toirt a-steach pacaidean IP an lìonra ath-chòmhdach taobh a-staigh pacaidean IP an ionaid dàta. Nuair a cheanglas tu ris a’ chiad nód, thèid eadar-theangachadh seòladh lìonra a dhèanamh Eadar-theangachadh seòladh lìonra (NAT) stàiteil an seòladh IP agus port nód Kubernetes eadar-theangachadh gu seòladh IP agus port anns an lìonra ath-chòmhdach (gu sònraichte, am pod leis an tagradh). Airson pacaidean a tha a 'tighinn a-steach, thèid an sreath de ghnìomhan a dhèanamh. Is e siostam iom-fhillte a th 'ann le mòran stàite agus mòran eileamaidean a tha daonnan air an ùrachadh agus air an atharrachadh mar a tha seirbheisean air an cleachdadh agus air an gluasad.

Goireasach tcpdump ann an deuchainn Vegeta tha dàil ann rè crathadh làimhe TCP (eadar SYN agus SYN-ACK). Gus an iom-fhillteachd neo-riatanach seo a thoirt air falbh, faodaidh tu a chleachdadh hping3 airson “pings” sìmplidh le pacaidean SYN. Nì sinn sgrùdadh a bheil dàil anns a’ phacaid freagairt, agus an uairsin ath-shuidhich sinn an ceangal. Is urrainn dhuinn an dàta a shìoladh gus dìreach pacaidean nas motha na 100 ms a ghabhail a-steach agus dòigh nas fhasa fhaighinn air an duilgheadas ath-riochdachadh na deuchainn lìonra lìonra iomlan 7 Vegeta. Seo “pings” nód Kubernetes a’ cleachdadh TCP SYN/SYN-ACK air an t-seirbheis “node port” (30927) aig amannan 10ms, air a shìoladh leis na freagairtean as slaodaiche:

theojulienne@shell ~ $ sudo hping3 172.16.47.27 -S -p 30927 -i u10000 | egrep --line-buffered 'rtt=[0-9]{3}.'

len=46 ip=172.16.47.27 ttl=59 DF id=0 sport=30927 flags=SA seq=1485 win=29200 rtt=127.1 ms

len=46 ip=172.16.47.27 ttl=59 DF id=0 sport=30927 flags=SA seq=1486 win=29200 rtt=117.0 ms

len=46 ip=172.16.47.27 ttl=59 DF id=0 sport=30927 flags=SA seq=1487 win=29200 rtt=106.2 ms

len=46 ip=172.16.47.27 ttl=59 DF id=0 sport=30927 flags=SA seq=1488 win=29200 rtt=104.1 ms

len=46 ip=172.16.47.27 ttl=59 DF id=0 sport=30927 flags=SA seq=5024 win=29200 rtt=109.2 ms

len=46 ip=172.16.47.27 ttl=59 DF id=0 sport=30927 flags=SA seq=5231 win=29200 rtt=109.2 ms

Is urrainn dha a’ chiad amharc a dhèanamh sa bhad. A’ breithneachadh leis an t-sreath àireamhan agus amannan, tha e soilleir nach e dùmhlachdan aon-ùine a tha seo. Bidh an dàil gu tric a’ cruinneachadh agus mu dheireadh ga ghiullachd.

An ath rud, tha sinn airson faighinn a-mach dè na pàirtean a dh’ fhaodadh a bhith an sàs ann an dùmhlachd dùmhlachd. Is dòcha gur e seo cuid de na ceudan de riaghailtean iptables ann an NAT? No a bheil duilgheadasan sam bith ann le tunail IPIP air an lìonra? Is e aon dòigh air seo a dhearbhadh deuchainn a dhèanamh air gach ceum den t-siostam le bhith ga chuir às. Dè thachras ma bheir thu air falbh NAT agus loidsig balla-teine, a’ fàgail dìreach am pàirt IPIP:

Debugging lìonra latency ann an Kubernetes

Gu fortanach, tha Linux ga dhèanamh furasta faighinn gu ìre ath-chòmhdach IP gu dìreach ma tha an inneal air an aon lìonra:

theojulienne@kube-node-client ~ $ sudo hping3 10.125.20.64 -S -i u10000 | egrep --line-buffered 'rtt=[0-9]{3}.'

len=40 ip=10.125.20.64 ttl=64 DF id=0 sport=0 flags=RA seq=7346 win=0 rtt=127.3 ms

len=40 ip=10.125.20.64 ttl=64 DF id=0 sport=0 flags=RA seq=7347 win=0 rtt=117.3 ms

len=40 ip=10.125.20.64 ttl=64 DF id=0 sport=0 flags=RA seq=7348 win=0 rtt=107.2 ms

A rèir nan toraidhean, tha an duilgheadas fhathast ann! Chan eil seo a’ gabhail a-steach iptables agus NAT. Mar sin is e TCP an duilgheadas? Chì sinn mar a thèid ping ICMP cunbhalach:

theojulienne@kube-node-client ~ $ sudo hping3 10.125.20.64 --icmp -i u10000 | egrep --line-buffered 'rtt=[0-9]{3}.'

len=28 ip=10.125.20.64 ttl=64 id=42594 icmp_seq=104 rtt=110.0 ms

len=28 ip=10.125.20.64 ttl=64 id=49448 icmp_seq=4022 rtt=141.3 ms

len=28 ip=10.125.20.64 ttl=64 id=49449 icmp_seq=4023 rtt=131.3 ms

len=28 ip=10.125.20.64 ttl=64 id=49450 icmp_seq=4024 rtt=121.2 ms

len=28 ip=10.125.20.64 ttl=64 id=49451 icmp_seq=4025 rtt=111.2 ms

len=28 ip=10.125.20.64 ttl=64 id=49452 icmp_seq=4026 rtt=101.1 ms

len=28 ip=10.125.20.64 ttl=64 id=50023 icmp_seq=4343 rtt=126.8 ms

len=28 ip=10.125.20.64 ttl=64 id=50024 icmp_seq=4344 rtt=116.8 ms

len=28 ip=10.125.20.64 ttl=64 id=50025 icmp_seq=4345 rtt=106.8 ms

len=28 ip=10.125.20.64 ttl=64 id=59727 icmp_seq=9836 rtt=106.1 ms

Tha na toraidhean a 'sealltainn nach eil an duilgheadas air falbh. Is dòcha gur e tunail IPIP a tha seo? Leig leinn an deuchainn a dhèanamh nas sìmplidhe:

Debugging lìonra latency ann an Kubernetes

Am bheil na pacaidean uile air an cur eadar an dà òstair seo?

theojulienne@kube-node-client ~ $ sudo hping3 172.16.47.27 --icmp -i u10000 | egrep --line-buffered 'rtt=[0-9]{3}.'

len=46 ip=172.16.47.27 ttl=61 id=41127 icmp_seq=12564 rtt=140.9 ms

len=46 ip=172.16.47.27 ttl=61 id=41128 icmp_seq=12565 rtt=130.9 ms

len=46 ip=172.16.47.27 ttl=61 id=41129 icmp_seq=12566 rtt=120.8 ms

len=46 ip=172.16.47.27 ttl=61 id=41130 icmp_seq=12567 rtt=110.8 ms

len=46 ip=172.16.47.27 ttl=61 id=41131 icmp_seq=12568 rtt=100.7 ms

len=46 ip=172.16.47.27 ttl=61 id=9062 icmp_seq=31443 rtt=134.2 ms

len=46 ip=172.16.47.27 ttl=61 id=9063 icmp_seq=31444 rtt=124.2 ms

len=46 ip=172.16.47.27 ttl=61 id=9064 icmp_seq=31445 rtt=114.2 ms

len=46 ip=172.16.47.27 ttl=61 id=9065 icmp_seq=31446 rtt=104.2 ms

Tha sinn air an suidheachadh a dhèanamh nas sìmplidhe gu dà nod Kubernetes a’ cur pacaid sam bith gu chèile, eadhon ping ICMP. Bidh iad fhathast a 'faicinn latency ma tha an neach-aoigheachd "dona" (cuid nas miosa na feadhainn eile).

A-nis a’ cheist mu dheireadh: carson nach tachair an dàil ach air frithealaichean kube-node? Agus a bheil e a’ tachairt nuair is e kube-node an neach a chuir no an neach-glacaidh? Gu fortanach, tha seo cuideachd gu math furasta obrachadh a-mach le bhith a’ cur pacaid bho òstair taobh a-muigh Kubernetes, ach leis an aon neach-faighinn “droch aithnichte”. Mar a chì thu, chan eil an duilgheadas air a dhol à bith:

theojulienne@shell ~ $ sudo hping3 172.16.47.27 -p 9876 -S -i u10000 | egrep --line-buffered 'rtt=[0-9]{3}.'

len=46 ip=172.16.47.27 ttl=61 DF id=0 sport=9876 flags=RA seq=312 win=0 rtt=108.5 ms

len=46 ip=172.16.47.27 ttl=61 DF id=0 sport=9876 flags=RA seq=5903 win=0 rtt=119.4 ms

len=46 ip=172.16.47.27 ttl=61 DF id=0 sport=9876 flags=RA seq=6227 win=0 rtt=139.9 ms

len=46 ip=172.16.47.27 ttl=61 DF id=0 sport=9876 flags=RA seq=7929 win=0 rtt=131.2 ms

Bidh sinn an uairsin a’ ruith na h-aon iarrtasan bhon stòr kube-node roimhe chun aoigh a-muigh (a tha a’ dùnadh a-mach an òstair stòr leis gu bheil am ping a’ toirt a-steach an dà chuid pàirt RX agus TX):

theojulienne@kube-node-client ~ $ sudo hping3 172.16.33.44 -p 9876 -S -i u10000 | egrep --line-buffered 'rtt=[0-9]{3}.'
^C
--- 172.16.33.44 hping statistic ---
22352 packets transmitted, 22350 packets received, 1% packet loss
round-trip min/avg/max = 0.2/7.6/1010.6 ms

Le bhith a’ sgrùdadh glacaidhean pacaid latency, fhuair sinn beagan fiosrachaidh a bharrachd. Gu sònraichte, gum faic an neach a chuir (gu h-ìosal) an ùine seo a-mach, ach chan eil an neach a gheibh (gu h-àrd) - faic colbh Delta (ann an diogan):

Debugging lìonra latency ann an Kubernetes

A bharrachd air an sin, ma choimheadas tu air an eadar-dhealachadh ann an òrdugh pacaidean TCP agus ICMP (a rèir àireamhan sreath) air taobh an neach a gheibh iad, bidh pacaidean ICMP an-còmhnaidh a’ ruighinn san aon sreath anns an deach an cur, ach le ùine eadar-dhealaichte. Aig an aon àm, bidh pacaidean TCP uaireannan ag eadar-fhighe, agus bidh cuid dhiubh a 'dol an sàs. Gu sònraichte, ma nì thu sgrùdadh air puirt pacaidean SYN, tha iad ann an òrdugh air taobh an neach a chuir, ach chan ann air taobh an neach-glacaidh.

Tha eadar-dhealachadh beag ann air ciamar cairtean lìonraidh bidh frithealaichean ùr-nodha (mar an fheadhainn san ionad dàta againn) a’ pròiseasadh phasganan anns a bheil TCP no ICMP. Nuair a ruigeas pacaid, bidh an inneal-atharrachaidh lìonra “ga hashes gach ceangal”, is e sin, bidh e a’ feuchainn ris na ceanglaichean a bhriseadh ann an ciudha agus a’ cur gach ciudha gu cridhe pròiseasar air leth. Airson TCP, tha an hash seo a’ toirt a-steach an dà chuid an stòr agus an ceann-uidhe seòladh IP agus port. Ann am faclan eile, tha gach ceangal air a ghluasad (a dh'fhaodadh a bhith) ann an dòigh eadar-dhealaichte. Airson ICMP, chan eil ach seòlaidhean IP air an toirt air falbh, leis nach eil puirt ann.

Beachdachadh ùr eile: rè na h-ùine seo chì sinn dàil ICMP air a h-uile conaltradh eadar dà aoigh, ach chan eil TCP. Tha seo ag innse dhuinn gu bheil coltas ann gu bheil an adhbhar co-cheangailte ri hashing ciudha RX: tha an dùmhlachd cha mhòr gu cinnteach ann a bhith a’ giullachd phasganan RX, chan ann ann a bhith a’ cur fhreagairtean.

Bidh seo a’ cur às do bhith a’ cur phasganan bhon liosta de dh’ adhbharan a dh’fhaodadh a bhith ann. Tha fios againn a-nis gu bheil an duilgheadas giollachd pacaid air an taobh faighinn air cuid de na frithealaichean kube-node.

A’ tuigsinn giullachd pacaid anns an kernel Linux

Gus tuigsinn carson a tha an duilgheadas a ’tachairt aig a’ ghlacadair air cuid de na frithealaichean kube-node, leig dhuinn sùil a thoirt air mar a bhios an kernel Linux a ’pròiseas pacaidean.

A 'tilleadh chun a' bhuileachadh traidiseanta as sìmplidh, bidh a 'chairt lìonra a' faighinn a 'phacaid agus a' cur brisidh an kernel Linux gu bheil pasgan ann a dh’ fheumar a phròiseasadh. Bidh an kernel a’ stad obair eile, ag atharrachadh co-theacsa chun inneal-làimhseachaidh brisidh, a’ pròiseasadh a’ phacaid, agus an uairsin a’ tilleadh gu na gnìomhan gnàthach.

Debugging lìonra latency ann an Kubernetes

Tha an t-atharrachadh co-theacsa seo slaodach: is dòcha nach robh latency ri fhaicinn air cairtean lìonra 10Mbps anns na 90an, ach air cairtean 10G an latha an-diugh le gluasad as àirde de 15 millean pacaid san diog, faodar stad a chuir air gach cridhe de fhrithealaiche beag ochd-cridhe milleanan uair san diog.

Gus nach bi thu an-còmhnaidh a’ làimhseachadh brisidhean, o chionn iomadh bliadhna chuir Linux ris NAPI: Lìonra API a bhios a h-uile draibhear ùr-nodha a’ cleachdadh gus coileanadh a leasachadh aig astaran àrda. Aig astaran ìosal bidh an kernel fhathast a’ faighinn brisidhean bhon chairt lìonra san t-seann dòigh. Cho luath ‘s a ruigeas pacaidean gu leòr a tha nas àirde na an stairsnich, bidh an kernel a’ cuir às do bhriseadh agus an àite sin a ’tòiseachadh a’ bhòtadh an inneal-atharrachaidh lìonra agus a ’togail phasganan ann am pìosan. Tha giullachd air a dhèanamh ann an softirq, is e sin, ann an co-theacsa brisidhean bathar-bog às deidh fiosan siostam agus brisidhean bathar-cruaidh, nuair a tha an kernel (seach àite luchd-cleachdaidh) a’ ruith mu thràth.

Debugging lìonra latency ann an Kubernetes

Tha seo tòrr nas luaithe, ach tha e ag adhbhrachadh duilgheadas eile. Ma tha cus phasgan ann, thèid an ùine gu lèir a chaitheamh a ’giullachd phasganan bhon chairt lìonra, agus chan eil ùine aig pròiseasan àite luchd-cleachdaidh na ciudhaichean sin fhalamhachadh (leugh bho cheanglaichean TCP, msaa). Mu dheireadh bidh na ciudhaichean a’ lìonadh agus tòisichidh sinn a’ leigeil phasganan sìos. Ann an oidhirp cothromachadh a lorg, bidh an kernel a’ suidheachadh buidseit airson an àireamh as motha de phasganan air an giullachd ann an co-theacsa softirq. Aon uair 's gu bheilear a' dol thairis air a' bhuidseit seo, thèid snàithlean fa leth a dhùsgadh ksoftirqd (chì thu fear dhiubh a stigh ps gach cridhe) a làimhsicheas na softirqs sin taobh a-muigh an t-slighe àbhaisteach syscall / brisidh. Tha an t-snàthainn seo clàraichte a’ cleachdadh clàr-ama pròiseas àbhaisteach, a bhios a’ feuchainn ri goireasan a riarachadh gu cothromach.

Debugging lìonra latency ann an Kubernetes

An dèidh sgrùdadh a dhèanamh air mar a bhios an kernel a 'pròiseas pacaidean, chì thu gu bheil coltas ann gum bi dùmhlachd ann. Mura faighear fiosan softirq cho tric, feumaidh pacaidean feitheamh beagan ùine gus an tèid an giullachd anns a’ chiudha RX air a’ chairt lìonraidh. Is dòcha gu bheil seo mar thoradh air cuid de dh ’obair a’ bacadh cridhe a ’phròiseasar, no gu bheil rudeigin eile a’ cur casg air a ’chridhe bho bhith a’ ruith softirq.

A 'lùghdachadh a' ghiollachd sìos chun a 'chridhe no an dòigh

Chan eil ann an dàil Softirq ach tomhas airson a-nis. Ach tha e a’ dèanamh ciall, agus tha fios againn gu bheil sinn a’ faicinn rudeigin glè choltach. Mar sin is e an ath cheum an teòiridh seo a dhearbhadh. Agus ma thèid a dhearbhadh, an uairsin lorg adhbhar an dàil.

Tillidh sinn chun na pacaidean slaodach againn:

len=46 ip=172.16.53.32 ttl=61 id=29573 icmp_seq=1953 rtt=99.3 ms

len=46 ip=172.16.53.32 ttl=61 id=29574 icmp_seq=1954 rtt=89.3 ms

len=46 ip=172.16.53.32 ttl=61 id=29575 icmp_seq=1955 rtt=79.2 ms

len=46 ip=172.16.53.32 ttl=61 id=29576 icmp_seq=1956 rtt=69.1 ms

len=46 ip=172.16.53.32 ttl=61 id=29577 icmp_seq=1957 rtt=59.1 ms

len=46 ip=172.16.53.32 ttl=61 id=29790 icmp_seq=2070 rtt=75.7 ms

len=46 ip=172.16.53.32 ttl=61 id=29791 icmp_seq=2071 rtt=65.6 ms

len=46 ip=172.16.53.32 ttl=61 id=29792 icmp_seq=2072 rtt=55.5 ms

Mar a chaidh a dheasbad na bu thràithe, tha na pacaidean ICMP seo air an toirt a-steach do aon ciudha RX NIC agus air an giullachd le aon chridhe CPU. Ma tha sinn airson tuigsinn mar a tha Linux ag obair, tha e feumail fios a bhith againn càite (air dè an cridhe CPU) agus ciamar (softirq, ksoftirqd) a tha na pacaidean sin air an giullachd gus am pròiseas a leantainn.

A-nis tha an t-àm ann innealan a chleachdadh a leigeas leat sùil a chumail air kernel Linux ann an àm fìor. An seo chleachd sinn Dld. Leigidh an seata innealan seo leat prògraman beaga C a sgrìobhadh a bhios a’ ceangal gnìomhan neo-riaghailteach anns an kernel agus a’ bufair na tachartasan a-steach do phrògram Python àite-cleachdaidh as urrainn an làimhseachadh agus an toradh a thilleadh thugad. Tha dubhan airson gnìomhan neo-riaghailteach anns an kernel na chùis iom-fhillte, ach tha an goireas air a dhealbhadh airson an tèarainteachd as motha agus tha e air a dhealbhadh gus lorg dìreach an seòrsa de chùisean cinneasachaidh nach eil furasta an ath-riochdachadh ann an àrainneachd deuchainn no leasachaidh.

Tha am plana an seo sìmplidh: tha fios againn gu bheil an kernel a ’pròiseasadh na buillean ICMP sin, agus mar sin cuiridh sinn dubhan air gnìomh kernel icmp_echo, a ghabhas ri pasgan iarrtas mac-talla ICMP a tha a’ tighinn a-steach agus a thòisicheas a’ cur freagairt mac-talla ICMP. Is urrainn dhuinn pasgan aithneachadh le bhith ag àrdachadh an àireamh icmp_seq, a sheallas hping3 nas àirde.

còd a ' sgriobt bcc a 'coimhead iom-fhillte, ach chan eil e cho eagallach' sa tha e coltach. Gnìomh icmp_echo a' giùlan struct sk_buff *skb: Seo pasgan le "iarrtas mac-talla". Is urrainn dhuinn a lorg, tarraing a-mach an t-sreath echo.sequence (a tha an coimeas ri icmp_seq le hping3 выше), agus cuir gu àite luchd-cleachdaidh e. Tha e cuideachd goireasach ainm / id pròiseas gnàthach a ghlacadh. Gu h-ìosal tha na toraidhean a chì sinn gu dìreach fhad ‘s a bhios na pacaidean pròiseas kernel:

AINM PRÒISEAS PID TGID ICMP_SEQ 0 0 suaipear/11 770 0 0 suaipear/11 771 0 0 suapper/11 772 0 0 swapper/11 773 0 0 swapper/11 774 20041 20086 775 pro swapper/0 0 11 776 neach-iomlaid/0 0 11 777 0 suapper/0 11 778 4512 neach-labhairt-aithisg-s 4542

Bu chòir a thoirt fa-near an seo gur ann an co-theacsa softirq nochdaidh pròiseasan a rinn fiosan siostam mar “phròiseasan” nuair a bhios e dha-rìribh an kernel a bhios a’ pròiseasadh phasganan gu sàbhailte ann an co-theacs an kernel.

Leis an inneal seo is urrainn dhuinn pròiseasan sònraichte a cheangal ri pasganan sònraichte a tha a’ nochdadh dàil de hping3. Dèanamaid sìmplidh e grep air an glacadh seo airson luachan sònraichte icmp_seq. Chaidh pacaidean a bha co-chosmhail ris na luachan icmp_seq gu h-àrd a thoirt fa-near còmhla ris an RTT a chunnaic sinn gu h-àrd (ann am brathan tha na luachan RTT ris a bheil dùil airson pacaidean a chuir sinn a-mach air sgàth luachan RTT nas lugha na 50 ms):

AINM PRÒISEAS PID TGID ICMP_SEQ ** RTT -- 10137 10436 cadvisor 1951 10137 10436 cadvisor 1952 76 76 ksoftirqd/11 1953 ** 99ms 76 76 ksoftirqd/11 1954 ksoftirqd/89 76 ksoftirqd/76 11 ksoftirqd/1955 79ksoft 76 ** 76ms 11 1956 ksoftirqd/ 69 76 ** 76ms 11 1957 ksoftirqd/59 76 ** 76ms 11 1958 ksoftirqd/49 76 ** (76ms) 11 1959 ksoftirqd/39 76 ** (76ms) 11 1960 ksoftirqd/29 76 ** (76ms) 11 1961 ksoft irqd/ 19 76 ** (76ms) 11 1962 ksoftirqd/9 10137 ** (10436ms) -- 2068 10137 cadvisor 10436 2069 76 cadvisor 76 11 2070 ksoftirqd/75 76 ksoftirqd/76 11 ksoftirqd/2071 65ksoft 76 ** 76ms 11 2072 ksoftirqd/ 55 76 ** 76ms 11 2073 ksoftirqd/45 76 ** (76ms) 11 2074 ksoftirqd/35 76 ** (76ms) 11 2075 ksoftirqd/25 76 ** (76ms) 11 2076 ksoftirqd/15 76 ** (76ms) 11 2077 ksoftirqd/5 XNUMX ** (XNUMXms) XNUMX XNUMXm bog ) XNUMX XNUMX ksoftirqd/XNUMX XNUMX ** (XNUMXms)

Tha na toraidhean ag innse grunn rudan dhuinn. An toiseach, tha na pacaidean sin uile air an giullachd leis a’ cho-theacsa ksoftirqd/11. Tha seo a’ ciallachadh, airson a’ phaidhir inneal sònraichte seo, gun deach pacaidean ICMP a ghluasad gu cridhe 11 aig an deireadh faighinn. Chì sinn cuideachd, nuair a bhios silidh ann, gu bheil pacaidean ann a tha air an giullachd ann an co-theacsa gairm an t-siostaim cadvisor. An uairsin ksoftirqd a’ gabhail thairis a’ ghnìomh agus a’ pròiseasadh a’ chiudha cruinnichte: dìreach an àireamh de phasganan a chruinnich às a dhèidh cadvisor.

Tha an fhìrinn gu bheil dìreach mus tha e an-còmhnaidh ag obair cadvisor, a 'ciallachadh gu bheil e an sàs anns an duilgheadas. Gu h-ìoranta, an adhbhar comhairliche - "Dèan sgrùdadh air cleachdadh ghoireasan agus feartan coileanaidh soithichean ruith" seach a bhith ag adhbhrachadh a’ chùis coileanaidh seo.

Coltach ri taobhan eile de shoithichean, tha iad sin uile nan innealan fìor adhartach agus faodar a bhith an dùil gum faigh iad eòlas air cùisean coileanaidh ann an cuid de shuidheachaidhean ris nach robh dùil.

Dè bhios cadvisor a’ dèanamh a chuireas maill air ciudha a’ phacaid?

Tha tuigse mhath againn a-nis air mar a tha an tubaist a’ tachairt, dè am pròiseas a tha ga adhbharachadh, agus air dè an CPU. Chì sinn mar thoradh air bacadh cruaidh, nach eil ùine aig an kernel Linux clàr-ama ksoftirqd. Agus chì sinn gu bheil pacaidean air an giullachd ann an co-theacsa cadvisor. Tha e loidsigeach a bhith den bheachd sin cadvisor a’ cur air bhog syscall slaodach, às deidh sin bidh a h-uile pacaid a chruinnichear aig an àm sin air an giullachd:

Debugging lìonra latency ann an Kubernetes

Is e teòiridh a tha seo, ach ciamar a nì thu deuchainn air? Is urrainn dhuinn a dhèanamh ach lorg cridhe an CPU tron ​​​​phròiseas seo, lorg a’ phuing far a bheil an àireamh de phasganan a’ dol thairis air a’ bhuidseit agus ksoftirqd ris an canar, agus an uairsin coimhead beagan nas fhaide air ais gus faicinn dè dìreach a bha a’ ruith air cridhe an CPU dìreach ron àm sin. . Tha e coltach ri x-raying an CPU a h-uile beagan milliseconds. Seallaidh e rudeigin mar seo:

Debugging lìonra latency ann an Kubernetes

Gu h-iomchaidh, faodar seo uile a dhèanamh leis na h-innealan a th ’ann. Mar eisimpleir, clàr perf a’ sgrùdadh cridhe CPU sònraichte aig tricead ainmichte agus is urrainn dha clàr de ghairmean a ghineadh chun t-siostam ruith, a’ toirt a-steach an dà chuid àite luchd-cleachdaidh agus an kernel Linux. Faodaidh tu an clàr seo a ghabhail agus a phròiseasadh le bhith a’ cleachdadh forc beag den phrògram FlameGraph bho Bhreandan Gregg, a ghlèidheas òrdugh lorg na stac. Is urrainn dhuinn lorgan stac aon-loidhne a shàbhaladh gach 1 ms, agus an uairsin sampall 100 milliseconds a chomharrachadh agus a shàbhaladh mus buail an lorg ksoftirqd:

# record 999 times a second, or every 1ms with some offset so not to align exactly with timers
sudo perf record -C 11 -g -F 999
# take that recording and make a simpler stack trace.
sudo perf script 2>/dev/null | ./FlameGraph/stackcollapse-perf-ordered.pl | grep ksoftir -B 100

Seo na toraidhean:

(сотни следов, которые выглядят похожими)

cadvisor;[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];entry_SYSCALL_64_after_swapgs;do_syscall_64;sys_read;vfs_read;seq_read;memcg_stat_show;mem_cgroup_nr_lru_pages;mem_cgroup_node_nr_lru_pages cadvisor;[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];entry_SYSCALL_64_after_swapgs;do_syscall_64;sys_read;vfs_read;seq_read;memcg_stat_show;mem_cgroup_nr_lru_pages;mem_cgroup_node_nr_lru_pages cadvisor;[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];entry_SYSCALL_64_after_swapgs;do_syscall_64;sys_read;vfs_read;seq_read;memcg_stat_show;mem_cgroup_iter cadvisor;[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];entry_SYSCALL_64_after_swapgs;do_syscall_64;sys_read;vfs_read;seq_read;memcg_stat_show;mem_cgroup_nr_lru_pages;mem_cgroup_node_nr_lru_pages cadvisor;[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];[cadvisor];entry_SYSCALL_64_after_swapgs;do_syscall_64;sys_read;vfs_read;seq_read;memcg_stat_show;mem_cgroup_nr_lru_pages;mem_cgroup_node_nr_lru_pages ksoftirqd/11;ret_from_fork;kthread;kthread;smpboot_thread_fn;smpboot_thread_fn;run_ksoftirqd;__do_softirq;net_rx_action;ixgbe_poll;ixgbe_clean_rx_irq;napi_gro_receive;netif_receive_skb_internal;inet_gro_receive;bond_handle_frame;__netif_receive_skb_core;ip_rcv_finish;ip_rcv;ip_forward_finish;ip_forward;ip_finish_output;nf_iterate;ip_output;ip_finish_output2;__dev_queue_xmit;dev_hard_start_xmit;ipip_tunnel_xmit;ip_tunnel_xmit;iptunnel_xmit;ip_local_out;dst_output;__ip_local_out;nf_hook_slow;nf_iterate;nf_conntrack_in;generic_packet;ipt_do_table;set_match_v4;ip_set_test;hash_net4_kadt;ixgbe_xmit_frame_ring;swiotlb_dma_mapping_error;hash_net4_test ksoftirqd/11;ret_from_fork;kthread;kthread;smpboot_thread_fn;smpboot_thread_fn;run_ksoftirqd;__do_softirq;net_rx_action;gro_cell_poll;napi_gro_receive;netif_receive_skb_internal;inet_gro_receive;__netif_receive_skb_core;ip_rcv_finish;ip_rcv;ip_forward_finish;ip_forward;ip_finish_output;nf_iterate;ip_output;ip_finish_output2;__dev_queue_xmit;dev_hard_start_xmit;dev_queue_xmit_nit;packet_rcv;tpacket_rcv;sch_direct_xmit;validate_xmit_skb_list;validate_xmit_skb;netif_skb_features;ixgbe_xmit_frame_ring;swiotlb_dma_mapping_error;__dev_queue_xmit;dev_hard_start_xmit;__bpf_prog_run;__bpf_prog_run

Tha tòrr rudan an seo, ach is e am prìomh rud gu bheil sinn a’ lorg am pàtran “cadvisor before ksoftirqd” a chunnaic sinn na bu thràithe san ICMP tracer. Dè a tha e a’ ciallachadh?

Tha gach loidhne na lorg CPU aig àm sònraichte. Tha gach gairm sìos an stac air loidhne air a sgaradh le leth-dhuilleag. Ann am meadhan nan loidhnichean chì sinn an syscall ga ainmeachadh: read(): .... ;do_syscall_64;sys_read; .... Mar sin bidh cadvisor a’ caitheamh mòran ùine air gairm an t-siostaim read()co-cheangailte ri gnìomhan mem_cgroup_* (stack gairm / deireadh na loidhne).

Tha e mì-ghoireasach faicinn ann an gairm lorg dè dìreach a thathas a’ leughadh, mar sin ruithidh sinn strace agus chì sinn dè a bhios cadvisor a’ dèanamh agus lorgaidh sinn fiosan siostam nas fhaide na 100 ms:

theojulienne@kube-node-bad ~ $ sudo strace -p 10137 -T -ff 2>&1 | egrep '<0.[1-9]'
[pid 10436] <... futex resumed> ) = 0 <0.156784>
[pid 10432] <... futex resumed> ) = 0 <0.258285>
[pid 10137] <... futex resumed> ) = 0 <0.678382>
[pid 10384] <... futex resumed> ) = 0 <0.762328>
[pid 10436] <... read resumed> "cache 154234880nrss 507904nrss_h"..., 4096) = 658 <0.179438>
[pid 10384] <... futex resumed> ) = 0 <0.104614>
[pid 10436] <... futex resumed> ) = 0 <0.175936>
[pid 10436] <... read resumed> "cache 0nrss 0nrss_huge 0nmapped_"..., 4096) = 577 <0.228091>
[pid 10427] <... read resumed> "cache 0nrss 0nrss_huge 0nmapped_"..., 4096) = 577 <0.207334>
[pid 10411] <... epoll_ctl resumed> ) = 0 <0.118113>
[pid 10382] <... pselect6 resumed> ) = 0 (Timeout) <0.117717>
[pid 10436] <... read resumed> "cache 154234880nrss 507904nrss_h"..., 4096) = 660 <0.159891>
[pid 10417] <... futex resumed> ) = 0 <0.917495>
[pid 10436] <... futex resumed> ) = 0 <0.208172>
[pid 10417] <... futex resumed> ) = 0 <0.190763>
[pid 10417] <... read resumed> "cache 0nrss 0nrss_huge 0nmapped_"..., 4096) = 576 <0.154442>

Mar a bhiodh dùil agad, chì sinn gairmean slaodach an seo read(). Bho shusbaint gnìomhachd leughaidh agus co-theacsa mem_cgroup tha e soilleir gu bheil na dùbhlain sin read() thoir iomradh air an fhaidhle memory.stat, a sheallas cleachdadh cuimhne agus crìochan cgroup (teicneòlas iomallachd ghoireasan Docker). Bidh an t-inneal cadvisor a’ ceasnachadh an fhaidhle seo gus fiosrachadh cleachdadh ghoireasan fhaighinn airson soithichean. Feuch an dèan sinn cinnteach an e an kernel no an comhairliche a tha a’ dèanamh rudeigin ris nach robh dùil:

theojulienne@kube-node-bad ~ $ time cat /sys/fs/cgroup/memory/memory.stat >/dev/null

real 0m0.153s
user 0m0.000s
sys 0m0.152s
theojulienne@kube-node-bad ~ $

A-nis is urrainn dhuinn am biast ath-riochdachadh agus tuigsinn gu bheil an kernel Linux mu choinneimh pathology.

Carson a tha an obair leughaidh cho slaodach?

Aig an ìre seo, tha e mòran nas fhasa teachdaireachdan a lorg bho luchd-cleachdaidh eile mu dhuilgheadasan coltach ris. Mar a thionndaidh e, anns an rianadair cadvisor chaidh aithris air a’ bhiast seo duilgheadas cus cleachdadh CPU, is e dìreach nach do mhothaich duine gu bheil an latency cuideachd air a nochdadh air thuaiream anns a’ chruach lìonra. Chaidh mothachadh gu dearbh gu robh an comhairliche a’ caitheamh barrachd ùine CPU na bha dùil, ach cha deach seo a thoirt gu mòr, leis gu bheil tòrr ghoireasan CPU aig na frithealaichean againn, agus mar sin cha deach an duilgheadas a sgrùdadh gu faiceallach.

Is e an duilgheadas a th’ ann gu bheil cgroups a’ toirt aire do chleachdadh cuimhne taobh a-staigh an ainm-àite (soithich). Nuair a dh'fhàgas a h-uile pròiseas san cgroup seo, bidh Docker a 'leigeil a-mach an cgroup cuimhne. Ach, chan e dìreach cuimhne pròiseas a th’ ann an “cuimhne”. Ged nach eilear a’ cleachdadh a’ chuimhne pròiseas fhèin tuilleadh, tha e coltach gu bheil an kernel fhathast a’ sònrachadh susbaint taisgte, leithid fiaclan agus inodes (meata-dàta leabhar-seòlaidh is faidhle), a tha air an tasgadh ann an cgroup cuimhne. Bhon tuairisgeul duilgheadas:

cgroups zombie: cgroups aig nach eil pròiseasan sam bith agus a chaidh an sguabadh às, ach a tha fhathast air an toirt seachad le cuimhne (anns a 'chùis agam, bhon tasglann fiaclaireachd, ach faodar a thoirt seachad cuideachd bho thasglann na duilleige no tmpfs).

Faodaidh sgrùdadh kernel a h-uile duilleag san tasgadan nuair a bhios tu a’ saoradh cgroup a bhith gu math slaodach, agus mar sin tha am pròiseas leisg air a thaghadh: fuirich gus an iarrar na duilleagan sin a-rithist, agus an uairsin cuir air falbh an cgroup mu dheireadh nuair a tha feum air a’ chuimhne. Gu ruige seo, thathas fhathast a’ toirt aire do cgroup nuair a thathar a’ cruinneachadh staitistig.

Bho thaobh coileanaidh, dh'ìobair iad cuimhne airson coileanadh: a 'luathachadh a' chiad ghlanadh le bhith a 'fàgail beagan cuimhne taisgte air chùl. Tha seo gu math. Nuair a chleachdas an kernel am fear mu dheireadh den chuimhne tasgaidh, thèid an cgroup a ghlanadh mu dheireadh, agus mar sin chan urrainn dha a bhith air ainmeachadh mar "aodion". Gu mì-fhortanach, tha gnìomhachadh sònraichte an uidheamachd sgrùdaidh memory.stat anns an dreach kernel seo (4.9), còmhla ris an ìre mhòr de chuimhne air na frithealaichean againn, a’ ciallachadh gun toir e fada nas fhaide an dàta taisgte as ùire a thoirt air ais agus zombies cgroup a ghlanadh.

Tha e a ’tionndadh a-mach gu robh uimhir de zombies cgroup aig cuid de na nodan againn gun deach an leughadh agus an latency nas àirde na diog.

Is e an dòigh-obrach airson duilgheadas cadvisor a bhith a’ saoradh dentries / inod caches sa bhad air feadh an t-siostaim, a chuireas às sa bhad latency leughaidh a bharrachd air latency lìonra air an aoigh, leis gu bheil glanadh an tasgadan a’ tionndadh air na duilleagan cgroup zombie tasgadan agus gan saoradh cuideachd. Chan e fuasgladh a tha seo, ach tha e a’ dearbhadh adhbhar na trioblaid.

Thionndaidh e a-mach gun deach coileanadh gairm ann an dreachan kernel nas ùire (4.19+). memory.stat, agus mar sin shocraich atharrachadh chun kernel seo an duilgheadas. Aig an aon àm, bha innealan againn gus nodan trioblaideach a lorg ann an cruinneachaidhean Kubernetes, an drèanadh gu gràsmhor agus an ath-thòiseachadh. Chìreadh sinn na cruinneachaidhean gu lèir, lorg sinn nodan le latency àrd gu leòr agus chuir sinn air ais iad. Thug seo ùine dhuinn an OS ùrachadh air na frithealaichean a bha air fhàgail.

A 'togail suas

Leis gun do chuir am biast seo stad air giollachd ciudha RX NIC airson ceudan de mhilleanan-tomhais, dh’ adhbhraich e aig an aon àm an dà chuid latency àrd air ceanglaichean goirid agus latency meadhan-ceangail, leithid eadar iarrtasan MySQL agus pacaidean freagairt.

Tha tuigse agus cumail suas coileanadh nan siostaman as bunaitiche, leithid Kubernetes, deatamach airson earbsachd agus astar nan seirbheisean uile a tha stèidhichte orra. Tha a h-uile siostam a bhios tu a’ ruith a’ faighinn buannachd bho leasachaidhean coileanaidh Kubernetes.

Source: www.habr.com

Cuir beachd ann