Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

У сучасных дата-цэнтрах устаноўлены сотні актыўных прылад, пакрытых рознымі відамі маніторынгаў. Але нават ідэальны інжынер з ідэальным маніторынгам у руках зможа правільна адрэагаваць на сеткавы збой толькі за некалькі хвілін. У дакладзе на канферэнцыі Next Hop 2020 я прадставіў метадалогію дызайну сеткі ДЦ, у якой ёсць унікальная асаблівасць – дата-цэнтр лечыць сябе сам за мілісекунды. Дакладней, інжынер спакойна чыніць праблему, у той час як сэрвісы яе проста не заўважаюць.

- Для пачатку я дам дастаткова падрабязную ўступную для тых, хто, можа быць, не ў курсе прылады сучаснага ДЦ.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Для шматлікіх сеткавых інжынераў сетка дата-цэнтра пачынаецца, вядома, з ToR, са світаку ў стойцы. ToR звычайна мае два тыпы лінкоў. Маленькія ідуць да сервераў, іншыя – іх у N разоў больш – ідуць у бок спайнаў першага ўзроўня, гэта значыць да яго аплінак. Аплінкі звычайна лічацца раўназначнымі, і трафік паміж аплінкамі балансуецца на аснове хеша ад 5-tuple, у які ўваходзяць proto, src_ip, dst_ip, src_port, dst_port. Тут ніякіх сюрпрызаў.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Далей, як выглядае архітэктура плэйнаў? Спайны першага ўзроўня паміж сабой не злучаныя, а злучаюцца пасродкам суперспайнаў. За суперспайны ў нас будзе адказваць літара X, яна практычна як красканнект.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

