Udostępnij za pośrednictwem


Rozwiązywanie problemów z serwerem interfejsu API i etcd w usługach Azure Kubernetes Services

Ten przewodnik jest przeznaczony do ułatwienia identyfikowania i rozwiązywania mało prawdopodobnych problemów, które mogą wystąpić na serwerze interfejsu API w dużych wdrożeniach usług Microsoft Azure Kubernetes Services (AKS).

Firma Microsoft przetestowała niezawodność i wydajność serwera interfejsu API na dużą skalę 5000 węzłów i 200 000 zasobników. Klaster, który zawiera serwer interfejsu API, ma możliwość automatycznego skalowania w poziomie i dostarczania celów poziomu usługi Kubernetes (SLO). Jeśli występują duże opóźnienia lub przekroczenia limitu czasu, prawdopodobnie jest to spowodowane wyciekiem zasobów w katalogu rozproszonym etc (itp.) lub obraźliwym klientem ma nadmierne wywołania interfejsu API.

Wymagania wstępne

  • Interfejs wiersza polecenia platformy Azure.

  • Narzędzie Kubernetes kubectl . Aby zainstalować narzędzie kubectl przy użyciu interfejsu wiersza polecenia platformy Azure, uruchom polecenie az aks install-cli .

  • Dzienniki diagnostyczne usługi AKS (w szczególności zdarzenia kube-audit), które są włączone i wysyłane do obszaru roboczego usługi Log Analytics. Aby określić, czy dzienniki są zbierane przy użyciu trybu diagnostyki specyficznego dla zasobu lub platformy Azure, sprawdź blok Ustawienia diagnostyczne w witrynie Azure Portal.

  • Warstwa Standardowa dla klastrów usługi AKS. Jeśli używasz warstwy Bezpłatna, serwer interfejsu API itp. zawiera ograniczone zasoby. Klastry usługi AKS w warstwie Bezpłatna nie zapewniają wysokiej dostępności. Często jest to główna przyczyna problemów z serwerem interfejsu API i itp.

  • Wtyczka kubectl-aks do uruchamiania poleceń bezpośrednio w węzłach usługi AKS bez korzystania z płaszczyzny sterowania Kubernetes.

Podstawowe kontrole kondycji

  • Zdarzenia usługi Resource Health

    Usługa AKS zapewnia zdarzenia dotyczące kondycji zasobów w przypadku przestojów krytycznych składników. Przed kontynuowaniem upewnij się, że w usłudze Resource Health nie są zgłaszane żadne zdarzenia krytyczne.

    Zrzut ekranu przedstawiający zdarzenie kondycji zasobu.

  • Diagnozowanie i rozwiązywanie problemów

    Usługa AKS udostępnia dedykowaną kategorię rozwiązywania problemów dla dostępności i wydajności płaszczyzny sterowania i klastra.

    Zrzut ekranu przedstawiający kategorię

Symptomy

W poniższej tabeli przedstawiono typowe objawy błędów serwera interfejsu API:

Objaw opis
Limity czasu z serwera interfejsu API Częste przekroczenia limitu czasu wykraczające poza gwarancje umowy SLA serwera interfejsu API usługi AKS. Na przykład kubectl przekroczenie limitu czasu poleceń.
Duże opóźnienia Duże opóźnienia, które sprawiają, że cele SLO platformy Kubernetes kończą się niepowodzeniem. Na przykład kubectl polecenie trwa ponad 30 sekund, aby wyświetlić listę zasobników.
Zasobnik serwera interfejsu API w CrashLoopbackOff stanie lub napotkanych błędach wywołania elementu webhook Sprawdź, czy nie masz niestandardowego elementu webhook przyjęcia (takiego jak aparat zasad Kyverno ), który blokuje wywołania serwera interfejsu API.

Lista kontrolna rozwiązywania problemów

