Муайян кардани таъхири шабака дар Кубернетес

Муайян кардани таъхири шабака дар Кубернетес

Якчанд сол пеш Кубернетес аллакай мухокима карда шуд дар блоги расмии GitHub. Аз он вақт инҷониб, он ба технологияи стандартии густариши хидматҳо табдил ёфт. Кубернетес ҳоло як қисми зиёди хидматҳои дохилӣ ва ҷамъиятиро идора мекунад. Вақте ки кластерҳои мо афзоиш ёфтанд ва талаботҳои иҷроиш сахттар шуданд, мо пай бурдем, ки баъзе хидматҳо дар Kubernetes ба таври мунтазам таъхирро аз сар мегузаронанд, ки онро бо бори худи барнома шарҳ додан мумкин нест.

Аслан, барномаҳо таъхири ба назар тасодуфии шабакаро то 100 мс ё бештар аз он эҳсос мекунанд, ки дар натиҷа мӯҳлатҳо ё кӯшишҳои такрорӣ ба вуҷуд меоянд. Интизор мерафт, ки хидматҳо метавонанд ба дархостҳо зудтар аз 100 мс ҷавоб диҳанд. Аммо ин имконнопазир аст, агар худи пайвастшавӣ ин қадар вақти зиёдро талаб кунад. Алоҳида, мо дархостҳои хеле зуди MySQL-ро мушоҳида кардем, ки бояд миллисонияҳоро дар бар гиранд ва MySQL дар миллисонияҳо анҷом ёфт, аммо аз нуқтаи назари дархости дархосткунанда, посух 100 мс ё бештар аз он вақт гирифт.

Дарҳол маълум шуд, ки мушкилот танҳо ҳангоми пайвастшавӣ ба гиреҳи Kubernetes рух медиҳад, ҳатто агар занг аз берун аз Кубернетес омада бошад. Роҳи осонтарини такрори мушкилот ин санҷиш аст ВНМО. Дар ин мақола мо дида мебароем, ки чӣ тавр мо метавонем сабаби ин мушкилотро пайгирӣ кунем.

Бартараф кардани мураккабии нолозим дар занҷир, ки ба нокомӣ оварда мерасонад

Бо такрори як мисол, мо мехостем, ки диққати мушкилотро танг кунем ва қабатҳои нолозими мураккабиро бартараф кунем. Дар аввал, дар ҷараёни байни Вегета ва қубурҳои Кубернетес унсурҳои аз ҳад зиёд буданд. Барои муайян кардани мушкилоти амиқи шабака, шумо бояд баъзеи онҳоро истисно кунед.

Муайян кардани таъхири шабака дар Кубернетес

Мизоҷ (Vegeta) бо ягон гиреҳи кластер пайвасти TCP эҷод мекунад. Kubernetes ҳамчун як шабакаи такрорӣ (дар болои шабакаи мавҷудаи маркази додаҳо) кор мекунад, ки истифода мебарад IPIP, яъне он пакетҳои IP-и шабакаи қабатро дар дохили пакетҳои IP-и маркази додаҳо фаро мегирад. Ҳангоми пайвастшавӣ ба гиреҳи аввал тарҷумаи суроғаи шабака анҷом дода мешавад Тарҷумаи суроғаи шабака (NAT) барои тарҷумаи суроғаи IP ва бандари гиреҳи Kubernetes ба суроғаи IP ва порт дар шабакаи overlay (махсусан, pod бо барнома). Барои бастаҳои воридотӣ пайдарпайии баръакси амалҳо иҷро карда мешавад. Ин як системаи мураккабест, ки дорои бисёр ҳолат ва унсурҳои зиёде мебошад, ки ҳангоми ҷойгиркунӣ ва интиқол додани хидматҳо пайваста нав карда мешаванд ва тағир меёбанд.

