Freigeben über


Behandeln von Problemen mit API-Servern und etcd in Azure Kubernetes Services

Dieses Handbuch soll Ihnen helfen, unwahrscheinliche Probleme zu identifizieren und zu beheben, die auf dem API-Server in großen Microsoft Azure Kubernetes Services (AKS)-Bereitstellungen auftreten können.

Microsoft hat die Zuverlässigkeit und Leistung des API-Servers mit einer Skalierung von 5.000 Knoten und 200.000 Pods getestet. Der Cluster, der den API-Server enthält, kann automatisch skaliert und Kubernetes Service Level Objectives (SLOs) bereitstellen. Wenn hohe Latenzen oder Timeouts auftreten, liegt dies wahrscheinlich daran, dass ein Ressourcenleck im verteilten etc Verzeichnis (usw.) vorliegt oder ein beleidigender Client über übermäßige API-Aufrufe verfügt.

Voraussetzungen

  • Azure-Befehlszeilenschnittstelle.

  • Das Kubernetes-Kubectl-Tool. Führen Sie zum Installieren von Kubectl mithilfe der Azure CLI den Befehl "az aks install-cli " aus.

  • AKS-Diagnoseprotokolle (insbesondere Kube-Audit-Ereignisse), die aktiviert und an einen Log Analytics-Arbeitsbereich gesendet werden. Um festzustellen, ob Protokolle mithilfe des ressourcenspezifischen oder Azure-Diagnosemodus erfasst werden, überprüfen Sie das Blatt "Diagnoseeinstellungen" im Azure-Portal.

  • Die Standardebene für AKS-Cluster. Wenn Sie die Stufe "Frei" verwenden, enthalten der API-Server und usw. begrenzte Ressourcen. AKS-Cluster auf der Stufe "Kostenlos" bieten keine hohe Verfügbarkeit. Dies ist häufig die Ursache für API-Server und etcd-Probleme.

  • Das Kubectl-aks-Plug-In zum Direkten Ausführen von Befehlen auf AKS-Knoten ohne Verwendung der Kubernetes-Steuerebene.

Grundlegende Integritätsüberprüfungen

  • Ereignisse zur Ressourcenintegrität

    AKS stellt Ressourcenintegritätsereignisse für kritische Komponentenausfallzeiten bereit. Stellen Sie vor dem Fortfahren sicher, dass in der Ressourcenintegrität keine kritischen Ereignisse gemeldet werden.

    Screenshot eines Ressourcenintegritätsereignisses.

  • Diagnose und Problembehandlung

    AKS bietet eine dedizierte Problembehandlungskategorie für die Verfügbarkeit und Leistung von Cluster- und Steuerungsebenen.

    Screenshot der Kategorie

Symptome

In der folgenden Tabelle werden die allgemeinen Symptome von API-Serverfehlern beschrieben:

Symptom Beschreibung
Timeouts vom API-Server Häufige Timeouts, die über die Garantien im SLA des AKS-API-Servers hinausgehen. Beispiel: kubectl Timeout für Befehle.
Hohe Latenzen Hohe Latenzen, die die Kubernetes-SLOs fehlschlagen. Beispielsweise dauert der kubectl Befehl mehr als 30 Sekunden, um Pods auflisten zu können.
API-Server-Pod im CrashLoopbackOff Status oder nach Webhook-Aufruffehlern Stellen Sie sicher, dass Sie keinen benutzerdefinierten Webhook (z. B. das Kyverno-Richtlinienmodul ) haben, der die Aufrufe des API-Servers blockiert.

Checkliste zur Problembehandlung

Wenn hohe Latenzzeiten auftreten, führen Sie die folgenden Schritte aus, um den fehlerhaften Client und die Typen von API-Aufrufen anzuheften, die fehlschlagen.

Schritt 1: Identifizieren der wichtigsten Benutzer-Agents anhand der Anzahl der Anforderungen

Um zu ermitteln, welche Clients die meisten Anforderungen generieren (und möglicherweise die meisten API-Serverlasten), führen Sie eine Abfrage aus, die dem folgenden Code ähnelt. Die folgende Abfrage listet die wichtigsten 10 Benutzer-Agents nach der Anzahl der gesendeten API-Serveranforderungen auf.

AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| summarize count() by UserAgent
| top 10 by count_
| project UserAgent, count_

Notiz