І зразумелая справа, што з іншага боку да ўсіх спайнаў першага ўзроўня падлучаныя торы. Што важна на гэтым малюнку? Калі ў нас ідзе ўзаемадзеянне ўсярэдзіне стойкі, то ўзаемадзеянне, зразумелая справа, ідзе праз ToR. Калі ўзаемадзеянне ідзе ўнутры модуля, то ўзаемадзеянне ідзе праз спайны першага ўзроўню. Калі ўзаемадзеянне міжмодульнае - як тут, ToR 1 і ToR 2, - то ўзаемадзеянне пойдзе праз спайны як першага, так і другога ўзроўню.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Тэарэтычна такая архітэктура лёгка маштабуецца. Калі ў нас ёсць партовая ёмістасць, запас месца ў дата-цэнтры і загадзя пракладзенае валакно, то заўсёды колькасць плэйнаў можна нарасціць, тым самым павялічваючы агульную ёмістасць сістэмы. На паперы зрабіць такое вельмi лёгка. Было б так у жыцці. Але сённяшняе апавяданне не пра гэта.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Я хачу, каб былі зроблены правільныя высновы. У нас унутры дата-цэнтра шмат шляхоў. Яны ўмоўна незалежныя. Адзін шлях усярэдзіне дата-цэнтра магчымы толькі ўсярэдзіне ToR. Унутры модуля ў нас колькасць шляхоў роўна колькасці плэйнаў. Колькасць шляхоў паміж модулямі роўна здабытку ліку плэйнаў на лік суперспайн ў кожным плейне. Каб было больш зразумела, каб адчуць маштаб, я дам лічбы, якія справядлівыя для аднаго з дата-цэнтраў Яндэкса.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Плейны восем, у кожным плейне 32 суперспайны. У выніку атрымліваецца, што ўсярэдзіне модуля восем шляхоў, а пры міжмодульным узаемадзеянні іх ужо 256.

Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Гэта значыць калі мы распрацоўваем Cookbook, спрабуем навучыцца таму, як будаваць адмоваўстойлівыя дата-цэнтры, якія лечаць сябе самастойна, то плейновая архітэктура - правільны выбар. Яна дазваляе рашыць задачу маштабавання, і тэарэтычна гэта лёгка. Ёсць шмат незалежных шляхоў. Застаецца пытанне: як такая архітэктура перажывае збоі? Бываюць розныя збоі. І мы зараз гэта абмяркуем.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Хай у нас адзін з суперспайнаў "захварэў". Я тут вярнуўся да архітэктуры двух плэйнаў. У якасці прыкладу мы спынімся на іх, таму што тут папросту будзе лягчэй бачыць, што адбываецца, з меншай колькасцю частак, якія рухаюцца. Няхай X11 захварэў. Як гэта паўплывае на сэрвісы, якія жывуць усярэдзіне дата-цэнтраў? Вельмі шмат залежыць ад таго, як збой выглядае на самой справе.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Калі збой добры, ловіцца на ўзроўні аўтаматыкі таго ж BFD, аўтаматыка радасна кладзе праблемныя стыкі і ізалюе праблему, тое ўсё добра. У нас мноства шляхоў, трафік маментальна перамаршрутызуецца на альтэрнатыўныя маршруты, і сэрвісы нічога не заўважаць. Гэта добры сцэнар.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Дрэнны сцэнар - калі ў нас узнікаюць пастаянныя страты, і аўтаматыка праблемы не заўважае. Каб зразумець, як гэта ўплывае на дадатак, нам давядзецца выдаткаваць крыху часу на абмеркаванне таго, як працуе пратакол TCP.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Я спадзяюся, што нікога не шакую гэтую інфармацыяй: TCP – пратакол з пацверджаннем перадачы. Гэта значыць, у найпростым выпадку ў нас адпраўнік адпраўляе два пакеты, і атрымлівае на іх кумулятыўны ack: «Я атрымаў два пакеты».
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Пасля гэтага ён адправіць яшчэ два пакеты, і сітуацыя паўторыцца. Я загадзя прашу прабачэння за некаторае спрашчэнне. Такі сцэнар дакладны, калі акно (лік пакетаў у палёце) роўна двум. Канешне, у агульным выпадку гэта неабавязкова так. Але на кантэкст перапасылкі пакетаў памер акна не ўплывае.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Што будзе, калі мы страцім пакет 3? У гэтым выпадку атрымальнік атрымае пакеты 1, 2 і 4. І ён у відавочным выглядзе з дапамогай опцыі SACK паведаміць адпраўніку: "Ты ведаеш, тры дайшло, а сярэдзіна згубілася". Ён кажа: "Ack 2, SACK 4".
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Адпраўнік у гэты момант без праблем паўтарае менавіта той пакет, які згубіўся.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Але калі згубіцца апошні пакет у акне, сітуацыя будзе выглядаць зусім інакш.

