Övervaka ett mikrotjänstprogram i AKS

Azure Monitor
Azure Kubernetes Service (AKS)

I den här artikeln beskrivs metodtips för övervakning av ett mikrotjänstprogram som körs på Azure Kubernetes Service (AKS). Specifika ämnen omfattar telemetrisamling, övervakning av ett klusters status, mått, loggning, strukturerad loggning och distribuerad spårning. Det senare illustreras i det här diagrammet:

Diagram that shows the architecture of a drone delivery application.

Ladda ned en Visio-fil med den här arkitekturen.

Telemetrisamling

I alla komplexa program kommer något att gå fel någon gång. I ett mikrotjänstprogram måste du spåra vad som händer i dussintals eller till och med hundratals tjänster. För att förstå vad som händer måste du samla in telemetri från programmet. Telemetri kan delas in i följande kategorier: loggar, spårningar och mått.

Loggar är textbaserade poster för händelser som inträffar när ett program körs. De omfattar saker som programloggar (spårningsinstruktioner) och webbserverloggar. Loggar är främst användbara för kriminalteknik och rotorsaksanalys.

Spårningar, som även kallas åtgärder, ansluter stegen i en enskild begäran över flera anrop inom och mellan mikrotjänster. De kan ge strukturerad observerbarhet i interaktionen mellan systemkomponenter. Spårningar kan börja tidigt i begärandeprocessen, till exempel i användargränssnittet för ett program, och kan spridas via nätverkstjänster i ett nätverk med mikrotjänster som hanterar begäran.

  • Intervall är arbetsenheter i en spårning. Varje spann är anslutet med en enda spårning och kan kapslas med andra intervall. De motsvarar ofta enskilda begäranden i en korstjänståtgärd, men de kan också definiera arbete i enskilda komponenter i en tjänst. Spans spårar även utgående samtal från en tjänst till en annan. (Intervall kallas ibland beroendeposter.)

Mått är numeriska värden som kan analyseras. Du kan använda dem för att observera ett system i realtid (eller nära realtid) eller för att analysera prestandatrender över tid. För att förstå ett system holistiskt måste du samla in mått på olika nivåer i arkitekturen, från den fysiska infrastrukturen till programmet, inklusive:

  • Mått på nodnivå , inklusive processor-, minnes-, nätverks-, disk- och filsystemanvändning. Systemmått hjälper dig att förstå resursallokering för varje nod i klustret och felsöka avvikande värden.

  • Containermått . För containerbaserade program måste du samla in mått på containernivå, inte bara på vm-nivå.

  • Programmått . Dessa mått är relevanta för att förstå beteendet för en tjänst. Exempel är antalet inkommande HTTP-begäranden i kö, svarstid för begäranden och längden på meddelandeköer. Program kan också använda anpassade mått som är specifika för domänen, till exempel antalet affärstransaktioner som bearbetas per minut.

  • Beroende tjänstmått . Tjänster anropar ibland externa tjänster eller slutpunkter, till exempel hanterade PaaS- eller SaaS-tjänster. Tjänster från tredje part kanske inte tillhandahåller mått. Om de inte gör det måste du förlita dig på dina egna programmått för att spåra statistik för svarstid och felfrekvens.

Övervaka klusterstatus

Använd Azure Monitor för att övervaka hälsotillståndet för dina kluster. Följande skärmbild visar ett kluster som har kritiska fel i användardistribuerade poddar:

Screenshot that shows the Monitor dashboard.

Härifrån kan du öka detaljnivån ytterligare för att hitta problemet. Om poddstatusen till exempel är ImagePullBackoffkunde Kubernetes inte hämta containeravbildningen från registret. Det här problemet kan orsakas av en ogiltig containertagg eller ett autentiseringsfel under en hämtning från registret.

Om en container kraschar blir Waitingcontainern State , med en Reason av CrashLoopBackOff. I ett typiskt scenario, där en podd är en del av en replikuppsättning och återförsöksprincipen är Always, visas inte det här problemet som ett fel i klusterstatusen. Du kan dock köra frågor eller konfigurera aviseringar för det här villkoret. Mer information finns i Förstå AKS-klusterprestanda med Azure Monitor Container Insights.