Jeśli występują duże opóźnienia, wykonaj następujące kroki, aby wskazać klienta, którego dotyczy błąd, oraz typy wywołań interfejsu API, które kończą się niepowodzeniem.

Krok 1. Identyfikowanie agentów najlepszych użytkowników według liczby żądań

Aby określić, którzy klienci generują najwięcej żądań (i potencjalnie największe obciążenie serwera interfejsu API), uruchom zapytanie podobne do poniższego kodu. Poniższe zapytanie zawiera listę 10 najważniejszych agentów użytkowników według liczby wysłanych żądań serwera interfejsu API.

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

Uwaga 16.

Jeśli zapytanie nie zwraca żadnych wyników, być może wybrano niewłaściwą tabelę do wykonywania zapytań dotyczących dzienników diagnostycznych. W trybie specyficznym dla zasobu dane są zapisywane w poszczególnych tabelach w zależności od kategorii zasobu. Dzienniki diagnostyczne są zapisywane w AKSAudit tabeli. W trybie diagnostyki platformy Azure wszystkie dane są zapisywane w AzureDiagnostics tabeli. Aby uzyskać więcej informacji, zobacz Dzienniki zasobów platformy Azure.

Chociaż warto wiedzieć, którzy klienci generują najwyższy wolumin żądań, duże ilości żądań mogą nie być przyczyną problemu. Lepszym wskaźnikiem rzeczywistego obciążenia generowanego przez każdego klienta na serwerze interfejsu API jest opóźnienie odpowiedzi, które występują.

Krok 2. Identyfikowanie i tworzenie wykresu średniego opóźnienia żądań serwera interfejsu API na agenta użytkownika

Aby zidentyfikować średnie opóźnienie żądań serwera interfejsu API na agenta użytkownika zgodnie z wykresem czasu, uruchom następujące zapytanie:

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

To zapytanie jest kontynuacją zapytania w sekcji "Identyfikowanie najważniejszych agentów użytkowników według liczby żądań". Może to dać więcej szczegółowych informacji na temat rzeczywistego obciążenia generowanego przez każdego agenta użytkownika w czasie.

Napiwek

Analizując te dane, można zidentyfikować wzorce i anomalie, które mogą wskazywać problemy w klastrze lub aplikacjach usługi AKS. Możesz na przykład zauważyć, że określony użytkownik ma duże opóźnienie. Ten scenariusz może wskazywać typ wywołań interfejsu API, które powodują nadmierne obciążenie serwera interfejsu API lub itp.

Krok 3. Identyfikowanie nieprawidłowych wywołań interfejsu API dla danego agenta użytkownika

Uruchom następujące zapytanie, aby utworzyć tabulacji 99. percentyla (P99) opóźnienia wywołań interfejsu API w różnych typach zasobów dla danego klienta:

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

Wyniki tego zapytania mogą być przydatne do identyfikowania rodzajów wywołań interfejsu API, które kończą się niepowodzeniem nadrzędnych celów SLO platformy Kubernetes. W większości przypadków klient, który obraża zbyt wiele LIST wywołań na dużym zestawie obiektów lub obiektów, które są zbyt duże. Niestety, nie są dostępne żadne twarde limity skalowalności, aby kierować użytkowników o skalowalności serwera interfejsu API. Limity skalowalności serwera interfejsu API lub etcd zależą od różnych czynników, które zostały wyjaśnione w progach skalowalności platformy Kubernetes.

Przyczyna 1: Reguła sieci blokuje ruch z węzłów agenta do serwera interfejsu API

Reguła sieci może blokować ruch między węzłami agenta i serwerem interfejsu API.

Aby sprawdzić, czy nieprawidłowo skonfigurowane zasady sieciowe blokują komunikację między serwerem interfejsu API i węzłami agenta, uruchom następujące polecenia kubectl-aks :

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

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

