Solución de problemas de red en los clústeres de AKS

Los problemas de red pueden producirse en nuevas instalaciones de Kubernetes o al aumentar la carga de Kubernetes. También pueden producirse otros problemas relacionados con los problemas de red. Compruebe siempre la guía de solución de problemas de AKS para ver si el problema se describe en ella. En este artículo se describen detalles y consideraciones adicionales desde una perspectiva de solución de problemas de red, y otros problemas específicos que pueden surgir.

El cliente no puede acceder al servidor de API

Estos errores implican problemas de conexión que se producen cuando no se puede acceder a un servidor de API del clúster de Azure Kubernetes Service (AKS) a través de la herramienta de línea de comandos del clúster de Kubernetes (kubectl) o mediante cualquier otra herramienta, como la API de REST a través de un lenguaje de programación.

Error

Es posible que vea errores similares a los siguientes:

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. 

Causa 1

Es posible que los intervalos IP que haya autorizado el servidor de API estén habilitados en el servidor de API del clúster, pero la dirección IP del cliente no se incluye en esos intervalos IP. Para determinar si los intervalos IP están habilitados, use el comando az aks show en la CLI de Azure. Si los intervalos IP están habilitados, el comando generará una lista de intervalos IP.

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

Solución 1

Asegúrese de que la dirección IP del cliente esté dentro de los intervalos que haya autorizado el servidor de API del clúster:

  1. Busque la dirección IP local. Para obtener información sobre cómo encontrarlo en Windows y Linux, consulte Cómo encontrar mi dirección IP.

  2. Actualice el intervalo que haya autorizado el servidor de API mediante el comando az aks update en la CLI de Azure. Autorice la dirección IP del cliente. Para obtener instrucciones, consulte Actualización de los intervalos IP autorizados por el servidor de API de un clúster.

Causa 2

Si el clúster de AKS es un clúster privado, el punto de conexión del servidor de API no tiene una dirección IP pública. Debe usar una VM que tenga acceso de red a la red virtual del clúster de AKS.

Solución 2

Para obtener información sobre cómo resolver este problema, consulte Opciones para conectarse a un clúster privado.

El pod no puede asignar la dirección IP

Error

El pod está bloqueado en el estado ContainerCreating y sus eventos notifican un error Failed to allocate address:

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 

O un error 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'}]

Compruebe las direcciones IP asignadas en el almacenamiento del complemento de IPAM. Es posible que se asignen todas las direcciones IP, pero el número es mucho menor que el número de pods en ejecución:

Si usa 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

Nota:

Para kubenet sin Calico, la ruta de acceso es /var/lib/cni/networks/kubenet. Para kubenet con Calico, la ruta de acceso es /var/lib/cni/networks/k8s-pod-network. El script anterior seleccionará automáticamente la ruta de acceso mientras se ejecuta el comando.

# 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 

Si usa Azure CNI para la asignación dinámica de direcciones 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

Causa 1

Este problema puede deberse a un error en el complemento de red. El complemento puede no desasignar la dirección IP cuando finaliza un pod.

Solución 1

Póngase en contacto con Microsoft para obtener una solución o corrección.

Causa 2

La creación de pods es mucho más rápida que la recolección de elementos no utilizados de pods eliminados.

Solución 2

Configure la recolección rápida de elementos no utilizados para kubelet. Para obtener instrucciones, consulte la documentación de recolección de elementos no utilizados de Kubernetes.

Servicio no accesible en los pods

El primer paso para resolver este problema es comprobar si los puntos de conexión se han creado automáticamente para el servicio:

kubectl get endpoints <service-name> 

Si obtiene un resultado vacío, es posible que el selector de etiquetas del servicio sea incorrecto. Confirme que la etiqueta es correcta:

# 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 

Si los pasos anteriores devuelven los valores esperados:

  • Compruebe si el pod containerPort es el mismo que el servicio containerPort.

  • Compruebe que podIP:containerPort esté funcionando.

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

Estas son otras causas potenciales de problemas de servicio:

  • El contenedor no escucha el elemento containerPort especificado. (Compruebe la descripción del pod).
  • Se produce un error de complemento CNI o un error de ruta de red.
  • El elemento kube-proxy no se está ejecutando o las reglas de iptables no están configuradas correctamente.
  • Las directivas de red están ralentizando el tráfico. Para obtener más información sobre cómo aplicar y probar directivas de red, consulte Información general sobre las directivas de red de Azure Kubernetes.
    • Si usa Calico como complemento de red, también puede capturar el tráfico de directivas de red. Para obtener información sobre cómo configurarlo, consulte el sitio de Calico.

Los nodos no puede acceder al servidor de API

Muchos complementos y contenedores necesitan acceder a la API de Kubernetes (por ejemplo, contenedores de operadores y kube-dns). Si se producen errores durante este proceso, los pasos siguientes pueden ayudarle a determinar el origen del problema.

En primer lugar, confirme si la API de Kubernetes es accesible en los pods:

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

Luego, ejecute lo siguiente desde el contenedor que ahora está en la shell.

# 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

El resultado correcto será similar al siguiente.

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

Si se produce un error, compruebe si el servicio kubernetes-internal y sus puntos de conexión son correctos:

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 

Si ambas pruebas devuelven respuestas como las anteriores y la dirección IP y el puerto devuelto coinciden con los que se devuelven para el contenedor, es probable que kube-apiserver no se esté ejecutando o que se haya bloqueado en la red.

Hay cuatro razones principales por las que se puede bloquear el acceso:

También puede comprobar los registros de kube-apiserver mediante Container Insights. Para obtener información sobre cómo consultar los registros de kube-apiserver y muchas otras consultas, consulte Consulta de registros desde Container Insights.

Por último, puede comprobar el estado de kube-apiserver y sus registros en el propio clúster:

# 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

Si se devuelve un error 403 - Forbidden, probablemente kube-apiserver esté configurado con el control de acceso basado en roles (RBAC) y es probable que el elemento ServiceAccount del contenedor no esté autorizado para acceder a los recursos. En este caso, debe crear los objetos RoleBinding y ClusterRoleBinding adecuados. Para obtener información sobre los roles y los enlaces de roles, consulte Acceso e identidad. Para obtener ejemplos de cómo configurar RBAC en el clúster, consulte Uso de la autorización de RBAC.

Colaboradores

Microsoft mantiene este artículo. Originalmente lo escribieron los siguientes colaboradores.

Autor principal:

Otros colaboradores:

Pasos siguientes