Wenn Ihre Abfrage keine Ergebnisse zurückgibt, haben Sie möglicherweise die falsche Tabelle für Abfragediagnoseprotokolle ausgewählt. Im ressourcenspezifischen Modus werden Daten je nach Kategorie der Ressource in einzelne Tabellen geschrieben. Diagnoseprotokolle werden in die AKSAudit Tabelle geschrieben. Im Azure-Diagnosemodus werden alle Daten in die AzureDiagnostics Tabelle geschrieben. Weitere Informationen finden Sie unter Azure-Ressourcenprotokolle.

Obwohl es hilfreich ist, zu wissen, welche Clients das höchste Anforderungsvolumen generieren, ist das Volumen für hohe Anforderungen allein möglicherweise keine Ursache für Bedenken. Ein besserer Indikator für die tatsächliche Last, die jeder Client auf dem API-Server generiert, ist die Antwortlatenz, die sie erleben.

Schritt 2: Identifizieren und Diagramm der durchschnittlichen Latenz von API-Serveranforderungen pro Benutzer-Agent

Führen Sie die folgende Abfrage aus, um die durchschnittliche Latenz von API-Serveranforderungen pro Benutzer-Agent zu identifizieren, wie in einem Zeitdiagramm dargestellt:

AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| extend start_time = RequestReceivedTime
| extend end_time = StageReceivedTime
| extend latency = datetime_diff('millisecond', end_time, start_time)
| summarize avg(latency) by UserAgent, bin(start_time, 5m)
| render timechart

Diese Abfrage ist eine Nachverfolgung der Abfrage im Abschnitt "Identifizieren der wichtigsten Benutzer-Agents nach der Anzahl der Anforderungen" . Möglicherweise erhalten Sie mehr Einblicke in die tatsächliche Last, die von jedem Benutzer-Agent im Laufe der Zeit generiert wird.

Tipp

Durch die Analyse dieser Daten können Sie Muster und Anomalien identifizieren, die auf Probleme in Ihrem AKS-Cluster oder -Anwendungen hinweisen können. Sie können beispielsweise feststellen, dass ein bestimmter Benutzer eine hohe Latenz hat. Dieses Szenario kann den Typ der API-Aufrufe angeben, die zu übermäßiger Auslastung auf dem API-Server oder etcd führen.

Schritt 3: Identifizieren fehlerhafter API-Aufrufe für einen bestimmten Benutzer-Agent

Führen Sie die folgende Abfrage aus, um die 99. Quantillatenz (P99) von API-Aufrufen für verschiedene Ressourcentypen für einen bestimmten Client zu tabulieren:

AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| extend HttpMethod = Verb
| extend Resource = tostring(ObjectRef.resource)
| where UserAgent == "DUMMYUSERAGENT" // Filter by name of the useragent you are interested in
| where Resource != ""
| extend start_time = RequestReceivedTime
| extend end_time = StageReceivedTime
| extend latency = datetime_diff('millisecond', end_time, start_time)
| summarize p99latency=percentile(latency, 99) by HttpMethod, Resource
| render table

Die Ergebnisse dieser Abfrage können hilfreich sein, um die Arten von API-Aufrufen zu identifizieren, die die upstream-Kubernetes-SLOs fehlschlagen. In den meisten Fällen führt ein beleidigender Client möglicherweise zu viele LIST Aufrufe für eine große Gruppe von Objekten oder Objekten, die zu groß sind. Leider stehen keine harten Skalierbarkeitsgrenzwerte zur Verfügung, um Benutzer zur Skalierbarkeit von API-Servern zu führen. API-Server- oder etcd-Skalierbarkeitsgrenzwerte hängen von verschiedenen Faktoren ab, die in Kubernetes-Skalierbarkeitsschwellenwerten erläutert werden.

Ursache 1: Eine Netzwerkregel blockiert den Datenverkehr von Agentknoten zum API-Server.

Eine Netzwerkregel kann den Datenverkehr zwischen den Agentknoten und dem API-Server blockieren.

Führen Sie die folgenden Kubectl-aks-Befehle aus, um zu überprüfen, ob eine falsch konfigurierte Netzwerkrichtlinie die Kommunikation zwischen dem API-Server und den Agentknoten blockiert:

kubectl aks config import \
    --subscription <mySubscriptionID> \
    --resource-group <myResourceGroup> \
    --cluster-name <myAKSCluster>

kubectl aks check-apiserver-connectivity --node <myNode>