Det finns flera containerspecifika arbetsböcker i fönstret arbetsböcker för en AKS-resurs. Du kan använda dessa arbetsböcker för en snabb översikt, felsökning, hantering och insikter. Följande skärmbild visar en lista över arbetsböcker som är tillgängliga som standard för AKS-arbetsbelastningar.

Screenshot that shows the workbooks for an AKS resource.

Mått

Vi rekommenderar att du använder Monitor för att samla in och visa mått för dina AKS-kluster och andra beroende Azure-tjänster.

  • För kluster- och containermått aktiverar du Azure Monitor Container Insights. När den här funktionen är aktiverad samlar Monitor in minnes- och processormått från styrenheter, noder och containrar via Kubernetes Metrics API. Mer information om de mått som är tillgängliga från Container Insights finns i Förstå AKS-klusterprestanda med Azure Monitor Container Insights.

  • Använd Application Insights för att samla in programmått. Application Insights är en utökningsbar tjänst för programprestandahantering (APM). Om du vill använda det installerar du ett instrumentationspaket i ditt program. Det här paketet övervakar appen och skickar telemetridata till Application Insights. Den kan också hämta telemetridata från värdmiljön. Data skickas sedan till Monitor. Application Insights tillhandahåller också inbyggd korrelations- och beroendespårning. (Se Distribuerad spårning senare i den här artikeln.)

Application Insights har ett maximalt dataflöde som mäts i händelser per sekund och begränsar telemetri om datahastigheten överskrider gränsen. Mer information finns i Application Insights-gränser. Skapa olika Application Insights-instanser för varje miljö så att utvecklings-/testmiljöer inte konkurrerar med produktionstelemetrin om kvoten.

En enda åtgärd kan generera många telemetrihändelser, så om ett program upplever en hög trafikvolym kommer telemetriinsamlingen sannolikt att begränsas. För att åtgärda det här problemet kan du utföra sampling för att minska telemetritrafiken. Kompromissen är att dina mått blir mindre exakta, såvida inte instrumentationen stöder föraggregering. I så fall kommer det att finnas färre spårningsexempel för felsökning, men måtten bibehåller noggrannheten. Mer information finns i Sampling i Application Insights. Du kan också minska datavolymen genom att föraggregera mått. Du kan alltså beräkna statistiska värden, till exempel medelvärdet och standardavvikelsen, och skicka dessa värden i stället för råtelemetri. Det här blogginlägget beskriver en metod för att använda Application Insights i stor skala: Azure Monitoring and Analytics i stor skala.

Om datahastigheten är tillräckligt hög för att utlösa begränsning och sampling eller aggregering inte är acceptabel kan du överväga att exportera mått till en tidsseriedatabas, till exempel Azure Data Explorer, Prometheus eller InfluxDB, som körs i klustret.

  • Azure Data Explorer är en Azure-intern, mycket skalbar datautforskningstjänst för logg- och telemetridata. Den har stöd för flera dataformat, ett omfattande frågespråk och anslutningar för användning av data i populära verktyg som Jupyter Notebooks och Grafana. Azure Data Explorer har inbyggda anslutningsappar för att mata in logg- och måttdata via Azure Event Hubs. Mer information finns i Mata in och fråga efter övervakningsdata i Azure Data Explorer.

  • InfluxDB är ett push-baserat system. En agent måste push-överföra måtten. Du kan använda TICK-stacken för att konfigurera övervakningen av Kubernetes. Därefter kan du skicka mått till InfluxDB med hjälp av Telegraf, som är en agent för att samla in och rapportera mått. Du kan använda InfluxDB för oregelbundna händelser och strängdatatyper.

  • Prometheus är ett pull-baserat system. Den skrapar regelbundet mått från konfigurerade platser. Prometheus kan skrapa mått som genereras av Azure Monitor eller kube-state-metrics. kube-state-metrics är en tjänst som samlar in mått från Kubernetes API-servern och gör dem tillgängliga för Prometheus (eller en skrapa som är kompatibel med en Prometheus-klientslutpunkt). För systemmått använder du nodexportören, som är en Prometheus-exportör för systemmått. Prometheus stöder flyttalsdata men inte strängdata, så det är lämpligt för systemmått men inte loggar. Kubernetes Metrics Server är en klusteromfattande sammansättning av resursanvändningsdata.