Polecenie importu konfiguracji pobiera informacje o zestawie skalowania maszyn wirtualnych dla wszystkich węzłów w klastrze. Następnie polecenie check-apiserver-connectivity używa tych informacji do weryfikowania łączności sieciowej między serwerem interfejsu API a określonym węzłem, w szczególności dla jego bazowego wystąpienia zestawu skalowania.

Uwaga 16.

Jeśli dane wyjściowe check-apiserver-connectivity polecenia zawierają Connectivity check: succeeded komunikat, łączność sieciowa jest niezapisane.

Rozwiązanie 1. Naprawianie zasad sieciowych w celu usunięcia blokady ruchu

Jeśli dane wyjściowe polecenia wskazują, że wystąpił błąd połączenia, skonfiguruj ponownie zasady sieciowe, aby nie blokowały niepotrzebnie ruchu między węzłami agenta i serwerem interfejsu API.

Przyczyna 2: Obraźliwe przecieki klienta itp. Powoduje spowolnienie itp.

Typowym problemem jest ciągłe tworzenie obiektów bez usuwania nieużywanych obiektów w bazie danych etcd. Może to spowodować problemy z wydajnością, gdy etcd zajmuje się zbyt wieloma obiektami (ponad 10 000) dowolnego typu. Szybki wzrost zmian w takich obiektach może również spowodować przekroczenie rozmiaru bazy danych etcd (domyślnie 4 gigabajty).

Aby sprawdzić użycie bazy danych itp., przejdź do pozycji Diagnozowanie i rozwiązywanie problemów w witrynie Azure Portal. Uruchom narzędzie diagnostyki problemów z dostępnością etcd, wyszukując ciąg "etcd" w polu wyszukiwania. Narzędzie do diagnostyki pokazuje podział użycia i całkowity rozmiar bazy danych.

Zrzut ekranu witryny Azure Portal przedstawiający diagnostykę dostępności etcd dla usługi Azure Kubernetes Service (AKS).

Jeśli chcesz tylko szybko wyświetlić bieżący rozmiar bazy danych itp. w bajtach, uruchom następujące polecenie:

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

Uwaga 16.

Nazwa metryki w poprzednim poleceniu różni się w przypadku różnych wersji platformy Kubernetes. W przypadku platformy Kubernetes w wersji 1.25 lub starszej użyj polecenia etcd_db_total_size_in_bytes. W przypadku platformy Kubernetes 1.26 do 1.28 użyj polecenia apiserver_storage_db_total_size_in_bytes.

Rozwiązanie 2. Definiowanie limitów przydziału dla tworzenia obiektów, usuwania obiektów lub ograniczania okresu istnienia obiektu itp.

Aby zapobiec osiągnięciu pojemności i spowodowaniu przestoju klastra, możesz ograniczyć maksymalną liczbę utworzonych zasobów. Można również spowolnić liczbę poprawek generowanych dla wystąpień zasobów. Aby ograniczyć liczbę obiektów, które można utworzyć, można zdefiniować przydziały obiektów.

Jeśli zidentyfikowano obiekty, które nie są już używane, ale zajmują zasoby, rozważ ich usunięcie. Możesz na przykład usunąć ukończone zadania, aby zwolnić miejsce:

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

W przypadku obiektów obsługujących automatyczne czyszczenie można ustawić wartość Czas wygaśnięcia (TTL), aby ograniczyć okres istnienia tych obiektów. Możesz również oznaczyć obiekty etykietami, aby można było zbiorczo usunąć wszystkie obiekty określonego typu przy użyciu selektorów etykiet. Jeśli ustanowisz odwołania właściciela między obiektami, wszystkie obiekty zależne zostaną automatycznie usunięte po usunięciu obiektu nadrzędnego.

Przyczyna 3: Klient naruszający błąd wykonuje nadmierne wywołania LIST lub PUT

Jeśli ustalisz, że element etcd nie jest przeciążony zbyt wieloma obiektami, obraźliwy klient może wykonać zbyt wiele LIST PUT wywołań do serwera interfejsu API.