Der Befehl "Konfigurationsimport " ruft die Informationen zum Skalierungssatz für virtuelle Computer für alle Knoten im Cluster ab. Anschließend verwendet der Befehl "Check-apiserver-connectivity " diese Informationen, um die Netzwerkkonnektivität zwischen dem API-Server und einem angegebenen Knoten zu überprüfen, insbesondere für die zugrunde liegende Skalierungssatzinstanz.

Notiz

Wenn die Ausgabe des check-apiserver-connectivity Befehls die Connectivity check: succeeded Nachricht enthält, ist die Netzwerkkonnektivität nicht zu beachten.

Lösung 1: Beheben der Netzwerkrichtlinie zum Entfernen der Datenverkehrssperre

Wenn die Befehlsausgabe angibt, dass ein Verbindungsfehler aufgetreten ist, konfigurieren Sie die Netzwerkrichtlinie neu, damit der Datenverkehr zwischen den Agentknoten und dem API-Server nicht unnötig blockiert wird.

Ursache 2: Ein beleidigender Clientlecks usw. führt zu einer Verlangsamung von etcd

Ein häufiges Problem besteht darin, Objekte kontinuierlich zu erstellen, ohne nicht verwendete Objekte in der etcd-Datenbank zu löschen. Dies kann zu Leistungsproblemen führen, wenn usw. zu viele Objekte (mehr als 10.000) eines beliebigen Typs behandelt werden. Eine schnelle Zunahme der Änderungen an solchen Objekten könnte auch dazu führen, dass die größe der etcd-Datenbank (standardmäßig 4 Gigabyte) überschritten wird.

Um die Verwendung der etcd-Datenbank zu überprüfen, navigieren Sie zur Diagnose und Lösung von Problemen im Azure-Portal. Führen Sie das Diagnosetool "Etcd-Verfügbarkeitsprobleme " aus, indem Sie im Suchfeld nach "etcd" suchen. Das Diagnosetool zeigt die Aufschlüsselung der Verwendung und die Gesamtgröße der Datenbank an.

Azure-Portal Screenshot mit der Uswd-Verfügbarkeitsdiagnose für Azure Kubernetes Service (AKS).

Wenn Sie nur eine schnelle Möglichkeit zum Anzeigen der aktuellen Größe Ihrer etcd-Datenbank in Byte wünschen, führen Sie den folgenden Befehl aus:

kubectl get --raw /metrics | grep -E "etcd_db_total_size_in_bytes|apiserver_storage_size_bytes|apiserver_storage_db_total_size_in_bytes"

Notiz

Der Metrikname im vorherigen Befehl unterscheidet sich für verschiedene Kubernetes-Versionen. Verwenden Sie etcd_db_total_size_in_bytesfür Kubernetes 1.25 und frühere Versionen . Verwenden Sie apiserver_storage_db_total_size_in_bytesfür Kubernetes 1.26 bis 1.28 .

Lösung 2: Definieren von Kontingenten für die Objekterstellung, das Löschen von Objekten oder das Einschränken der Objektlebensdauer in usw.

Um zu verhindern, dass kapazität erreicht und Clusterausfallzeiten verursacht werden, können Sie die maximale Anzahl von Ressourcen begrenzen, die erstellt werden. Sie können auch die Anzahl der Überarbeitungen verlangsamen, die für Ressourceninstanzen generiert werden. Um die Anzahl der Objekte zu begrenzen, die erstellt werden können, können Sie Objektkontingente definieren.

Wenn Sie Objekte identifiziert haben, die nicht mehr verwendet werden, aber Ressourcen aufnehmen, sollten Sie sie löschen. Beispielsweise können Sie abgeschlossene Aufträge löschen, um Speicherplatz freizugeben:

kubectl delete jobs --field-selector status.successful=1

Für Objekte, die die automatische Bereinigung unterstützen, können Sie Time to Live (TTL)-Werte festlegen, um die Lebensdauer dieser Objekte zu begrenzen. Sie können Ihre Objekte auch beschriften, sodass Sie alle Objekte eines bestimmten Typs mithilfe von Bezeichnungsmarkierern massenweise löschen können. Wenn Sie Besitzerverweise zwischen Objekten einrichten, werden alle abhängigen Objekte automatisch gelöscht, nachdem das übergeordnete Objekt gelöscht wurde.

Ursache 3: Ein beleidigender Client führt übermäßige LIST- oder PUT-Aufrufe aus

Wenn Sie feststellen, dass etcd nicht mit zu vielen Objekten überladen ist, kann ein beleidigter Client zu viele LIST oder PUT Aufrufe an den API-Server ausführen.