Коммуналӣ tcpdump дар санҷиши Vegeta дар вақти дастфишори TCP таъхир вуҷуд дорад (байни SYN ва SYN-ACK). Барои бартараф кардани ин мураккабии нолозим, шумо метавонед истифода баред hping3 барои "pings"-и оддӣ бо бастаҳои SYN. Мо тафтиш мекунем, ки оё дар бастаи ҷавоб таъхир вуҷуд дорад ва сипас пайвастро аз нав барқарор мекунем. Мо метавонем маълумотро филтр кунем, то танҳо бастаҳои аз 100 мс калонтарро дар бар гиранд ва роҳи осонтари дубора тавлид кардани мушкилотро аз санҷиши пурраи қабати шабакаи 7 дар Vegeta ба даст орем. Инҳо гиреҳи Kubernetes "pings" -ро бо истифода аз TCP SYN/SYN-ACK дар хидмати "порти гиреҳ" (30927) бо фосилаи 10 мс, ки бо посухҳои сусттарин филтр карда мешаванд:

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

Метавонед фавран мушоҳидаи аввалро анҷом диҳад. Аз руи ракамхои пайдарпай ва вактхо маълум мешавад, ки инхо якдафъаина банд нестанд. Таъхир аксар вақт ҷамъ мешавад ва дар ниҳоят коркард мешавад.

Баъдан, мо мехоҳем фаҳмем, ки кадом ҷузъҳо метавонанд дар пайдоиши банд иштирок кунанд. Шояд инҳо баъзе аз садҳо қоидаҳои iptables дар NAT бошанд? Ё ягон мушкилот бо нақби IPIP дар шабака вуҷуд дорад? Як роҳи санҷиши ин санҷиши ҳар як қадами система тавассути бартараф кардани он мебошад. Чӣ мешавад, агар шумо мантиқи NAT ва девори деворро хориҷ кунед ва танҳо қисми IPIP боқӣ монад:

Муайян кардани таъхири шабака дар Кубернетес

Хушбахтона, Linux дастрасии бевосита ба қабати қабати IP-ро осон мекунад, агар мошин дар як шабака бошад:

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

Аз рӯи натиҷаҳо, мушкилот то ҳол боқӣ мемонад! Ин iptables ва NAT-ро истисно мекунад. Пас мушкилот TCP аст? Биёед бубинем, ки пинги муқаррарии ICMP чӣ гуна мегузарад:

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

Натичадо нишон медиданд, ки проблемадо дал нашудааст. Шояд ин нақби IPIP бошад? Биёед санҷишро боз ҳам соддатар кунем:

Муайян кардани таъхири шабака дар Кубернетес

Оё ҳама бастаҳо байни ин ду ҳост фиристода мешаванд?

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

Мо вазъиятро ба ду гиреҳи Kubernetes содда кардем, ки ба ҳамдигар ҳама гуна баста, ҳатто ping ICMP мефиристанд. Онҳо то ҳол таъхирро мебинанд, агар мизбони ҳадаф "бад" бошад (баъзеҳо аз дигарон бадтар).

Акнун саволи охирин: чаро таъхир танҳо дар серверҳои kube-гиреҳ рух медиҳад? Ва оё ин вақте рӯй медиҳад, ки kube-гиреҳ ирсолкунанда ё қабулкунанда аст? Хушбахтона, фаҳмидани ин инчунин тавассути фиристодани баста аз мизбон берун аз Кубернетес, аммо бо ҳамон гирандаи "бад" маълум аст. Тавре ки шумо мебинед, мушкилот аз байн нарафтааст:

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

