Аз ҳаёт бо Кубернетес: Чӣ гуна сервери HTTP ба испаниҳо маъқул набуд

Аз ҳаёт бо Кубернетес: Чӣ гуна сервери HTTP ба испаниҳо маъқул набуд

Намояндаи муштарии мо, ки стеки замимаҳои он дар абри Microsoft (Azure) ҷойгир аст, ба мушкилот муроҷиат кард: ба наздикӣ, баъзе дархостҳо аз баъзе муштариён аз Аврупо бо хатогии 400 (Дархости ганда). Ҳама барномаҳо дар .NET навишта шудаанд ва дар Kubernetes ҷойгир шудаанд...

Яке аз барномаҳо API мебошад, ки тавассути он тамоми трафик дар ниҳоят меояд. Ин трафикро сервери HTTP гӯш мекунад Кестрел, аз ҷониби муштарии .NET конфигуратсияшуда ва дар як pod ҷойгир карда шудааст. Бо ислоҳи ислоҳ, мо хушбахт будем, ки корбари мушаххасе вуҷуд дошт, ки мушкилотро пайваста дубора тавлид мекард. Бо вуҷуди ин, ҳама чиз бо занҷири трафик мураккаб буд:

Аз ҳаёт бо Кубернетес: Чӣ гуна сервери HTTP ба испаниҳо маъқул набуд

Хатогӣ дар Ingress чунин менамуд:

{
   "number_fields":{
      "status":400,
      "request_time":0.001,
      "bytes_sent":465,
      "upstream_response_time":0,
      "upstream_retries":0,
      "bytes_received":2328
   },
   "stream":"stdout",
   "string_fields":{
      "ingress":"app",
      "protocol":"HTTP/1.1",
      "request_id":"f9ab8540407208a119463975afda90bc",
      "path":"/api/sign-in",
      "nginx_upstream_status":"400",
      "service":"app",
      "namespace":"production",
      "location":"/front",
      "scheme":"https",
      "method":"POST",
      "nginx_upstream_response_time":"0.000",
      "nginx_upstream_bytes_received":"120",
      "vhost":"api.app.example.com",
      "host":"api.app.example.com",
      "user":"",
      "address":"83.41.81.250",
      "nginx_upstream_addr":"10.240.0.110:80",
      "referrer":"https://api.app.example.com/auth/login?long_encrypted_header",
      "service_port":"http",
      "user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
      "time":"2019-03-06T18:29:16+00:00",
      "content_kind":"cache-headers-not-present",
      "request_query":""
   },
   "timestamp":"2019-03-06 18:29:16",
   "labels":{
      "app":"nginx",
      "pod-template-generation":"6",
      "controller-revision-hash":"1682636041"
   },
   "namespace":"kube-nginx-ingress",
   "nsec":6726612,
   "source":"kubernetes",
   "host":"k8s-node-55555-0",
   "pod_name":"nginx-v2hcb",
   "container_name":"nginx",
   "boolean_fields":{}
}

Дар баробари ин Кестрел дод:

HTTP/1.1 400 Bad Request
Connection: close
Date: Wed, 06 Mar 2019 12:34:20 GMT
Server: Kestrel
Content-Length: 0

Ҳатто бо ҳадди аксар, хатогии Kestrel хеле зиёд буд маълумоти каме муфид:

{
   "number_fields":{"ThreadId":76},
   "stream":"stdout",
   "string_fields":{
      "EventId":"{"Id"=>17, "Name"=>"ConnectionBadRequest"}",
      "SourceContext":"Microsoft.AspNetCore.Server.Kestrel",
      "ConnectionId":"0HLL2VJSST5KV",
      "@mt":"Connection id "{ConnectionId}" bad request data: "{message}"",
      "@t":"2019-03-07T13:06:48.1449083Z",
      "@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()",
      "message":"Malformed request: invalid headers."
   },
   "timestamp":"2019-03-07 13:06:48",
   "labels":{
      "pod-template-hash":"2368795483",
      "service":"app"
   },
   "namespace":"production",
   "nsec":145341848,
   "source":"kubernetes",
   "host":"k8s-node-55555-1",
   "pod_name":"app-67bdcf98d7-mhktx",
   "container_name":"app",
   "boolean_fields":{}
}

Чунин ба назар мерасад, ки танҳо tcpdump ба ҳалли ин мушкилот кӯмак мекунад, аммо ман дар бораи занҷири трафик такрор мекунам:

Аз ҳаёт бо Кубернетес: Чӣ гуна сервери HTTP ба испаниҳо маъқул набуд

Тафтиш

Аён аст, ки ба ҳаракати нақлиёт гӯш додан беҳтар аст дар он гиреҳи мушаххас, ки дар он Кубернетес подкастро ҷойгир кардааст: ҳаҷми партовҳо чунон хоҳад буд, ки ҳадди аққал чизеро зуд пайдо кардан мумкин аст. Ва дар хакикат, хангоми тахкики он чорчубаи зерин мушохида шуд:

GET /back/user HTTP/1.1
Host: api.app.example.com
X-Request-ID: 27ceb14972da8c21a8f92904b3eff1e5
X-Real-IP: 83.41.81.250
X-Forwarded-For: 83.41.81.250
X-Forwarded-Host: api.app.example.com
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Original-URI: /front/back/user
X-Scheme: https
X-Original-Forwarded-For: 83.41.81.250
X-Nginx-Geo-Client-Country: Spain
X-Nginx-Geo-Client-City: M.laga
Accept-Encoding: gzip
CF-IPCountry: ES
CF-RAY: 4b345cfd1c4ac691-MAD
CF-Visitor: {"scheme":"https"}
pragma: no-cache
cache-control: no-cache
accept: application/json, text/plain, */*
origin: https://app.example.com
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36
referer: https://app.example.com/auth/login
accept-language: en-US,en;q=0.9,en-GB;q=0.8,pl;q=0.7
cookie: many_encrypted_cookies; .AspNetCore.Identity.Application=something_encrypted; 
CF-Connecting-IP: 83.41.81.250
True-Client-IP: 83.41.81.250
CDN-Loop: cloudflare

HTTP/1.1 400 Bad Request
Connection: close
Date: Wed, 06 Mar 2019 12:34:20 GMT
Server: Kestrel
Content-Length: 0

Хангоми бодиккат аз назар гузарондани партовгох калом пай бурд M.laga. Тахмин кардан осон аст, ки дар Испания ягон шаҳри M.laga вуҷуд надорад (аммо вуҷуд дорад Málaga). Бо назардошти ин идея, мо ба конфигуратсияҳои Ingress назар кардем, ки дар он конфигуратсияи як моҳ пеш гузошташударо дидем (бо дархости муштарӣ) порчаи "безарар":

    ingress.kubernetes.io/configuration-snippet: |
      proxy_set_header X-Nginx-Geo-Client-Country $geoip_country_name;
      proxy_set_header X-Nginx-Geo-Client-City $geoip_city;

Пас аз ғайрифаъол кардани интиқоли ин сарлавҳаҳо, ҳама чиз хуб шуд! (Ба зудӣ маълум шуд, ки худи барнома дигар ба ин сарлавҳаҳо ниёз надорад.)

Акнун биёед ба мушкилот назар андозем умуман бештар. Онро дар дохили барнома тавассути дархости telnet ба осонӣ дубора тавлид кардан мумкин аст localhost:80:

GET /back/user HTTP/1.1
Host: api.app.example.com
cache-control: no-cache
accept: application/json, text/plain, */*
origin: https://app.example.com
Cookie: test=Desiree

... бармегардад 401 Unauthorized, чунон ки интизор мерафт. Чӣ мешавад, агар мо кунем:

GET /back/user HTTP/1.1
Host: api.app.example.com
cache-control: no-cache
accept: application/json, text/plain, */*
origin: https://app.example.com
Cookie: test=Désirée

?

бармегардад 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 дар барномаро ба нақша нагирифтааст. Аммо, мушкилот дар худи AspNetCore (№4318, №7707) мегуянд, ки ин кумак намекунад...

Хулоса: ёддошт дигар на дар бораи мушкилоти мушаххаси Kestrel ё UTF-8 (дар соли 2019?!), балки дар бораи он аст, ки шуурнокй ва омӯзиши пайваста Ҳар як қадами шумо ҳангоми ҷустуҷӯи мушкилот дер ё зуд самар хоҳад дод. Барори кор!

PS

Инчунин дар блоги мо хонед:

Манбаъ: will.com

Илова Эзоҳ