Lösung 3a: Optimieren des API-Aufrufmusters

Erwägen Sie die Optimierung des API-Aufrufmusters Ihres Clients, um den Druck auf die Steuerungsebene zu verringern.

Lösung 3b: Drosseln eines Clients, der die Steuerungsebene überwältigend

Wenn Sie den Client nicht optimieren können, können Sie das Feature "Priorität und Fairness " in Kubernetes verwenden, um den Client zu drosseln. Dieses Feature kann dazu beitragen, den Zustand der Steuerebene zu erhalten und andere Anwendungen daran zu hindern, fehlschlagen zu können.

Das folgende Verfahren zeigt, wie Sie die LIST Pods-API eines beleidigenden Clients auf fünf gleichzeitige Aufrufe drosseln:

  1. Erstellen Sie ein FlowSchema , das dem API-Aufrufmuster des beleidigenden Clients entspricht:

    apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
    kind: FlowSchema
    metadata:
      name: restrict-bad-client
    spec:
      priorityLevelConfiguration:
        name: very-low-priority
      distinguisherMethod:
        type: ByUser
      rules:
      - resourceRules:
        - apiGroups: [""]
          namespaces: ["default"]
          resources: ["pods"]
          verbs: ["list"]
        subjects:
        - kind: ServiceAccount
          serviceAccount:
            name: bad-client-account
            namespace: default 
    
  2. Erstellen Sie eine Konfiguration mit niedrigerer Priorität, um fehlerhafte API-Aufrufe des Clients zu drosseln:

    apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
    kind: PriorityLevelConfiguration
    metadata:
      name: very-low-priority
    spec:
      limited:
        assuredConcurrencyShares: 5
        limitResponse:
          type: Reject
      type: Limited
    
  3. Beobachten Sie den gedrosselten Aufruf in den API-Servermetriken.

    kubectl get --raw /metrics | grep "restrict-bad-client"
    

Ursache 4: Ein benutzerdefinierter Webhook kann einen Deadlock in API-Server-Pods verursachen.

Ein benutzerdefinierter Webhook, z. B. Kyverno, verursacht möglicherweise einen Deadlock in API-Server-Pods.

Überprüfen Sie die Ereignisse, die mit Ihrem API-Server zusammenhängen. Möglicherweise werden Ereignismeldungen angezeigt, die dem folgenden Text ähneln:

Interner Fehler: Fehler beim Aufrufen von Webhook "mutate.kyverno.svc-fail": Fehler beim Aufrufen von Webhook: Beitrag "https://kyverno-system-kyverno-system-svc.kyverno-system.svc:443/mutate/fail?timeout=10s": schreiben unix @->/tunnel-uds/proxysocket: write: broken pipe

In diesem Beispiel blockiert der validierende Webhook die Erstellung einiger API-Serverobjekte. Da dieses Szenario während der Bootstrapzeit auftreten kann, können der API-Server und Konnectivity-Pods nicht erstellt werden. Daher kann der Webhook keine Verbindung mit diesen Pods herstellen. Diese Abfolge von Ereignissen verursacht den Deadlock und die Fehlermeldung.

Lösung 4: Löschen von Webhook-Konfigurationen

Um dieses Problem zu beheben, löschen Sie die Überprüfen und Stummschalten von Webhook-Konfigurationen. Wenn Sie diese Webhook-Konfigurationen in Kyverno löschen möchten, lesen Sie den Artikel zur Problembehandlung in Kyverno.

Haftungsausschluss für Kontaktinformationen von Drittanbietern

Die Kontaktinformationen zu den in diesem Artikel erwähnten Drittanbietern sollen Ihnen helfen, zusätzliche Informationen zu diesem Thema zu finden. Diese Kontaktinformationen können ohne vorherige Ankündigung geändert werden. Sie werden von Microsoft ohne jede Gewähr weitergegeben.

Informationen zum Haftungsausschluss von Drittanbietern

Die in diesem Artikel genannten Drittanbieterprodukte stammen von Herstellern, die von Microsoft unabhängig sind. Microsoft gewährt keine implizite oder sonstige Garantie in Bezug auf die Leistung oder Zuverlässigkeit dieser Produkte.

Kontaktieren Sie uns für Hilfe

Wenn Sie Fragen haben oder Hilfe mit Ihren Azure-Gutschriften benötigen, dann erstellen Sie beim Azure-Support eine Support-Anforderung oder fragen Sie den Azure Community-Support. Sie können auch Produktfeedback an die Azure Feedback Community senden.