Атрымальнік атрымлівае першыя тры пакеты і перш за ўсё пачынае чакаць. Дзякуючы некаторым аптымізацыям у TCP-стэка ядра Linux ён будзе чакаць парнага пакета, калі няма відавочнага ўказання ў сцягах, што гэта апошні пакет або нешта падобнае. Ён пачакае, пакуль скончыцца Delayed ACK таймаўт, і пасля гэтага адправіць пацверджанне на першыя тры пакеты. Але зараз ужо адпраўнік будзе чакаць. Ён жа не ведае, згубіўся чацвёрты пакет ці вось-вось дойдзе. А каб не перагружаць сетку, ён будзе спрабаваць дачакацца моманту відавочнага ўказання, што пакет страчаны, ці заканчэння RTO timeout.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Што такое RTO timeout? Гэта максімум ад вылічанага TCP-стэкам RTT і некаторай канстанты. Што гэта за канстанта, мы зараз абмяркуем.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Але важна, што калі нам зноў не шанцуе і чацвёрты пакет зноў губляецца, то RTO падвойваецца. Гэта значыць кожная няўдалая спроба - гэта падваенне таймаўту.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Цяпер паглядзім, чаму роўная гэтая база. Па дэфолце мінімальны RTO роўны 200 мс. Гэта мінімальны RTO для дата-пакетаў. Для SYN-пакетаў ён іншы, 1 секунда. Як можна бачыць, нават першая спроба пераслаць пакеты будзе па часе займаць у 100 разоў больш, чым RTT усярэдзіне дата-цэнтра.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Цяпер вернемся да нашага сцэнара. Што адбываецца ў сервісу? Сэрвіс пачынае губляць пакеты. Няхай сэрвісу спачатку ўмоўна вязе і губляецца нешта ў сярэдзіне акна, тады ён атрымлівае SACK, перасылае пакеты, якія згубіліся.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Але калі нешанцаванне паўтараецца, то ў нас здараецца RTO. Што тут важна? Так, у нас у сетцы вельмі шмат шляхоў. Але TCP-трафік аднаго канкрэтнага TCP-злучэння будзе працягваць ісці праз адзін і той жа біты стэк. Страты пакетаў пры ўмове, што гэты наш чароўны X11 не згасае самастойна, не прыводзяць да таго, што трафік перацякае ва ўчасткі, якія не з'яўляюцца праблемнымі. Мы спрабуем даставіць пакет праз той жа самы біты стэк. Гэта прыводзіць да каскаднай адмовы: дата-цэнтр – гэта мноства якія ўзаемадзейнічаюць прыкладанняў, і частка TCP-злучэнняў усіх гэтых прыкладанняў пачынаюць дэградаваць – таму што суперспайн закранае наогул усе прыкладанні, якія ёсць усярэдзіне ДЦ. Як у прымаўцы: не падкавалі каня - конь закульгаў; конь закульгаў - данясенне не даставілі; данясенне не даставілі - прайгралі вайну. Толькі тут рахунак ідзе на секунды з моманту ўзнікнення праблемы да стадыі дэградацыі, якую пачынаюць адчуваць сэрвісы. А значыць нешта дзесьці могуць недаатрымаць карыстальнікі.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Ёсць два класічныя рашэнні, якія адзін аднаго дапаўняюць. Першае - гэта сэрвісы, якія спрабуюць падкласці саломкі і вырашыць праблему так: «А давайце мы падкруцім што-небудзь у TCP-стэку. А давайце мы зробім таймаўты на ўзроўні прыкладання або доўга якія жывуць TCP-сесіі з унутранымі health checks». Праблема ў тым, што такія рашэнні: а) увогуле не маштабуюцца; б) вельмі дрэнна правяраюцца. Гэта значыць нават калі сэрвіс выпадкова наладзіць TCP-стэк так, каб яму стала лепш, па-першае, гэта ці наўрад будзе дастасавальна для ўсіх прыкладанняў і ўсіх дата-цэнтраў, а па-другое, хутчэй за ўсё, ён не зразумее, што зроблена правільна , а што не. Гэта значыць, яно працуе, але працуе дрэнна і не маштабуецца. І калі ўзнікае сеткавая праблема, хто вінаваты? Канешне, NOC. Што робіць NOC?

Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Многія сэрвісы лічаць, што ў NOC праца адбываецца прыкладна так. Але калі казаць сапраўды, не толькі.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

