కుబెర్నెటీస్‌తో జీవితం నుండి: HTTP సర్వర్ స్పెయిన్ దేశస్థులకు ఎలా అనుకూలంగా లేదు

కుబెర్నెటీస్‌తో జీవితం నుండి: HTTP సర్వర్ స్పెయిన్ దేశస్థులకు ఎలా అనుకూలంగా లేదు

మైక్రోసాఫ్ట్ క్లౌడ్ (అజూర్)లో అప్లికేషన్ స్టాక్ ఉన్న మా క్లయింట్ ప్రతినిధి సమస్యను పరిష్కరించారు: ఇటీవల, యూరప్ నుండి కొంతమంది క్లయింట్ల నుండి వచ్చిన కొన్ని అభ్యర్థనలు లోపం 400తో ముగియడం ప్రారంభించాయి (తప్పుడు విన్నపం) అన్ని అప్లికేషన్లు .NETలో వ్రాయబడ్డాయి, కుబెర్నెట్స్‌లో అమలు చేయబడ్డాయి...

అప్లికేషన్‌లలో ఒకటి API, దీని ద్వారా అన్ని ట్రాఫిక్ అంతిమంగా వస్తుంది. ఈ ట్రాఫిక్ HTTP సర్వర్ ద్వారా వినబడుతుంది కెస్ట్రెల్, .NET క్లయింట్ ద్వారా కాన్ఫిగర్ చేయబడింది మరియు పాడ్‌లో హోస్ట్ చేయబడింది. డీబగ్గింగ్‌తో, సమస్యను స్థిరంగా పునరుత్పత్తి చేసే నిర్దిష్ట వినియోగదారు ఉన్నారనే అర్థంలో మేము అదృష్టవంతులం. అయితే, ట్రాఫిక్ చైన్ ద్వారా ప్రతిదీ సంక్లిష్టంగా ఉంది:

కుబెర్నెటీస్‌తో జీవితం నుండి: HTTP సర్వర్ స్పెయిన్ దేశస్థులకు ఎలా అనుకూలంగా లేదు

ప్రవేశంలో లోపం ఇలా కనిపించింది:

{
   "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":{}
}

అదే సమయంలో, Kestrel ఇచ్చింది:

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 నగరం లేదని ఊహించడం సులభం (కానీ ఉంది మాలాగా) ఈ ఆలోచనను స్వీకరించడం ద్వారా, మేము ఇన్‌గ్రెస్ కాన్ఫిగర్‌లను చూశాము, అక్కడ మేము ఒక నెల క్రితం చొప్పించినదాన్ని చూశాము (క్లయింట్ అభ్యర్థన మేరకు) "హాని లేని" స్నిప్పెట్:

    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;

ఈ హెడర్‌ల ఫార్వార్డింగ్‌ని డిసేబుల్ చేసిన తర్వాత, అంతా బాగానే ఉంది! (అప్లికేషన్‌కు ఇకపై ఈ శీర్షికలు అవసరం లేదని త్వరలో స్పష్టమైంది.)

ఇప్పుడు సమస్య చూద్దాం సాధారణంగా. టెల్‌నెట్ అభ్యర్థన చేయడం ద్వారా అప్లికేషన్ లోపల దీన్ని సులభంగా పునరుత్పత్తి చేయవచ్చు 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

ఒక వ్యాఖ్యను జోడించండి