Сипас, мо ҳамон дархостҳоро аз сарчашмаи kube-гиреҳ ба ҳости беруна иҷро мекунем (ки ҳости манбаъро истисно мекунад, зеро пинг ҳам ҷузъҳои RX ва 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

Бо тафтиши сабти бастаҳои таъхирнопазир, мо маълумоти иловагӣ гирифтем. Махсусан, ирсолкунанда (поён) ин вақтро мебинад, аммо қабулкунанда (боло) не - сутуни Delta (дар сонияҳо) бубинед:

Муайян кардани таъхири шабака дар Кубернетес

Илова бар ин, агар шумо фарқияти тартиби бастаҳои TCP ва ICMP (аз рӯи рақамҳои пайдарпай) дар тарафи гирандаро бубинед, бастаҳои ICMP ҳамеша бо ҳамон пайдарпаии фиристодашуда, вале бо вақти гуногун меоянд. Дар айни замон, пакетҳои TCP баъзан ба ҳам мепайванданд ва баъзеи онҳо часпида мешаванд. Махсусан, агар шумо портҳои бастаҳои SYN-ро тафтиш кунед, онҳо дар тарафи ирсолкунанда ҷойгиранд, аммо на дар тарафи қабулкунанда.

Дар чӣ гуна фарқияти ночиз вуҷуд дорад кортҳои шабакавӣ серверҳои муосир (монанди серверҳои маркази додаҳои мо) пакетҳои дорои TCP ё ICMP-ро коркард мекунанд. Вақте ки баста меояд, адаптери шабакавӣ "онро дар як пайвастшавӣ ҳаш мекунад", яъне вай мекӯшад пайвастҳоро ба навбат шикаста ва ҳар як навбатро ба ядрои алоҳидаи протсессор фиристад. Барои TCP, ин хэш ҳам суроғаи IP ва порти манбаъ ва таъинотро дар бар мегирад. Ба ибораи дигар, ҳар як пайвастшавӣ ба таври гуногун (потенсиал) ҳаш карда мешавад. Барои ICMP танҳо суроғаҳои IP ҳаш карда мешаванд, зеро портҳо вуҷуд надоранд.

Боз як мушоҳидаи нав: дар ин давра мо таъхирҳои ICMP-ро дар ҳама иртибот байни ду ҳост мебинем, аммо TCP ин тавр намекунад. Ин ба мо мегӯяд, ки сабаб эҳтимолан бо ҳашингкунии навбати RX алоқаманд аст: сарборӣ қариб дар коркарди бастаҳои RX аст, на дар ирсоли посухҳо.

Ин фиристодани бастаҳоро аз рӯйхати сабабҳои эҳтимолӣ нест мекунад. Ҳоло мо медонем, ки мушкилоти коркарди бастаҳо дар баъзе серверҳои гиреҳи kube дар тарафи қабул аст.

Фаҳмидани коркарди бастаҳо дар ядрои Linux

Барои фаҳмидани он ки чаро мушкилот дар қабулкунанда дар баъзе серверҳои kube-гиреҳ рух медиҳад, биёед бубинем, ки ядрои Linux пакетҳоро чӣ гуна коркард мекунад.

Бозгашт ба соддатарин татбиқи анъанавӣ, корти шабака бастаро қабул мекунад ва мефиристад халалдор кардан ядрои Linux, ки бастае вуҷуд дорад, ки бояд коркард карда шавад. Ядро кори дигарро бозмедорад, контекстро ба коркардкунандаи қатъ мекунад, бастаро коркард мекунад ва сипас ба вазифаҳои ҷорӣ бармегардад.

Муайян кардани таъхири шабака дар Кубернетес

Ин гузариши контекст суст аст: дар солҳои 10-ум дар кортҳои шабакавии 90 Мбит/с таъхир метавонад ба назар намерасид, аммо дар кортҳои муосири 10G бо интиқоли ҳадди аксар 15 миллион пакет дар як сония, ҳар як ядрои сервери ҳашт ядроии хурд метавонад миллионҳо қатъ карда шавад. маротиба дар як сония.

Барои он ки пайваста халалдор нашавед, чандин сол пеш Linux илова карда буд НАПИ: Шабакаи API, ки ҳама драйверҳои муосир барои беҳтар кардани кор бо суръати баланд истифода мебаранд. Дар суръати паст ядро ​​​​ҳанӯз аз корти шабака ба таври кӯҳна халалҳоро қабул мекунад. Пас аз расидани бастаҳои кофӣ, ки аз ҳадди меъёр зиёданд, ядро ​​​​фанҳоро ғайрифаъол мекунад ва ба ҷои он ба пурсиши адаптери шабака ва гирифтани пакетҳо дар қисмҳо оғоз мекунад. Коркард дар softirq анҷом дода мешавад, яъне дар контексти қатъҳои нармафзор пас аз зангҳои система ва қатъи сахтафзор, вақте ки ядро ​​​​(бар хилофи фазои корбар) аллакай кор мекунад.

Муайян кардани таъхири шабака дар Кубернетес

Ин хеле тезтар аст, аммо боиси мушкилоти дигар мегардад. Агар бастаҳо аз ҳад зиёд бошанд, он гоҳ ҳама вақт барои коркарди бастаҳо аз корти шабака сарф мешавад ва равандҳои фазои корбар барои воқеан холӣ кардани ин навбатҳо вақт надоранд (хондан аз пайвастҳои TCP ва ғ.). Дар ниҳоят, навбатҳо пур мешаванд ва мо ба партофтани пакетҳо шурӯъ мекунем. Дар кӯшиши пайдо кардани тавозун, ядро ​​барои шумораи ҳадди аксар бастаҳои коркардшуда дар заминаи softirq буҷет муқаррар мекунад. Пас аз гузаштани ин буҷет, як риштаи алоҳида бедор мешавад ksoftirqd (шумо яке аз онҳоро дар ps барои ҳар як ядро), ки ин softirqҳоро берун аз роҳи муқаррарии системаи занги / қатъкунӣ идора мекунад. Ин ришта бо истифода аз нақшаи равандҳои стандартӣ, ки кӯшиш мекунад, ки захираҳоро одилона тақсим кунад, ба нақша гирифта шудааст.

Муайян кардани таъхири шабака дар Кубернетес

Пас аз омӯхтани он, ки ядро ​​​​пакетҳоро чӣ гуна коркард мекунад, шумо мебинед, ки эҳтимолияти бандшавӣ вуҷуд дорад. Агар зангҳои softirq камтар қабул карда шаванд, бастаҳо бояд муддате интизор шаванд, то дар навбати RX дар корти шабака коркард шаванд. Ин метавонад сабаби бастани ягон вазифа бошад, ки ядрои протсессорро бозмедорад ва ё чизи дигар аз кор кардани ядро ​​​​монеъ мешавад softirq.

Маҳдуд кардани коркарди аслӣ ё усули

Таъхирҳои Softirq ҳоло танҳо як тахмин аст. Аммо ин маъно дорад ва мо медонем, ки мо чизи хеле монандро мебинем. Пас, қадами оянда тасдиқи ин назария аст. Ва агар тасдиқ шавад, пас сабаби таъхирро пайдо кунед.

Биёед ба бастаҳои сусти худ баргардем:

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

Тавре ки қаблан муҳокима карда шуд, ин бастаҳои ICMP ба як навбати ягонаи RX NIC ҳаш карда мешаванд ва аз ҷониби як ядрои ягонаи CPU коркард карда мешаванд. Агар мо хоҳем фаҳмем, ки чӣ тавр Linux кор мекунад, барои пайгирии раванд фаҳмидани он муфид аст, ки ин бастаҳо дар куҷо (дар кадом ядрои CPU) ва чӣ гуна (softirq, ksoftirqd) коркард мешаванд.

Акнун вақти истифодаи абзорҳое расидааст, ки ба шумо имкон медиҳанд ядрои Linux-ро дар вақти воқеӣ назорат кунед. Дар ин ҷо мо истифода мебарем нусхабардорӣ. Ин маҷмӯи асбобҳо ба шумо имкон медиҳад, ки барномаҳои хурди C нависед, ки функсияҳои ихтиёриро дар ядро ​​пайваст мекунанд ва рӯйдодҳоро дар барномаи Python-и корбар буферӣ мекунанд, ки метавонанд онҳоро коркард кунанд ва натиҷаро ба шумо баргардонанд. Пайваст кардани функсияҳои худсарона дар ядро ​​​​тиҷорати душвор аст, аммо утилита барои амнияти ҳадди аксар тарҳрезӣ шудааст ва барои пайгирӣ кардани маҳз навъи масъалаҳои истеҳсолӣ тарҳрезӣ шудааст, ки дар муҳити озмоиш ё таҳия ба осонӣ дубора тавлид намешаванд.

Нақша дар ин ҷо оддӣ аст: мо медонем, ки ядро ​​ин пингҳои ICMP-ро коркард мекунад, аз ин рӯ мо ба функсияи ядро ​​қалмоқе мегузорем. icmp_echo, ки бастаи дархости эхо-и ICMP-ро қабул мекунад ва фиристодани посухи эхо-и ICMP-ро оғоз мекунад. Мо метавонем бастаро тавассути зиёд кардани рақами icmp_seq муайян кунем, ки нишон медиҳад hping3 баландтар.

рамз скрипти bcc мураккаб ба назар мерасад, аммо он қадар даҳшатнок нест, ки ба назар мерасад. Функсия icmp_echo интиқол медиҳад struct sk_buff *skb: Ин маҷмӯа бо "дархости эхо" аст. Мо метавонем онро пайгирӣ кунем, пайдарпайро берун кашем echo.sequence (ки бо муқоиса icmp_seq аз ҷониби hping3 выше), ва онро ба фазои корбар фиристед. Он инчунин барои гирифтани номи раванди ҷорӣ/id қулай аст. Дар зер натиҷаҳое ҳастанд, ки мо бевосита ҳангоми коркарди ядро ​​​​бастаҳо мебинем:

TGID PID РАВАНДИ НОМИ ICMP_SEQ
0 0 ивазкунанда / 11
770 0 ивазкунанда / 0
11 771 ивазкунанда / 0
0 11 ивазкунанда / 772
0 0 ивазкунанда / 11
773 0 Прометей 0
11 774 ивазкунанда / 20041
20086 775 ивазкунанда / 0
0 11 ивазкунанда / 776
0 0 сухан-хабар-хо 11

Дар ин чо бояд кайд кард, ки дар заминаи softirq равандҳое, ки зангҳои системаро анҷом додаанд, ҳамчун "равандҳо" пайдо мешаванд, дар ҳоле ки дар асл он ядроест, ки бастаҳоро дар контексти ядро ​​бехатар коркард мекунад.

Бо ин асбоб мо метавонем равандҳои мушаххасро бо бастаҳои мушаххасе, ки таъхирро нишон медиҳанд, пайваст кунем hping3. Биёед онро содда кунем grep дар бораи ин забт барои арзишҳои муайян icmp_seq. Бастаҳое, ки ба арзишҳои дар боло зикршуда icmp_seq мувофиқанд, дар якҷоягӣ бо RTT-и онҳо, ки мо дар боло мушоҳида кардем, ишора карда шуданд (дар қавс арзишҳои пешбинишудаи RTT барои бастаҳое ҳастанд, ки мо бо сабаби арзишҳои RTT камтар аз 50 мс филтр кардаем):

TGID PID Раванди НОМИ ICMP_SEQ ** RTT
--
10137 10436 кадвисор соли 1951
10137 10436 кадвисор соли 1952
76 76 ксофтиркд/11 1953 ** 99ms
76 76 ксофтиркд/11 1954 ** 89мс
76 76 ксофтиркд/11 1955 ** 79мс
76 76 ксофтиркд/11 1956 ** 69мс
76 76 ксофтиркд/11 1957 ** 59мс
76 76 ксофтиркд/11 1958 ** (49ms)
76 76 ксофтиркд/11 1959 ** (39ms)
76 76 ksoftirqd/11 1960 ** (29ms)
76 76 ксофтиркд/11 1961 ** (19мс)
76 76 ксофтиркд/11 1962 ** (9ms)
--
10137 10436 кадвисор 2068
10137 10436 кадвисор 2069
76 76 ksoftirqd/11 2070 ** 75ms
76 76 ksoftirqd/11 2071 ** 65ms
76 76 ksoftirqd/11 2072 ** 55ms
76 76 ksoftirqd/11 2073 ** (45ms)
76 76 ksoftirqd/11 2074 ** (35ms)
76 76 ksoftirqd/11 2075 ** (25ms)
76 76 ksoftirqd/11 2076 ** (15ms)
76 76 ksoftirqd/11 2077 ** (5ms)

Натиҷаҳо ба мо чанд чизро мегӯянд. Аввалан, ҳамаи ин бастаҳо аз рӯи контекст коркард карда мешаванд ksoftirqd/11. Ин маънои онро дорад, ки барои ин ҷуфти мушаххаси мошинҳо, бастаҳои ICMP дар охири қабул ба ядрои 11 ҳаш карда шудаанд. Мо инчунин мебинем, ки вақте ки роҳбандӣ вуҷуд дорад, пакетҳое ҳастанд, ки дар контексти занги система коркард мешаванд cadvisor. Баъд ksoftirqd вазифаро ба ӯҳда мегирад ва навбати ҷамъшударо коркард мекунад: маҳз шумораи пакетҳое, ки пас аз он ҷамъ шудаанд cadvisor.

Далели он, ки фавран пеш аз он ҳамеша кор мекунад cadvisor, иштироки уро ба проблема дар назар дорад. Аҷиб, ҳадаф кадвизор - "таҳлили истифодабарии захираҳо ва хусусиятҳои кори контейнерҳои коркунанда" на ба ин мушкили иҷроиш.

Мисли дигар ҷанбаҳои контейнерҳо, ин ҳама асбобҳои хеле пешрафта мебошанд ва интизор шудан мумкин аст, ки дар баъзе ҳолатҳои ғайричашмдошт мушкилоти иҷроишро аз сар гузаронанд.

Кадвизор чӣ кор мекунад, ки навбати бастаҳоро суст мекунад?

Ҳоло мо дарки хуб дорем, ки чӣ гуна садама рух медиҳад, кадом раванд боиси он мегардад ва дар кадом CPU. Мо мебинем, ки бо сабаби бастани сахт, ядрои Linux барои ҷадвал вақт надорад ksoftirqd. Ва мо мебинем, ки бастаҳо дар контекст коркард карда мешаванд cadvisor. Чунин тахмин кардан мантик аст cadvisor системаи сустро оғоз мекунад, ки пас аз он ҳамаи пакетҳои дар он вақт ҷамъшуда коркард мешаванд:

Муайян кардани таъхири шабака дар Кубернетес

Ин як назария аст, аммо чӣ гуна онро санҷидан мумкин аст? Мо чӣ кор карда метавонем, ин аст, ки ядрои CPU-ро дар тӯли ин раванд пайгирӣ кунем, нуқтаеро ёбем, ки шумораи пакетҳо аз буҷа мегузарад ва ksoftirqd номида мешавад ва сипас каме ба ақиб нигарем, то бубинем, ки маҳз дар ядрои CPU маҳз пеш аз он чӣ кор мекард. . Ин ба монанди рентген кардани CPU дар ҳар чанд миллисония аст. Он чизе монанди ин хоҳад буд:

Муайян кардани таъхири шабака дар Кубернетес

Ба таври қулай, ҳамаи инро бо асбобҳои мавҷуда кардан мумкин аст. Барои намуна, сабти perf ядрои CPU-ро бо басомади муайян тафтиш мекунад ва метавонад ҷадвали зангҳоро ба системаи корбар, аз ҷумла фазои корбар ва ядрои Linux тавлид кунад. Шумо метавонед ин сабтро бигиред ва онро бо истифода аз порчаи хурди барнома коркард кунед FlameGraph аз Брендан Грегг, ки тартиби пайгирии стекро нигоҳ медорад. Мо метавонем пайҳои стеки яксараро ҳар 1 мс захира кунем ва баъд намунаро 100 миллисония пеш аз расидани пай таъкид ва захира кунем. 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

Инҳоянд натиҷаҳо:

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

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

Дар ин ҷо чизҳои зиёде мавҷуданд, аммо чизи асосӣ ин аст, ки мо намунаи "кадвизор пеш аз ksoftirqd" -ро пайдо мекунем, ки қаблан дар трекери ICMP дида будем. Ин чӣ маъно дорад?

Ҳар як сатр пайгирии CPU дар як нуқтаи муайяни вақт аст. Ҳар як занги поёни стек дар сатр бо нуқта-вергул ҷудо карда мешавад. Дар мобайни сатрҳо мо мебинем, ки система даъват карда мешавад: read(): .... ;do_syscall_64;sys_read; .... Ҳамин тавр, cadvisor вақти зиёдеро барои занги система сарф мекунад read()вобаста ба функсияҳо mem_cgroup_* (боло стеки занг/охири сатр).

Дар пайгирии занг дидани он ки маҳз чӣ хонда мешавад, нороҳат аст, пас биёед давем strace ва биёед бубинем, ки cadvisor чӣ кор мекунад ва зангҳои системаро бештар аз 100 мс пайдо кунед:

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>

Тавре ки шумо интизор будед, мо дар ин ҷо зангҳои сустро мебинем read(). Аз мундариҷаи амалиёти хондан ва контекст mem_cgroup равшан аст, ки ин душворихо read() ба файл муроҷиат кунед memory.stat, ки истифодаи хотира ва маҳдудиятҳои гурӯҳҳоро нишон медиҳад (технологияи ҷудокунии захираҳои Docker). Воситаи cadvisor ин файлро дархост мекунад, то маълумоти истифодаи захираҳоро барои контейнерҳо ба даст орад. Биёед бубинем, ки оё ядро ​​ё кадвизор кори ғайричашмдошт мекунад:

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 ~ $

Акнун мо метавонем хатогиро дубора тавлид кунем ва бифаҳмем, ки ядрои Linux бо патология рӯбарӯ аст.

Чаро амалиёти хондан ин кадар суст аст?

Дар ин марҳила пайдо кардани паёмҳои корбарони дигар дар бораи мушкилоти шабеҳ хеле осонтар аст. Тавре маълум шуд, дар трекери кадвизор ин хато ҳамчунон гузориш дода шудааст мушкилоти истифодаи аз ҳад зиёди CPU, ин танҳо он аст, ки ҳеҷ кас пай набурд, ки таъхир низ дар стек шабака ба таври тасодуфӣ инъикос меёбад. Воқеан мушоҳида шуд, ки cadvisor вақти бештари CPU-ро аз интизорӣ сарф мекунад, аммо ба ин аҳамияти зиёд дода нашуд, зеро серверҳои мо захираҳои зиёди CPU доранд, бинобар ин мушкилот бодиққат омӯхта нашудааст.

Мушкилот дар он аст, ки гурӯҳҳо истифодаи хотираро дар фазои номҳо (контейнер) ба назар мегиранд. Вақте ки ҳамаи равандҳо дар ин гурӯҳ хориҷ мешаванд, Docker гурӯҳи хотираро мебарорад. Аммо, "хотира" танҳо хотираи коркард нест. Ҳарчанд худи хотираи раванд дигар истифода намешавад, чунин ба назар мерасад, ки ядро ​​то ҳол мундариҷаи кэшшударо таъин мекунад, ба монанди дандонҳо ва инодҳо (директорҳо ва метамаълумоти файл), ки дар гурӯҳи хотира кэш карда мешаванд. Аз тавсифи мушкилот:

гурӯҳҳои зомби: гурӯҳҳое, ки раванд надоранд ва нест карда шудаанд, аммо ба ҳар ҳол хотира ҷудо карда шудаанд (дар ҳолати ман, аз кэши dentry, аммо онро инчунин аз кэши саҳифа ё tmpfs ҷудо кардан мумкин аст).

Санҷиши ядрои ҳамаи саҳифаҳои кэш ҳангоми озод кардани гурӯҳ метавонад хеле суст бошад, бинобар ин раванди танбалӣ интихоб карда мешавад: интизор шавед, ки ин саҳифаҳо дубора дархост карда шаванд ва дар ниҳоят, вақте ки хотира воқеан лозим аст, гурӯҳро тоза кунед. То ин дам, ҳангоми ҷамъоварии омор, гурӯҳҳо ба назар гирифта мешаванд.

Аз нуқтаи назари кор, онҳо хотираро барои иҷроиш қурбон карданд: суръат бахшидан ба тозакунии ибтидоӣ тавассути гузоштани баъзе хотираи кэшшуда. Ин хуб аст. Вақте ки ядро ​​охирин хотираи кэшшударо истифода мебарад, гурӯҳ дар ниҳоят тоза карда мешавад, аз ин рӯ онро "ихроҷ" номидан мумкин нест. Мутаассифона, татбици конкретии механизми чустучу memory.stat дар ин версияи ядро ​​​​(4.9), дар якҷоягӣ бо миқдори зиёди хотираи серверҳои мо, маънои онро дорад, ки барои барқарор кардани маълумоти охирини кэшшуда ва тоза кардани зомбиҳои гурӯҳӣ вақти зиёд лозим аст.

Маълум мешавад, ки баъзе гиреҳҳои мо он қадар зомбиҳои гурӯҳӣ доштанд, ки хондан ва таъхир аз як сония зиёд буд.

Роҳи ҳалли масъалаи cadvisor фавран озод кардани кэшҳои dentries/inodes дар тамоми система мебошад, ки он таъхири хондан ва инчунин таъхири шабакаро дар ҳост фавран нест мекунад, зеро тозакунии кэш саҳифаҳои зомбиҳои cgroup кэшшударо бармегардонад ва онҳо низ озод карда мешаванд. Ин роҳи ҳал нест, аммо сабаби мушкилотро тасдиқ мекунад.

Маълум шуд, ки дар версияҳои нави ядро ​​​​(4.19+) иҷрои занг беҳтар шудааст memory.stat, бинобар ин гузариш ба ин ядро ​​мушкилотро ҳал кард. Ҳамзамон, мо асбобҳое доштем, ки гиреҳҳои мушкилотро дар кластерҳои Kubernetes ошкор кунанд, онҳоро ба таври возеҳ холӣ кунанд ва дубора оғоз кунанд. Мо ҳама кластерҳоро шона кардем, гиреҳҳои дорои таъхири кофӣ баланд ёфтем ва онҳоро дубора оғоз кардем. Ин ба мо вақт дод, ки OS-ро дар серверҳои боқимонда навсозӣ кунем.

Барои ҷамъбаст кардан

Азбаски ин хато коркарди навбати RX NIC-ро дар тӯли садҳо миллисония қатъ кард, он ҳамзамон боиси таъхири баланд дар пайвастҳои кӯтоҳ ва таъхири миёнаи пайвастшавӣ, ба мисли байни дархостҳои MySQL ва бастаҳои посух гашт.

Фаҳмидан ва нигоҳ доштани кори системаҳои бунёдӣ, ба монанди Kubernetes, барои эътимоднокӣ ва суръати ҳама хидматҳо дар асоси онҳо муҳим аст. Ҳар як системае, ки шумо идора мекунед, аз беҳбуди иҷрои Kubernetes баҳра мебарад.

Манбаъ: will.com

Илова Эзоҳ