Řešení potíží se sítí v clusterech AKS

K problémům se sítí může dojít v nových instalacích Kubernetes nebo při zvýšení zatížení Kubernetes. Mohou také nastat další problémy související se sítí. Vždy si projděte průvodce odstraňováním potíží se službou AKS a zjistěte, jestli je tam váš problém popsaný. Tento článek popisuje další podrobnosti a aspekty z hlediska řešení potíží se sítí a konkrétních problémů, které by mohly nastat.

Klient se nemůže spojit se serverem rozhraní API

Tyto chyby zahrnují problémy s připojením, ke kterým dochází v případě, že se nemůžete spojit se serverem rozhraní API clusteru Azure Kubernetes Service (AKS) prostřednictvím nástroje příkazového řádku clusteru Kubernetes (kubectl) nebo jakéhokoli jiného nástroje, jako je rozhraní REST API prostřednictvím programovacího jazyka.

Chyba

Můžou se zobrazit chyby, které vypadají takto:

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. 

Příčina 1

Je možné, že rozsahy IP adres autorizované serverem rozhraní API jsou povolené na serveru rozhraní API clusteru, ale IP adresa klienta není součástí těchto rozsahů IP adres. Pokud chcete zjistit, jestli jsou povolené rozsahy IP adres, použijte v Azure CLI následující az aks show příkaz. Pokud jsou rozsahy IP adres povolené, příkaz vytvoří seznam rozsahů IP adres.

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

Řešení 1

Ujistěte se, že IP adresa vašeho klienta spadá do rozsahů autorizovaných serverem rozhraní API clusteru:

  1. Vyhledejte místní IP adresu. Informace o tom, jak ji najít ve Windows a Linuxu, najdete v tématu Jak najít moji IP adresu.

  2. Pomocí příkazu v Azure CLI aktualizujte rozsah autorizovaný serverem az aks update rozhraní API. Autorizovat IP adresu klienta. Pokyny najdete v tématu Aktualizace rozsahů IP adres autorizovaných serverem rozhraní API clusteru.

Příčina 2

Pokud je váš cluster AKS privátním clusterem, koncový bod serveru ROZHRANÍ API nemá veřejnou IP adresu. Potřebujete použít virtuální počítač, který má síťový přístup k virtuální síti clusteru AKS.

Řešení 2

Informace o řešení tohoto problému najdete v možnostech připojení k privátnímu clusteru.

Pod se nepodaří přidělit IP adresu

Chyba

Pod je zablokovaný ContainerCreating ve stavu a jeho události hlásí Failed to allocate address chybu:

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 

Nebo chyba not enough IPs available :

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'}]

Zkontrolujte přidělené IP adresy v Správa IP adres úložišti modulů plug-in. Možná zjistíte, že jsou přiděleny všechny IP adresy, ale číslo je mnohem menší než počet spuštěných podů:

Pokud používáte 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

Poznámka:

Pro kubenet bez Calico, cesta je /var/lib/cni/networks/kubenet. Pro kubenet s Calico, cesta je /var/lib/cni/networks/k8s-pod-network. Výše uvedený skript automaticky vybere cestu při provádění příkazu.

# 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 

Pokud k dynamickému přidělování IP adres používáte Azure CNI:

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

Příčina 1

Příčinou této chyby může být chyba v síťovém modulu plug-in. Modul plug-in může při ukončení podu zrušit přidělení IP adresy.

Řešení 1

Požádejte Microsoft o alternativní řešení nebo opravu.

Příčina 2

Vytváření podů je mnohem rychlejší než uvolňování paměti ukončených podů.

Řešení 2

Nakonfigurujte rychlé uvolňování paměti pro kubelet. Pokyny najdete v dokumentaci k uvolňování paměti Kubernetes.

Služba není přístupná v rámci podů

Prvním krokem k vyřešení tohoto problému je zkontrolovat, jestli se pro službu automaticky vytvořily koncové body:

kubectl get endpoints <service-name> 

Pokud se zobrazí prázdný výsledek, může být selektor popisků vaší služby chybný. Ověřte správnost popisku:

# 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 

Pokud předchozí kroky vrátí očekávané hodnoty:

  • Zkontrolujte, jestli je pod containerPort stejný jako služba containerPort.

  • Zkontrolujte, jestli podIP:containerPort funguje:

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

Toto jsou některé další možné příčiny problémů se službami:

  • Kontejner nenaslouchá zadanému containerPortparametru . (Zkontrolujte popis podu.)
  • Dochází k chybě modulu plug-in CNI nebo k chybě síťové trasy.
  • Kube-proxy není spuštěný nebo nejsou správně nakonfigurovaná pravidla iptables.
  • Zásady sítě ruší provoz. Informace o použití a testování zásad sítě najdete v přehledu zásad sítě Azure Kubernetes.
    • Pokud jako síťový modul plug-in používáte Calico, můžete také zaznamenávat přenosy síťových zásad. Informace o konfiguraci najdete v lokalitě Calico.

Uzly se nemůžou spojit se serverem rozhraní API

Mnoho doplňků a kontejnerů potřebuje přístup k rozhraní API Kubernetes (například kontejnery kube-dns a operátor). Pokud během tohoto procesu dojde k chybám, následující kroky vám můžou pomoct určit zdroj problému.

Nejprve ověřte, jestli je rozhraní API Kubernetes přístupné v rámci podů:

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

Potom v kontejneru, do kterého jste teď zasílali, spusťte následující příkaz.

# 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

Výstup, který je v pořádku, bude vypadat podobně jako v následujícím příkladu.

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

Pokud dojde k chybě, zkontrolujte, jestli kubernetes-internal je služba a její koncové body v pořádku:

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 

Pokud oba testy vrátí odpovědi jako předchozí a vrácená IP adresa a port odpovídají odpovědím pro váš kontejner, je pravděpodobné, že kube-apiserver není spuštěný nebo je zablokovaný ze sítě.

Přístup může být blokovaný ze čtyř hlavních důvodů:

  • Zásady sítě. Můžou bránit přístupu k rovině služby API Management. Informace o testování zásad sítě najdete v tématu Přehled zásad sítě.
  • Povolené IP adresy vašeho rozhraní API Informace o řešení tohoto problému najdete v tématu Aktualizace rozsahů IP adres autorizovaných serverem rozhraní API clusteru.
  • Vaše privátní brána firewall. Pokud směrujete provoz AKS přes privátní bránu firewall, ujistěte se, že existují pravidla odchozích přenosů, jak je popsáno v části Požadovaná pravidla odchozí sítě a plně kvalifikované názvy domén pro clustery AKS.
  • Vaše privátní DNS. Pokud hostujete privátní cluster a nemůžete se spojit se serverem rozhraní API, vaše servery pro předávání DNS nemusí být správně nakonfigurované. Pokud chcete zajistit správnou komunikaci, proveďte kroky v hubu a paprsku pomocí vlastního DNS.

Protokoly kube-apiserver můžete také zkontrolovat pomocí přehledů kontejneru. Informace o dotazování protokolů kube-apiserver a mnoha dalších dotazů najdete v tématu Dotazování protokolů z Container Insights.

Nakonec můžete zkontrolovat stav serveru kube-apiserver a jeho protokoly v samotném clusteru:

# 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

403 - Forbidden Pokud se vrátí chyba, kube-apiserver je pravděpodobně nakonfigurovaný s řízením přístupu na základě role (RBAC) a váš kontejner ServiceAccount pravděpodobně nemá oprávnění pro přístup k prostředkům. V tomto případě byste měli vytvořit vhodné RoleBinding objekty a ClusterRoleBinding objekty. Informace o rolích a vazbách rolí najdete v tématu Přístup a identita. Příklady konfigurace řízení přístupu na základě role v clusteru najdete v tématu Použití autorizace RBAC.

Přispěvatelé

Tento článek spravuje Microsoft. Původně byla napsána následujícími přispěvateli.

Hlavní autor:

Další přispěvatelé:

Další kroky