Loggning

Här är några av de allmänna utmaningarna med loggning i ett mikrotjänstprogram:

  • Förstå bearbetningen från slutpunkt till slutpunkt för en klientbegäran, där flera tjänster kan anropas för att hantera en enda begäran.
  • Konsolidera loggar från flera tjänster till en enda aggregerad vy.
  • Parsningsloggar som kommer från flera källor som använder sina egna loggningsscheman eller som inte har något särskilt schema. Loggar kan genereras av komponenter från tredje part som du inte styr.
  • Mikrotjänstarkitekturer genererar ofta en större mängd loggar än traditionella monoliter eftersom det finns fler tjänster, nätverksanrop och steg i en transaktion. Det innebär att själva loggningen kan vara en prestanda- eller resursflaskhals för programmet.

Det finns några ytterligare utmaningar för Kubernetes-baserade arkitekturer:

  • Containrar kan flyttas runt och schemaläggas om.
  • Kubernetes har en nätverksabstraktion som använder virtuella IP-adresser och portmappningar.

I Kubernetes är standardmetoden för loggning att en container skriver loggar till stdout och stderr. Containermotorn omdirigerar dessa strömmar till en loggningsdrivrutin. För att göra frågan enklare och för att förhindra eventuell förlust av loggdata om en nod slutar svara är den vanliga metoden att samla in loggarna från varje nod och skicka dem till en central lagringsplats.

Azure Monitor integreras med AKS för att stödja den här metoden. Monitor samlar in containerloggar och skickar dem till en Log Analytics-arbetsyta. Därifrån kan du använda Kusto-frågespråk för att skriva frågor i de aggregerade loggarna. Här är till exempel en Kusto-fråga för att visa containerloggarna för en angiven podd:

ContainerLogV2
| where PodName == "podName" //update with target pod
| project TimeGenerated, Computer, ContainerId, LogMessage, LogSource

Azure Monitor är en hanterad tjänst och att konfigurera ett AKS-kluster för att använda Monitor är en enkel konfigurationsändring i CLI- eller Azure Resource Manager-mallen. (Mer information finns i Så här aktiverar du Azure Monitor Container Insights.) En annan fördel med att använda Azure Monitor är att den konsoliderar dina AKS-loggar med andra Azure-plattformsloggar för att ge en enhetlig övervakningsupplevelse.

Azure Monitor debiteras per gigabyte (GB) data som matas in i tjänsten. (Se Prissättning för Azure Monitor.) Vid höga volymer kan kostnaden bli ett övervägande. Det finns många alternativ med öppen källkod för Kubernetes-ekosystemet. Många organisationer använder till exempel Fluentd med Elasticsearch. Fluentd är en datainsamlare med öppen källkod och Elasticsearch är en dokumentdatabas som används för sökning. En utmaning med dessa alternativ är att de kräver extra konfiguration och hantering av klustret. För en produktionsarbetsbelastning kan du behöva experimentera med konfigurationsinställningar. Du måste också övervaka prestanda för loggningsinfrastrukturen.

OpenTelemetry

OpenTelemetry är ett branschöverskridande arbete för att förbättra spårningen genom att standardisera gränssnittet mellan program, bibliotek, telemetri och datainsamlare. När du använder ett bibliotek och ramverk som är instrumenterade med OpenTelemetry hanteras det mesta av arbetet med spårningsåtgärder som traditionellt är systemåtgärder av de underliggande biblioteken, som innehåller följande vanliga scenarier:

  • Loggning av grundläggande begärandeåtgärder, till exempel starttid, sluttid och varaktighet
  • Undantag som utlöses
  • Kontextspridning (som att skicka ett korrelations-ID över HTTP-anropsgränser)

I stället skapar de basbibliotek och ramverk som hanterar dessa åtgärder omfattande sammanhängande spann och spårar datastrukturer och sprider dem över kontexter. Före OpenTelemetry injicerades dessa vanligtvis bara som särskilda loggmeddelanden eller som proprietära datastrukturer som var specifika för leverantören som skapade övervakningsverktygen. OpenTelemetry uppmuntrar också till en mer omfattande instrumentationsdatamodell än en traditionell loggningsmetod, och loggarna är mer användbara eftersom loggmeddelandena är länkade till de spårningar och intervall där de genererades. Detta gör det ofta enkelt att hitta loggar som är associerade med en specifik åtgärd eller begäran.

