Кубернетестэй хийсэн амьдралаас: HTTP сервер Испаничуудад хэрхэн таалагдаагүй вэ?

Кубернетестэй хийсэн амьдралаас: HTTP сервер Испаничуудад хэрхэн таалагдаагүй вэ?

Майкрософт (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. Испанид М.лага хот байдаггүйг таахад амархан (гэхдээ байдаг Малага). Энэ санааг олж авснаар бид нэг сарын өмнө оруулсан (үйлчлүүлэгчийн хүсэлтээр) 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 чадахгүй байна нэлээд олон тооны хотын нэрэнд агуулагдах UTF-8 дахь зөв тэмдэгтүүд бүхий HTTP толгойг зөв боловсруулах.

Манай тохиолдолд нэмэлт хүчин зүйл бол үйлчлүүлэгч одоогоор програм дахь Kestrel-ийн хэрэгжилтийг өөрчлөхөөр төлөвлөөгүй байгаа явдал юм. Гэсэн хэдий ч AspNetCore-ийн асуудал (Үгүй. 4318, Үгүй. 7707) энэ нь тус болохгүй гэж тэд хэлдэг ...

Дүгнэж хэлэхэд: тэмдэглэл нь Kestrel эсвэл UTF-8-ийн тодорхой асуудлуудын тухай биш (2019 онд ?!) анхаарал, тууштай судлах Асуудлыг хайж байхдаа хийх алхам бүр чинь эрт орой хэзээ нэгэн цагт үр дүнгээ өгөх болно. Амжилт хүсье!

PS

Мөн манай блог дээрээс уншина уу:

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх