Rozwiązywanie problemów z siecią w klastrach usługi AKS

Problemy z siecią mogą wystąpić w nowych instalacjach platformy Kubernetes lub podczas zwiększania obciążenia platformy Kubernetes. Mogą również wystąpić inne problemy związane z siecią. Zawsze sprawdź przewodnik rozwiązywania problemów z usługą AKS, aby sprawdzić, czy problem został tam opisany. W tym artykule opisano dodatkowe szczegóły i zagadnienia z perspektywy rozwiązywania problemów z siecią oraz konkretne problemy, które mogą wystąpić.

Klient nie może nawiązać połączenia z serwerem interfejsu API

Te błędy obejmują problemy z połączeniem występujące, gdy nie można nawiązać połączenia z serwerem interfejsu API klastra usługi Azure Kubernetes Service (AKS) za pośrednictwem narzędzia wiersza polecenia klastra Kubernetes (kubectl) lub innego narzędzia, takiego jak interfejs API REST za pośrednictwem języka programowania.

Błąd

Mogą pojawić się błędy, które wyglądają następująco:

Unable to connect to the server: dial tcp <API-server-IP>:443: i/o timeout 
Unable to connect to the server: dial tcp <API-server-IP>:443: connectex: A connection attempt
failed because the connected party did not properly respond after a period, or established 
connection failed because connected host has failed to respond. 

Przyczyna 1

Możliwe, że zakresy adresów IP autoryzowane przez serwer interfejsu API są włączone na serwerze interfejsu API klastra, ale adres IP klienta nie jest uwzględniony w tych zakresach adresów IP. Aby określić, czy zakresy adresów IP są włączone, użyj następującego az aks show polecenia w interfejsie wiersza polecenia platformy Azure. Jeśli zakresy adresów IP są włączone, polecenie utworzy listę zakresów adresów IP.

az aks show --resource-group <cluster-resource-group> \ 
    --name <cluster-name> \ 
    --query apiServerAccessProfile.authorizedIpRanges 

Rozwiązanie 1

Upewnij się, że adres IP klienta znajduje się w zakresach autoryzowanych przez serwer interfejsu API klastra:

  1. Znajdź lokalny adres IP. Aby uzyskać informacje na temat znajdowania go w systemach Windows i Linux, zobacz Jak znaleźć mój adres IP.

  2. Zaktualizuj zakres autoryzowany przez serwer interfejsu API przy użyciu polecenia w interfejsie az aks update wiersza polecenia platformy Azure. Autoryzuj adres IP klienta. Aby uzyskać instrukcje, zobacz Aktualizowanie autoryzowanych zakresów adresów IP serwera interfejsu API klastra.

Przyczyna 2

Jeśli klaster usługi AKS jest klastrem prywatnym, punkt końcowy serwera interfejsu API nie ma publicznego adresu IP. Musisz użyć maszyny wirtualnej, która ma dostęp sieciowy do sieci wirtualnej klastra usługi AKS.

Rozwiązanie 2

Aby uzyskać informacje na temat rozwiązywania tego problemu, zobacz opcje nawiązywania połączenia z klastrem prywatnym.

Zasobnik nie może przydzielić adresu IP

Błąd

Zasobnik jest zablokowany w ContainerCreating stanie, a jego zdarzenia zgłaszają Failed to allocate address błąd:

Normal   SandboxChanged          5m (x74 over 8m)    kubelet, k8s-agentpool-00011101-0 Pod sandbox
changed, it will be killed and re-created. 

  Warning  FailedCreatePodSandBox  21s (x204 over 8m)  kubelet, k8s-agentpool-00011101-0 Failed 
create pod sandbox: rpc error: code = Unknown desc = NetworkPlugin cni failed to set up pod 
"deployment-azuredisk6-874857994-487td_default" network: Failed to allocate address: Failed to 
delegate: Failed to allocate address: No available addresses 

not enough IPs available Lub błąd:

Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox 
'ac1b1354613465324654c1588ac64f1a756aa32f14732246ac4132133ba21364': plugin type='azure-vnet' 
failed (add): IPAM Invoker Add failed with error: Failed to get IP address from CNS with error: 
%w: AllocateIPConfig failed: not enough IPs available for 9c6a7f37-dd43-4f7c-a01f-1ff41653609c, 
waiting on Azure CNS to allocate more with NC Status: , IP config request is [IPConfigRequest: 
DesiredIPAddress , PodInterfaceID a1876957-eth0, InfraContainerID 
a1231464635654a123646565456cc146841c1313546a515432161a45a5316541, OrchestratorContext 
{'PodName':'a_podname','PodNamespace':'my_namespace'}]