Många av Azure SDK:erna har instrumenterats med OpenTelemetry eller håller på att implementera den.

En programutvecklare kan lägga till manuell instrumentering med hjälp av OpenTelemetry SDK:er för att utföra följande aktiviteter:

  • Lägg till instrumentation där ett underliggande bibliotek inte tillhandahåller den.
  • Utöka spårningskontexten genom att lägga till intervall för att exponera programspecifika arbetsenheter (till exempel en orderloop som skapar ett intervall för bearbetning av varje orderrad).
  • Utöka befintliga intervall med entitetsnycklar för att möjliggöra enklare spårning. (Lägg till exempel till en OrderID-nyckel/värde i begäran som bearbetar ordern.) Dessa nycklar visas av övervakningsverktygen som strukturerade värden för frågor, filtrering och aggregering (utan att parsa ut loggmeddelandesträngar eller leta efter kombinationer av loggmeddelandesekvenser, vilket var vanligt med en loggnings-första metod).
  • Sprid spårningskontext genom att komma åt spårnings- och span-attribut, mata in traceIds i svar och nyttolaster och/eller läsa traceIds från inkommande meddelanden för att skapa begäranden och intervall.

Läs mer om instrumentation och OpenTelemetry SDK:er i dokumentationen om OpenTelemetry.

Programinsikter

Application Insights samlar in omfattande data från OpenTelemetry och dess instrumentationsbibliotek och samlar in dem i ett effektivt datalager för att ge omfattande visualisering och frågestöd. Application Insights OpenTelemetry-baserade instrumentationsbibliotek för språk som .NET, Java, Node.js och Python gör det enkelt att skicka telemetridata till Application Insights.

Om du använder .NET Core rekommenderar vi att du även överväger Application Insights för Kubernetes-biblioteket . Det här biblioteket berikar Application Insights-spårningar med ytterligare information, till exempel containern, noden, podden, etiketterna och replikuppsättningen.

Application Insights mappar OpenTelemetry-kontexten till sin interna datamodell:

  • Spårning –> åtgärd
  • Spårnings-ID –> åtgärds-ID
  • Span –> begäran eller beroende

Ta hänsyn till följande:

  • Application Insights begränsar telemetrin om datahastigheten överskrider en maximal gräns. Mer information finns i Application Insights-gränser. En enda åtgärd kan generera flera telemetrihändelser, så om ett program upplever en hög trafikvolym begränsas den sannolikt.
  • Eftersom Application Insights batchar data kan du förlora en batch om en process misslyckas med ett ohanterat undantag.
  • Application Insights-fakturering baseras på datavolym. Mer information finns i Hantera priser och datavolym i Application Insights.

Strukturerad loggning

Om du vill göra loggarna enklare att parsa använder du strukturerad loggning när du kan. När du använder strukturerad loggning skriver programmet loggar i ett strukturerat format, till exempel JSON, i stället för att mata ut ostrukturerade textsträngar. Det finns många strukturerade loggningsbibliotek tillgängliga. Här är till exempel en loggningsuttryck som använder Serilog-biblioteket för .NET Core:

public async Task<IActionResult> Put([FromBody]Delivery delivery, string id)
{
    logger.LogInformation("In Put action with delivery {Id}: {@DeliveryInfo}", id, delivery.ToLogInfo());

    ...
}

Här innehåller anropet till LogInformation en Id parameter och DeliveryInfo parameter. När du använder strukturerad loggning interpoleras inte dessa värden i meddelandesträngen. Loggutdata ser i stället ut ungefär så här:

{"@t":"2019-06-13T00:57:09.9932697Z","@mt":"In Put action with delivery {Id}: {@DeliveryInfo}","Id":"36585f2d-c1fa-4a3d-9e06-a7f40b7d04ef","DeliveryInfo":{...

Det här är en JSON-sträng, där @t fältet är en tidsstämpel, @mt är meddelandesträngen och de återstående nyckel-/värdeparen är parametrarna. Genom att mata ut JSON-format blir det enklare att köra frågor mot data på ett strukturerat sätt. Till exempel söker följande Log Analytics-fråga, skriven i Kusto-frågespråket, efter instanser av det här meddelandet från alla containrar med namnet fabrikam-delivery:

traces
| where customDimensions.["Kubernetes.Container.Name"] == "fabrikam-delivery"
| where customDimensions.["{OriginalFormat}"] == "In Put action with delivery {Id}: {@DeliveryInfo}"
| project message, customDimensions["Id"], customDimensions["@DeliveryInfo"]

Om du visar resultatet i Azure-portalen kan du se att det DeliveryInfo är en strukturerad post som innehåller den serialiserade representationen DeliveryInfo av modellen:

Screenshot that shows the Log Analytics workspace.

Här är JSON från det här exemplet:

{
  "Id": "36585f2d-c1fa-4a3d-9e06-a7f40b7d04ef",
  "Owner": {
    "UserId": "user id for logging",
    "AccountId": "52dadf0c-0067-43e7-af76-86e32b48bc5e"
  },
  "Pickup": {
    "Altitude": 0.29295161612934972,
    "Latitude": 0.26815900219052985,
    "Longitude": 0.79841844309047727
  },
  "Dropoff": {
    "Altitude": 0.31507750848078986,
    "Latitude": 0.753494655598651,
    "Longitude": 0.89352830773849423
  },
  "Deadline": "string",
  "Expedited": true,
  "ConfirmationRequired": 0,
  "DroneId": "AssignedDroneId01ba4d0b-c01a-4369-ba75-51bde0e76cc9"
}

Många loggmeddelanden markerar början eller slutet av en arbetsenhet, eller så ansluter de en affärsentitet med en uppsättning meddelanden och åtgärder för spårning. I många fall är berikande OpenTelemetry-span- och begärandeobjekt en bättre metod än att bara logga starten och slutet av åtgärden. När du gör det läggs kontexten till i alla anslutna spårningar och underordnade åtgärder, och den informationen placeras i omfånget för den fullständiga åtgärden. OpenTelemetry SDK:er för olika språk har stöd för att skapa intervall eller lägga till anpassade attribut i intervall. Följande kod använder till exempel Java OpenTelemetry SDK, som stöds av Application Insights. Ett befintligt överordnat spann (till exempel ett begärandeintervall som är associerat med ett REST-kontrollantanrop och som skapats av det webbramverk som används) kan utökas med ett entitets-ID som är associerat med det, som du ser här:

import io.opentelemetry.api.trace.Span;

// ...

Span.current().setAttribute("A1234", deliveryId);

Den här koden anger en nyckel eller ett värde för det aktuella intervallet, som är anslutet till åtgärder och loggmeddelanden som inträffar under det intervallet. Värdet visas i Application Insights-begärandeobjektet, som du ser här:

requests
| extend deliveryId = tostring(customDimensions.deliveryId)  // promote to column value (optional)
| where deliveryId == "A1234"
| project timestamp, name, url, success, resultCode, duration, operation_Id, deliveryId

Den här tekniken blir mer kraftfull när den används med loggar, filtrering och anteckning av loggspårningar med spännviddskontext, som du ser här:

requests
| extend deliveryId = tostring(customDimensions.deliveryId)  // promote to column value (optional)
| where deliveryId == "A1234"
| project deliveryId, operation_Id, requestTimestamp = timestamp, requestDuration = duration  // keep some request info
| join kind=inner traces on operation_Id   // join logs only for this deliveryId
| project requestTimestamp, requestDuration, logTimestamp = timestamp, deliveryId, message

Om du använder ett bibliotek eller ramverk som redan har instrumenterats med OpenTelemetry hanterar det att skapa intervall och begäranden, men programkoden kan också skapa arbetsenheter. Till exempel kan en metod som loopar genom en matris med entiteter som utför arbete på var och en skapa ett spann för varje iteration av bearbetningsloopen. Information om hur du lägger till instrumentation i program- och bibliotekskod finns i dokumentationen om OpenTelemery-instrumentation.

Distribuerad spårning

En av utmaningarna när du använder mikrotjänster är att förstå flödet av händelser mellan tjänster. En enskild transaktion kan omfatta anrop till flera tjänster.

Exempel på distribuerad spårning

I det här exemplet beskrivs sökvägen för en distribuerad transaktion via en uppsättning mikrotjänster. Exemplet baseras på ett drönarleveransprogram.

Diagram that shows the architecture of a drone delivery application.

I det här scenariot innehåller den distribuerade transaktionen följande steg:

  1. Inmatningstjänsten placerar ett meddelande i en Azure Service Bus-kö.
  2. Arbetsflödestjänsten hämtar meddelandet från kön.
  3. Arbetsflödestjänsten anropar tre serverdelstjänster för att bearbeta begäran (Drone Scheduler, Package och Delivery).

Följande skärmbild visar programkartan för drönarleveransprogrammet. Den här kartan visar anrop till den offentliga API-slutpunkten som resulterar i ett arbetsflöde som omfattar fem mikrotjänster.

Screenshot that shows the application map for the drone delivery application.

Pilarna från fabrikam-workflow och fabrikam-ingestion till en Service Bus-kö visar var meddelandena skickas och tas emot. Du kan inte se i diagrammet vilken tjänst som skickar meddelanden och vilken som tar emot. Pilarna visar bara att båda tjänsterna anropar Service Bus. Men information om vilken tjänst som skickar och vilken som tar emot finns i informationen:

Screenshot that shows the application map details.

Eftersom varje anrop innehåller ett åtgärds-ID kan du också visa stegen från slutpunkt till slutpunkt för en enskild transaktion, inklusive tidsinformation och HTTP-anrop i varje steg. Här är visualiseringen av en sådan transaktion:

Screenshot that shows an end-to-end transaction.

Den här visualiseringen visar stegen från inmatningstjänsten till kön, från kön till arbetsflödestjänsten och från arbetsflödestjänsten till de andra serverdelstjänsterna. Det sista steget är arbetsflödestjänsten som markerar Service Bus-meddelandet som slutfört.

Det här exemplet visar anrop till en serverdelstjänst som misslyckas:

Screenshot that shows an application map with errors.

Den här kartan visar att en stor del (36 %) av anropen till Drone Scheduler-tjänsten misslyckades under frågans period. Transaktionsvyn från slutpunkt till slutpunkt visar att ett undantag inträffar när en HTTP PUT-begäran skickas till tjänsten:

Screenshot of the end-to-end transaction. It shows that an exception occurs when an HTTP PUT request is sent to the service.

Om du ökar detaljnivån ytterligare kan du se att undantaget är ett socket-undantag: "Ingen sådan enhet eller adress."

Fabrikam.Workflow.Service.Services.BackendServiceCallFailedException: 
No such device or address 
---u003e System.Net.Http.HttpRequestException: No such device or address 
---u003e System.Net.Sockets.SocketException: No such device or address

Det här undantaget tyder på att serverdelstjänsten inte kan nås. Nu kan du använda kubectl för att visa distributionskonfigurationen. I det här exemplet löser inte tjänstvärdnamnet på grund av ett fel i Kubernetes-konfigurationsfilerna. Artikeln Felsökningstjänster i Kubernetes-dokumentationen innehåller tips för att diagnostisera den här typen av fel.

Här är några vanliga orsaker till fel:

  • Kodbuggar. Dessa buggar kan visas som:
    • Undantag. Titta i Application Insights-loggarna för att visa undantagsinformationen.
    • En process misslyckas. Titta på container- och poddstatus och visa containerloggar eller Application Insights-spårningar.
    • HTTP 5xx-fel .
  • Resursöverbelastning:
    • Leta efter begränsningar (HTTP 429) eller tidsgränser för begäranden.
    • Granska containermått för CPU, minne och disk.
    • Titta på konfigurationerna för container- och poddresursgränser.
  • Tjänstidentifiering. Granska Kubernetes-tjänstens konfiguration och portmappningar.
  • API-matchningsfel. Leta efter HTTP 400-fel. Om API:er är versionshanterade kan du titta på den version som anropas.
  • Det gick inte att hämta en containeravbildning. Titta på poddspecifikationen. Kontrollera också att klustret har behörighet att hämta från containerregistret.
  • RBAC-problem.

Nästa steg

Läs mer om funktioner i Azure Monitor som stöder övervakning av program i AKS: