З жыцця з Kubernetes: Як HTTP-сервер іспанцаў не дараваў
Прадстаўнік нашага кліента, стэк прыкладанняў якога насяляе ў воблаку ад Microsoft (Azure), звярнуўся з праблемай: з нядаўняга часу частка запытаў некаторых кліентаў з Еўропы стала завяршацца памылкай 400 (Дрэнны запыт). Усе прыкладанні напісаны на .NET, разгорнутыя ў Kubernetes…
Адно з прыкладанняў – API, праз які ў канчатковым рахунку прыходзіць увесь трафік. Гэты трафік слухае HTTP-сервер пустальга, сканфігураваны кліентам. NET і размешчаны ў pod'е. З адладкай нам павезла ў тым сэнсе, што быў пэўны карыстач, у якога стабільна прайгравалася праблема. Аднак усё ўскладнялася ланцужком трафіку:
Здавалася б, толькі tcpdump дапаможа ў рашэнні гэтай праблемы… але паўтару пра ланцужок трафіку:
расследаванне
Відавочна, што паслухаць трафік лепш на тым канкрэтным вузле, дзе Kubernetes разгарнуў pod: аб'ём дампа будзе такі, што атрымаецца даволі хутка знайсці хоць нешта. І сапраўды, пры яго разглядзе быў заўважаны такі фрэйм:
Пры ўважлівым разглядзе дампа было заўважана слова M.laga. Лёгка здагадацца, што ў Іспаніі няма горада M.laga (затое ёсць малага). Ухапіўшыся за гэтую ідэю, мы паглядзелі канфігі Ingress, дзе ўбачылі устаўлены месяц таму (па запыце кліента) бяскрыўдны snippet:
Пры адключэнні пракіду гэтых загалоўкаў усё стала добра! (Неўзабаве і зусім высветлілася, што гэтыя загалоўкі самому з дадаткам больш не патрабаваліся.)
Цяпер паглядзім на праблему у больш агульным выглядзе. Яе лёгка прайграць ўнутры прыкладання, калі зрабіць telnet-запыт на localhost:80:
Вернецца 400 Bad request - У логу прыкладання атрымаем ужо знаёмую нам памылку:
{
"@t":"2019-03-31T12:59:54.3746446Z",
"@mt":"Connection id "{ConnectionId}" bad request data: "{message}"",
"@x":"Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Malformed request: invalid headers.n at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)n at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.<ProcessRequestsAsync>d__185`1.MoveNext()",
"ConnectionId":"0HLLLR1J974L9",
"message":"Malformed request: invalid headers.",
"EventId":{
"Id":17,
"Name":"ConnectionBadRequest"
},
"SourceContext":"Microsoft.AspNetCore.Server.Kestrel",
"ThreadId":71
}
Вынікі
Канкрэтна Kestrel не можа карэктна апрацоўваць HTTP-загалоўкі з правільнымі сімваламі ў UTF-8, якія змяшчаюцца ў назвах даволі вялікай колькасці гарадоў.
Дадатковы фактар у нашым выпадку - змяняць рэалізацыю Kestrel у дадатку кліент у дадзены момант не плануе. Зрэшты, issues у самім AspNetCore (№ 4318, № 7707) кажуць аб тым, што гэта і не дапаможа…
Падагульняючы: нататка больш не пра спецыфічныя праблемы Kestrel або UTF-8 (у 2019 годзе?!), а пра тое, што уважлівасць і паслядоўнае вывучэнне кожнага кроку падчас пошуку праблемы рана ці позна прынясуць свой плён. Поспехаў!