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:
Znajdź lokalny adres IP. Aby uzyskać informacje na temat znajdowania go w systemach Windows i Linux, zobacz Jak znaleźć mój adres IP.
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ługacontainerPort
.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
containerPort
elementu . (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.
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:
- Michael Walters | Starszy konsultant
Inni współautorzy:
- Mick Alberts | Składnik zapisywania technicznego
- Ayobami Ayodeji | Starszy menedżer programu
- Bahram Rushenas | Architekt
Następne kroki
- Pojęcia dotyczące sieci związane z aplikacjami w usłudze AKS
- Rozwiązywanie problemów z aplikacjami
- Debugowanie usług
- Sieć klastra Kubernetes
- Wybieranie najlepszej wtyczki sieciowej dla usługi AKS