NOC у класічнай схеме займаецца распрацоўкай мноства маніторынгаў. Гэта як black box-маніторынгі, так і white box. Аб прыкладзе black box-маніторынгу спайнаў распавядаў Аляксандр Кліменка на мінулым Next Hop. Дарэчы, гэты маніторынг працуе. Але нават ідэальны маніторынг будзе мець лаг у часе. Звычайна гэта некалькі хвілін. Пасля таго, як ён спрацоўвае, дзяжурным інжынерам неабходны час, каб пераправерыць яго працу, лакалізаваць праблему і пасля гэтага пагасіць праблемны ўчастак. Гэта значыць у лепшым выпадку лячэнне праблемы займае 5 хвілін, у горшым 20 хвілін, калі адразу аказваецца не відавочна, дзе ж узнікаюць страты. Зразумелая справа, што ўвесь гэты час - 5 ці 20 хвілін - у нас будуць працягваць хварэць сэрвісы, што, напэўна, нядобра.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Што вельмі хацелася б атрымаць? У нас жа столькі шляхоў. А праблемы ўзнікаюць роўна таму, што TCP-струмені, якім не шанцуе, працягваюць выкарыстоўваць адзін і той жа маршрут. Трэба нешта, што дазволіць нам выкарыстоўваць мноства маршрутаў у рамках аднаго TCP-злучэнні. Здавалася б, у нас ёсць рашэнне. Ёсць TCP, які так і называецца – multipath TCP, гэта значыць TCP для мноства шляхоў. Праўда, распрацоўваўся ён для зусім іншай задачы – для смартфонаў, якія маюць некалькі сеткавых прылад. Каб максымізаваць перадачу або зрабіць рэжым primary/backup, быў распрацаваны механізм, які празрыста для прыкладання стварае некалькі патокаў (сеансаў) і дазваляе ў выпадку ўзнікнення збою перамыкацца паміж імі. Ці, як я сказаў, максымізаваць паласу.

Але тут ёсць нюанс. Каб зразумець, у чым ён, нам давядзецца паглядзець, як устанаўліваюцца патокі.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Струмені ўсталёўваюцца паслядоўна. Спачатку ўстанаўліваецца першы паток. Потым з выкарыстаннем печыва, якая ўжо ўзгоднена ў рамках гэтага патоку, устанаўліваюцца наступныя патокі. І тут праблема.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Праблема ў тым, што калі першы паток не ўсталюецца, другія і трэція патокі ніколі і не ўзнікнуць. Гэта значыць multipath TCP ніяк не вырашае страту SYN пакета ў першага струменя. І калі SYN губляецца, multipath TCP ператвараецца ў звычайны TCP. А значыць, у асяроддзі дата-цэнтра не дапаможа нам вырашыць праблему страт у фабрыцы і навучыцца выкарыстоўваць мноства шляхоў у выпадку збою.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Што нам можа дапамагчы? Некаторыя з вас ужо здагадаліся з назову, што важным полем у нашым наступным апавяданні стане поле загалоўка IPv6 flow label. І праўда, гэтае поле, якое з'яўляецца ў v6, яго няма ў v4, яно займае 20 біт, і з нагоды яго выкарыстанні доўгі час ішлі спрэчкі. Гэта вельмі цікава – спрэчкі ішлі, нешта фіксавалася ў рамках RFC, а ў Linux-ядры ў той жа час з'явілася рэалізацыя, якая так нідзе і не задакументаваная.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Я прапаную вам разам са мной адправіцца на невялікае расследаванне. Давайце паглядзім, што адбывалася ў ядры Linux за апошнія некалькі гадоў.

Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

2014 год. Інжынер з адной буйной і паважанай кампаніі дадае ў функцыянальнасць ядра Linux залежнасць значэння flow label ад хеша сокета. Што тут спрабавалі паправіць? Гэта злучана з RFC 6438, у якім абмяркоўвалася наступная праблема. Усярэдзіне дата-цэнтра часцяком инкапсулируется IPv4 у пакеты IPv6, таму што сама фабрыка - IPv6, але вонкі неяк трэба аддаць IPv4. Доўгі час былі праблемы са свічкамі, якія не маглі зазірнуць пад два IP-загалоўка, каб дабрацца да TCP ці UDP і знайсці там src_ports, dst_ports. Атрымлівалася, што хэш, калі глядзець на два першыя IP-загалоўка, апыняўся ці ледзь не фіксаваным. Каб гэтага пазбегнуць, каб балансаванне гэтага інкапсуляванага трафіку працавала карэктна, прапанавалі ў значэнне поля flow label дадаць хэш ад 5-tuple інкапсуляванага пакета. Прыкладна тое ж самае было зроблена і для іншых схем інкапсуляцыі, для UDP, для GRE, у апошнім выкарыстоўвалася поле GRE Key. Так ці інакш, тут мэты зразумелыя. І прынамсі, на той момант часу яны былі карысныя.

Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

У 2015 годзе ад гэтага ж паважанага інжынера прыходзіць новы патч. Ён вельмі цікавы. У ім гаворыцца наступнае — мы будзем рандамізаваць хэш у выпадку негатыўнай падзеі маршрутызацыі. Што такое негатыўная падзея маршрутызацыі? Гэта RTO, якое мы з вамі раней абмяркоўвалі, гэта значыць страта хваста акна - падзея, якое сапраўды негатыўнае. Праўда адносна складана здагадацца, што гэта менавіта яно.

Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

2016 год, іншая паважаная кампанія, таксама вялікая. Яна разбірае апошнія мыліцы і робіць так, што хэш, які мы раней зрабілі рандомізірованным, зараз змяняецца на кожны рэтрансміт SYN і пасля кожнага RTO таймаўту. І ў гэтым лісце ў першы і апошні раз гучыць канчатковая мэта - зрабіць так, каб трафік у выпадку ўзнікнення страт або перагрузкі каналаў меў магчымасць мяккай перамаршрутызацыі, выкарыстання мноства шляхоў. Вядома, пасля гэтага была маса публікацый, вы лёгка іх зможаце знайсці.

Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Хаця не, не зможаце, таму што ніводнай публікацыі на гэтую тэму не было. Але ж мы ведаем!

Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

І калі вы не да канца зразумелі, што ж было зроблена, я вам зараз раскажу.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Што ж было зроблена, якую функцыянальнасць дадалі ў ядро ​​Linux? txhash мяняецца на рандомнае значэнне пасля кожнай падзеі RTO. Гэты той самы негатыўны вынік маршрутызацыі. Хэш залежыць ад гэтага txhash, а flow label залежыць ад skb hash. Тут ёсць некаторыя выкладкі па функцый, на адзін слайд усе дэталі не змясціць. Калі камусьці цікава, можна прайсці па кодзе ядра і праверыць.

Што тут важна? Значэнне поля flow label мяняецца на выпадковы лік пасля кожнага RTO. Як гэта ўплывае на наш нешчаслівы TCP-струмень?
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

У выпадку ўзнікнення SACK нічога не змянілася, таму што мы спрабуем пераслаць вядомы страчаны пакет. Пакуль усё адносна добра.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Але ў выпадку RTO, пры ўмове, што мы дадалі flow label у хэш-функцыю на ToR, трафік можа пайсці іншым маршрутам. І чым больш плэйнаў, тым больш шанцаў, што ён знойдзе шлях, які не закрануць збоем на канкрэтнай прыладзе.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Застаецца адна праблема - RTO. Іншы маршрут, вядома, знаходзіцца, але вельмі шмат на гэта траціцца часу. 200 мс - гэта шмат. Секунда - гэта наогул дзікасць. Раней я расказваў пра таймаўты, якія настройваюць сэрвісы. Дык вось, секунда - гэта таймаўт, які звычайна наладжвае сэрвіс на ўзроўні прыкладання, і ў гэтым сэрвіс будзе нават адносна правоў. Прытым, што, паўтаруся, сапраўдны RTT усярэдзіне сучаснага дата-цэнтра – у раёне 1 мілісекунды.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Што можна зрабіць з RTO-таймаўтамі? Таймаўт, які адказвае за RTO у выпадку страты пакетаў з дадзенымі, адносна лёгка можна наладзіць з user space: ёсць утыліта IP, і ў адным з яе параметраў ёсць той самы rto_min. Улічваючы, што круціць RTO, безумоўна, трэба не глабальна, а для зададзеных прэфіксаў, такі механізм выглядае суцэль працоўным.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Праўда, з SYN_RTO усё крыху горш. Ён натуральна прыбіты цвікамі. У ядры зафіксавана значэнне - 1 секунда, і ўсё. З user space дацягнуцца туды нельга. Ёсць толькі адзін спосаб.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

На дапамогу прыходзіць eBPF. Калі казаць спрошчана, гэта невялікія праграмы на C. Іх можна ўставіць у хуки ў розных месцах выканання стэка ядра і TCP-стэка, з дапамогай якога можна змяняць вельмі вялікую колькасць налад. Наогул, eBPF – гэта доўгатэрміновы трэнд. Замест таго каб пілаваць дзясяткі новых параметраў sysctl і пашыраць утыліту IP, рух ідзе менавіта ў бок eBPF і пашырэнні яго функцыянальнасці. З дапамогай eBPF можна дынамічна змяняць congestion controls і іншыя разнастайныя налады TCP.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Але нам важна, што з дапамогай яго можна круціць значэнні SYN_RTO. Прычым ёсць публічна выкладзены прыклад: https://elixir.bootlin.com/linux/latest/source/samples/bpf/tcp_synrto_kern.c. Што тут зроблена? Прыклад працоўны, але сам па сабе вельмі грубіянскі. Тут мяркуецца, што ўсярэдзіне дата-цэнтра мы параўноўваем першыя 44 біта, калі яны супадаюць, значыць, мы апыняемся ўсярэдзіне ДЦ. І ў гэтым выпадку мы мяняем значэнне SYN_RTO timeout на 4ms. Тую ж самую задачу можна зрабіць куды хупавей. Але гэты просты прыклад паказвае, што такое а) магчыма; б) адносна проста.

Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Што мы ведаем? Што плейновая архітэктура дазваляе маштабавацца, яна аказваецца нам надзвычай карыснай, калі мы ўключаем flow label на ToR і атрымліваем магчымасць абцякаць праблемныя ўчасткі. Самы лепшы спосаб знізіць значэння RTO і SYN-RTO - выкарыстоўваць eBPF-праграмы. Застаецца пытанне: а ці бяспечна выкарыстоўваць flow label для балансавання? І тут ёсць нюанс.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Няхай у вас у сетцы ёсць сэрвіс, які жыве ў anycast. Нажаль, у мяне няма часу падрабязна распавядаць, што такое anycast, але гэта размеркаваны сэрвіс, розныя фізічныя серверы якога даступныя па адным і тым жа IP-адрасу. І тут магчымая праблема: падзея RTO можа ўзнікнуць не толькі пры праходжанні трафіку праз фабрыку. Яно можа ўзнікнуць і на ўзроўні буфера ToR: калі здараецца incast-падзея, яна можа ўзнікнуць нават на хасце, калі хост нешта пралівае. Калі адбываецца падзея RTO, і яна мяняе flow label. У гэтым выпадку трафік можа патрапіць на іншы anycast instance. Выкажам здагадку, гэта stateful anycast, ён трымае ў сабе connection state - гэта можа быць L3 Balancer ці яшчэ нейкі сэрвіс. Тады ўзнікае праблема, таму што пасля RTO TCP-злучэнне прылятае на сервер, які пра гэтае TCP-злучэнні нічога не ведае. І калі ў нас няма шэрагу стейтаў паміж anycast-серверамі, то такі трафік будзе скінуты і TCP-злучэнне парвецца.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Што тут можна зрабіць? Унутры вашага кантраляванага асяроддзя, дзе вы ўключаеце балансаванне flow label, неабходна фіксаваць значэнне flow label пры звароце да anycast-сервераў. Самы просты спосаб - зрабіць гэта праз тую ж eBPF-праграму. Але тут вельмі важны момант - што рабіць, калі вы аперуеце не сеткай дата-цэнтра, а з'яўляецеся аператарам сувязі? Гэта і ваша праблема таксама: пачынальна з вызначаных версій Juniper і Arista уключаюць flow label у хэш-функцыі па дэфолце шчыра кажучы, па незразумелай мне чынніку. Гэта можа прыводзіць да таго, што вы будзеце ірваць TCP-злучэнні карыстальнікаў, якія ідуць праз вашу сетку. Таму я настойліва рэкамендую праверыць наладкі вашых маршрутызатараў у гэтым месцы.

Так ці інакш, мне падаецца, што мы гатовы перайсці да эксперыментаў.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Калі мы ўключылі flow label на ToR, падрыхтавалі eBPF агента, які зараз жыве на хастах, мы вырашылі не чакаць наступнага вялікага збою, а правесці кантраляваныя выбухі. Мы ўзялі ToR, у якога чатыры аплінкі, і на адным з іх задаволілі дропы. Намалявалі правіла, сказалі - зараз ты губляеш усе пакеты. Як можна бачыць злева, у нас per-packet monitoring, які асеў да значэння 75%, гэта значыць 25% пакетаў губляюцца. Справа графікі сэрвісаў, якія жывуць за гэтым ToR. Па сутнасці гэта графікі трафіку стыкаў з серверамі ўнутры стойкі. Як можна бачыць, яны аселі нават ніжэй. Чаму яны аселі ніжэй - не на 25%, а ў некаторых выпадках у 3-4 разы? Калі TCP-злучэнні не шанцуе, яно працягвае спрабаваць дагрукацца праз біты стык. Гэта пагаршаецца тыпавымі паводзінамі сэрвісу ўнутры ДЦ – на адзін запыт карыстальніка генеруецца N запытаў да ўнутраных сэрвісаў, і адказ сыдзе да карыстача, альбо калі адкажуць усе крыніцы дадзеных, альбо калі спрацуе таймаўт на ўзроўні прыкладання, які яшчэ павінен быць наладжаны. Гэта значыць, усё вельмі і вельмі дрэнна.
Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Цяпер той жа самы эксперымент, але з уключаным значэннем flow label. Як мага бачыць, злева наш пакетны маніторынг асеў на тыя ж самыя 25%. Гэта абсалютна карэктна, таму што ён нічога не ведае аб рэтрансмітах, ён адпраўляе пакеты і проста лічыць стаўленне колькасці дастаўленых і страчаных пакетаў.

А справа знаходзіцца графік сервісаў. Вы тут не знойдзеце эфекту ад праблемнага стыку. Трафік за тыя самыя мілісекунды перацёк з праблемнага ўчастка ў тры аплінкі, якія не закранулі праблему. Мы атрымалі сетку, якая лечыць сябе сама.

Сетка, якая лечыць сябе сама: магія Flow Label і дэтэктыў вакол ядра Linux. Даклад Яндэкса

Гэта мой апошні слайд, час падвесці вынікі. Цяпер, я спадзяюся, вы ведаеце, як будаваць сетку дата-цэнтра, здольную да самалячэння. Вам не трэба будзе хадзіць па архіве ядра Linux і вышукваць тамака адмысловыя патчы, вы ведаеце, што Flow label у дадзеным выпадку вырашае праблему, але падыходзіць да гэтага механізму трэба асцярожна. І я яшчэ раз падкрэсліваю, што калі вы аператар сувязі, вы не павінны выкарыстоўваць flow label у якасці хэш-функцыі, інакш вы будзеце рваць сесіі вашых карыстальнікаў.

У сеткавых інжынераў павінен адбыцца канцэптуальны зрух: сетка пачынаецца не з ToR, не з сеткавай прылады, а з хаста. Досыць яркі прыклад - тое, як мы выкарыстоўваем eBPF і для змены RTO, і для фіксацыі flow label у бок anycast-сэрвісаў.

Механіка flow label, безумоўна, падыходзіць і для іншых ужыванняў усярэдзіне кантраляванага адміністрацыйнага сегмента. Гэта можа быць трафік паміж дата-цэнтрамі, а можна адмысловым спосабам выкарыстоўваць такую ​​механіку і для кіравання выходным трафікам. Але пра гэта я раскажу, спадзяюся, наступным разам. Дзякуй вялікі за ўвагу.

Крыніца: habr.com