Sprawdź przydzielone adresy IP w magazynie IPAM wtyczki. Może się okazać, że wszystkie adresy IP są przydzielane, ale liczba jest znacznie mniejsza niż liczba uruchomionych zasobników:

W przypadku korzystania z rozwiązania kubenet:

# Kubenet, for example. The actual path of the IPAM store file depends on network plugin implementation. 
chroot /host/
ls -la "/var/lib/cni/networks/$(ls /var/lib/cni/networks/ | grep -e "k8s-pod-network" -e "kubenet")" | grep -v -e "lock\|last\|total" -e '\.$' | wc -l
244

Uwaga

W przypadku rozwiązania kubenet bez Calico ścieżka to /var/lib/cni/networks/kubenet. W przypadku rozwiązania kubenet z Calico ścieżka to /var/lib/cni/networks/k8s-pod-network. Powyższy skrypt automatycznie wybierze ścieżkę podczas wykonywania polecenia.

# Check running Pod IPs
kubectl get pods --field-selector spec.nodeName=<your_node_name>,status.phase=Running -A -o json | jq -r '.items[] | select(.spec.hostNetwork != 'true').status.podIP' | wc -l
7 

W przypadku korzystania z usługi Azure CNI na potrzeby dynamicznej alokacji adresów IP:

kubectl get nnc -n kube-system -o wide
NAME                               REQUESTED IPS  ALLOCATED IPS  SUBNET  SUBNET CIDR   NC ID                                 NC MODE  NC TYPE  NC VERSION
aks-agentpool-12345678-vmss000000  32             32             subnet  10.18.0.0/15  559e239d-f744-4f84-bbe0-c7c6fd12ec17  dynamic  vnet     1
# Check running Pod IPs
kubectl get pods --field-selector spec.nodeName=aks-agentpool-12345678-vmss000000,status.phase=Running -A -o json | jq -r '.items[] | select(.spec.hostNetwork != 'true').status.podIP' | wc -l
21

Przyczyna 1

Ten błąd może być spowodowany usterką w wtyczki sieciowej. Po zakończeniu działania zasobnika wtyczka nie może cofnąć przydziału adresu IP.

Rozwiązanie 1

Skontaktuj się z firmą Microsoft, aby uzyskać obejście lub rozwiązać ten problem.

Przyczyna 2

Tworzenie zasobnika jest znacznie szybsze niż odzyskiwanie pamięci zakończonych zasobników.

Rozwiązanie 2

Skonfiguruj szybkie odzyskiwanie pamięci dla narzędzia kubelet. Aby uzyskać instrukcje, zobacz dokumentację odzyskiwania pamięci platformy Kubernetes.

Usługa nie jest dostępna w zasobnikach

Pierwszym krokiem do rozwiązania tego problemu jest sprawdzenie, czy punkty końcowe zostały utworzone automatycznie dla usługi:

kubectl get endpoints <service-name> 

Jeśli otrzymasz pusty wynik, selektor etykiet usługi może być nieprawidłowy. Upewnij się, że etykieta jest poprawna:

# Query Service LabelSelector. 
kubectl get svc <service-name> -o jsonpath='{.spec.selector}' 

# Get Pods matching the LabelSelector and check whether they're running. 
kubectl get pods -l key1=value1,key2=value2 

Jeśli powyższe kroki zwracają oczekiwane wartości:

  • Sprawdź, czy zasobnik containerPort jest taki sam jak usługa containerPort.

  • Sprawdź, czy podIP:containerPort działa:

    # Testing via cURL. 
    curl -v telnet ://<Pod-IP>:<containerPort>
    
    # Testing via Telnet. 
    telnet <Pod-IP>:<containerPort> 
    

Są to inne potencjalne przyczyny problemów z usługą:

  • Kontener nie nasłuchuje określonego containerPortelementu . (Sprawdź opis zasobnika).
  • Występuje błąd wtyczki CNI lub błąd trasy sieciowej.
  • Serwer kube-proxy nie jest uruchomiony lub reguły iptables nie są poprawnie skonfigurowane.
  • Zasady sieciowe porzucają ruch. Aby uzyskać informacje na temat stosowania i testowania zasad sieciowych, zobacz Omówienie zasad sieci platformy Azure Kubernetes.
    • Jeśli używasz Calico jako wtyczki sieciowej, możesz również przechwytywać ruch zasad sieciowych. Aby uzyskać informacje na temat konfigurowania, zobacz witrynę Calico.

Węzły nie mogą nawiązać połączenia z serwerem interfejsu API

Wiele dodatków i kontenerów musi uzyskać dostęp do interfejsu API Kubernetes (na przykład kontenerów kube-dns i operatorów). Jeśli podczas tego procesu wystąpią błędy, poniższe kroki mogą pomóc w ustaleniu źródła problemu.