Rozwiązanie 3a: dostrajanie wzorca wywołania interfejsu API

Rozważ dostrajanie wzorca wywołania interfejsu API klienta w celu zmniejszenia ciśnienia na płaszczyźnie sterowania.

Rozwiązanie 3b: ograniczanie klienta, który przeciąża płaszczyznę sterowania

Jeśli nie możesz dostroić klienta, możesz użyć funkcji Priorytet i Sprawiedliwość w usłudze Kubernetes, aby ograniczyć klienta. Ta funkcja może pomóc zachować kondycję płaszczyzny sterowania i zapobiec awarii innych aplikacji.

Poniższa procedura pokazuje, jak ograniczyć interfejs API list klienta ustawiony na pięć współbieżnych wywołań:

  1. Utwórz usługę FlowSchema zgodną ze wzorcem wywołania interfejsu API klienta, który jest obraźliwy:

    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. Utwórz konfigurację o niższym priorytcie, aby ograniczyć nieprawidłowe wywołania interfejsu API klienta:

    apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
    kind: PriorityLevelConfiguration
    metadata:
      name: very-low-priority
    spec:
      limited:
        assuredConcurrencyShares: 5
        limitResponse:
          type: Reject
      type: Limited
    
  3. Obserwuj wywołanie ograniczone w metrykach serwera interfejsu API.

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

Przyczyna 4. Niestandardowy element webhook może spowodować zakleszczenie w zasobnikach serwera interfejsu API

Niestandardowy element webhook, taki jak Kyverno, może powodować zakleszczenie w zasobnikach serwera interfejsu API.

Sprawdź zdarzenia związane z serwerem interfejsu API. Mogą pojawić się komunikaty o zdarzeniach podobne do następującego tekstu:

Wystąpił błąd wewnętrzny: nie można wywołać elementu webhook "mutate.kyverno.svc-fail": nie można wywołać elementu webhook: Post "https://kyverno-system-kyverno-system-svc.kyverno-system.svc:443/mutate/fail?timeout=10s": write unix @->/tunnel-uds/proxysocket: write: broken pipe

W tym przykładzie sprawdzanie poprawności elementu webhook blokuje tworzenie niektórych obiektów serwera interfejsu API. Ponieważ ten scenariusz może wystąpić w czasie uruchamiania, nie można utworzyć zasobników serwera interfejsu API i konnectivity. W związku z tym element webhook nie może nawiązać połączenia z tymi zasobnikami. Ta sekwencja zdarzeń powoduje zakleszczenie i komunikat o błędzie.

Rozwiązanie 4. Usuwanie konfiguracji elementu webhook

Aby rozwiązać ten problem, usuń konfiguracje elementów webhook weryfikowania i mutowania. Aby usunąć te konfiguracje elementu webhook w usłudze Kyverno, zapoznaj się z artykułem dotyczącym rozwiązywania problemów z kyverno.

Wyłączenie odpowiedzialności za kontakty z osobami trzecimi

Firma Microsoft udostępnia informacje kontaktowe innych firm, aby uzyskać dodatkowe informacje na temat tego tematu. Informacje te mogą zostać zmienione bez powiadomienia. Firma Microsoft nie gwarantuje dokładności informacji kontaktowych innych firm.

Zastrzeżenie dotyczące innych firm

Produkty innych firm omówione w tym artykule są wytwarzane przez producentów niezależnych od firmy Microsoft. Firma Microsoft nie udziela żadnych gwarancji, dorozumianych ani żadnego innego rodzaju, w odniesieniu do wydajności lub niezawodności tych produktów.

Skontaktuj się z nami, aby uzyskać pomoc

Jeśli masz pytania lub potrzebujesz pomocy, utwórz wniosek o pomoc techniczną lub zadaj pytanie w społeczności wsparcia dla platformy Azure. Możesz również przesłać opinię o produkcie do społeczności opinii na temat platformy Azure.