Najpierw upewnij się, że interfejs API Kubernetes jest dostępny w zasobnikach:

kubectl run curl --image=mcr.microsoft.com/azure-cli -i -t --restart=Never --overrides='[{"op":"add","path":"/spec/containers/0/resources","value":{"limits":{"cpu":"200m","memory":"128Mi"}}}]' --override-type json --command -- sh

Następnie wykonaj następujące polecenie z poziomu kontenera, do którego teraz masz powłokę.

# If you don't see a command prompt, try selecting Enter. 
KUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) 
curl -sSk -H "Authorization: Bearer $KUBE_TOKEN" https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces/default/pods

Dane wyjściowe w dobrej kondycji będą wyglądać podobnie do poniższych.

{ 
  "kind": "PodList", 
  "apiVersion": "v1", 
  "metadata": { 
    "selfLink": "/api/v1/namespaces/default/pods", 
    "resourceVersion": "2285" 
  }, 
  "items": [ 
   ... 
  ] 
} 

Jeśli wystąpi błąd, sprawdź, czy kubernetes-internal usługa i jej punkty końcowe są w dobrej kondycji:

kubectl get service kubernetes-internal
NAME                TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE 
kubernetes-internal ClusterIP   10.96.0.1    <none>        443/TCP   25m 
kubectl get endpoints kubernetes-internal
NAME                ENDPOINTS          AGE 
kubernetes-internal 172.17.0.62:6443   25m 

Jeśli oba testy zwracają odpowiedzi, takie jak poprzednie, a adres IP i port zwrócone są zgodne z tymi dla kontenera, prawdopodobnie serwer kube-apiserver nie działa lub jest zablokowany z sieci.

Istnieją cztery główne przyczyny, dla których dostęp może zostać zablokowany:

  • Zasady sieciowe. Mogą one uniemożliwiać dostęp do płaszczyzny zarządzania interfejsem API. Aby uzyskać informacje na temat testowania zasad sieciowych, zobacz Omówienie zasad sieciowych.
  • Dozwolone adresy IP interfejsu API. Aby uzyskać informacje na temat rozwiązywania tego problemu, zobacz Aktualizowanie zakresów adresów IP autoryzowanych przez serwer interfejsu API klastra.
  • Twoja prywatna zapora. W przypadku kierowania ruchu usługi AKS przez zaporę prywatną upewnij się, że istnieją reguły ruchu wychodzącego zgodnie z opisem w artykule Wymagane reguły sieci wychodzącej i nazwy FQDN dla klastrów usługi AKS.
  • Twój prywatny system DNS. Jeśli hostujesz klaster prywatny i nie możesz nawiązać połączenia z serwerem interfejsu API, usługi przesyłania dalej DNS mogą nie być prawidłowo skonfigurowane. Aby zapewnić właściwą komunikację, wykonaj kroki opisane w temacie Centrum i szprychy z niestandardowym systemem DNS.

Możesz również sprawdzić dzienniki kube-apiserver przy użyciu usługi Container Insights. Aby uzyskać informacje na temat wykonywania zapytań dotyczących dzienników kube-apiserver i wielu innych zapytań, zobacz Jak wykonywać zapytania dotyczące dzienników z usługi Container Insights.

Na koniec możesz sprawdzić stan serwera kube-apiserver i jego dzienniki w samym klastrze:

# Check kube-apiserver status. 
kubectl -n kube-system get pod -l component=kube-apiserver 

# Get kube-apiserver logs. 
PODNAME=$(kubectl -n kube-system get pod -l component=kube-apiserver -o jsonpath='{.items[0].metadata.name}')
kubectl -n kube-system logs $PODNAME --tail 100

Jeśli zostanie zwrócony 403 - Forbidden błąd, serwer kube-apiserver jest prawdopodobnie skonfigurowany z kontrolą dostępu opartą na rolach (RBAC), a kontener ServiceAccount prawdopodobnie nie jest autoryzowany do uzyskiwania dostępu do zasobów. W takim przypadku należy utworzyć odpowiednie RoleBinding obiekty i ClusterRoleBinding . Aby uzyskać informacje o rolach i powiązaniach ról, zobacz Dostęp i tożsamość. Przykłady konfigurowania kontroli dostępu opartej na rolach w klastrze można znaleźć w temacie Using RBAC Authorization (Używanie autoryzacji RBAC).

Współautorzy

Ten artykuł jest obsługiwany przez firmę Microsoft. Pierwotnie został napisany przez następujących współautorów.

Główny autor:

Inni współautorzy:

Następne kroki