Solucionar errores de CSE que impiden el aprovisionamiento de nodos de Azure Kubernetes Service

Resumen

Este artículo le ayuda a solucionar errores de extensión de script personalizado (CSE) que impiden que Azure Kubernetes Service (AKS) aprovisione un nuevo nodo. Identifique el código de salida de CSE y resuelva el error para que las nuevas instancias del conjunto de escalado de máquinas virtuales se registren como nodos de AKS.

Requisitos previos

Asegúrese de que tiene CLI de Azure instalado y de que se actualiza a la versión más reciente. Use az --version para comprobar la versión instalada.

Síntomas

Una instancia recién aprovisionada de un conjunto de escalado de máquinas virtuales no se registra como nodo de AKS. Después de una operación de escalado horizontal del grupo de nodos, es posible que observe que el número de instancias de Virtual Machine Scale Sets aumenta mientras que el número de nodos de Kubernetes permanece sin cambios.

Si el escalador automático del clúster está habilitado, puede quitar la instancia de Virtual Machine Scale Sets no registrada después de un período de tiempo.

Solución de problemas

Para identificar la causa, recupere el código de salida de CSE de la instancia de Virtual Machine Scale Sets afectada.

Use CLI de Azure para realizar los pasos siguientes:

  1. Establezca las variables para el clúster de AKS.

    export RG_NAME="<cluster-resource-group>"
    export CLUSTER_NAME="<cluster-name>"
    
    export NODE_RG=$(az aks show \
      --resource-group "$RG_NAME" \
      --name "$CLUSTER_NAME" \
      --query nodeResourceGroup \
      --output tsv)
    
    export API_FQDN=$(az aks show \
      --resource-group "$RG_NAME" \
      --name "$CLUSTER_NAME" \
      --query fqdn \
      --output tsv)
    
  2. Enumere los conjuntos de escalado de máquinas virtuales en el grupo de recursos del nodo e identifique el conjunto de escalado de máquinas virtuales para el grupo de nodos afectado.

    az vmss list \
      --resource-group "$NODE_RG" \
      --query "[].{Name:name,Capacity:sku.capacity,ProvisioningState:provisioningState}" \
      --output table
    
    export VMSS_NAME="<affected-vmss-name>"
    
  3. Busque el identificador de instancia de la instancia de Virtual Machine Scale Sets afectada y exporte el valor.

    export INSTANCE_ID="<affected-vmss-instance-id>"
    
  4. Recupere el estado de CSE de la instancia afectada.

    az vmss get-instance-view \
      --resource-group "$NODE_RG" \
      --name "$VMSS_NAME" \
      --instance-id "$INSTANCE_ID" \
      --query "extensions[?name=='vmssCSE'].statuses[].{
        ExtensionState:code,
        Details:message
      }" \
      --output json
    

    A continuación se incluye el resultado del ejemplo.

     [
       {
         "ExtensionState": "ProvisioningState/failed/0",
         "Details": "failed to execute command: command terminated with exit status=1\n[stdout]\n{ \"ExitCode\": \"51\", \"Output\": \"... Failed to connect to <AKS API server FQDN> port 443: Connection timed out ... API server connection check code: 51 ... exit 51\", ... }\n\n[stderr]\n..."
       }
     ]
    

Los códigos de salida identifican el problema específico que provocó el error de aprovisionamiento. En el ejemplo anterior, CSE devuelve el código 51de salida , que indica un problema de conectividad con el servidor de API de Kubernetes.

Para consultar las asignaciones de otros códigos de salida, consulte el ayudante de CSE.

Solución: Probar y corregir los tiempos de espera de red del servidor API

Asegúrese de que el servidor de API sea accesible desde la instancia de Virtual Machine Scale Sets afectada. Compruebe las siguientes configuraciones de red:

  • Compruebe si el grupo de seguridad de red (NSG) asociado a la subred de AKS bloquea el tráfico saliente a la dirección IP del servidor de API en el puerto TCP 443.
  • Compruebe si un NSG adicional está asociado a la interfaz de red de Virtual Machine Scale Sets. Cada NSG aplicable debe permitir el tráfico saliente a la dirección IP del servidor de API en el puerto TCP 443.
  • Compruebe si un firewall o una aplicación virtual de red (NVA) está en la ruta de acceso de tráfico saliente. Normalmente, se configura un NVA a través de una tabla de rutas asociada a la subred del nodo de AKS. Asegúrese de que el firewall o NVA permite el tráfico saliente a la dirección IP del servidor de API en el puerto TCP 443. Para obtener más información, vea Control del tráfico de salida de los nodos de clúster en AKS.

Para probar la conectividad desde la instancia de Virtual Machine Scale Sets al servidor de API, use CLI de Azure para ejecutar los comandos siguientes.

az vmss run-command invoke \
  --resource-group "$NODE_RG" \
  --name "$VMSS_NAME" \
  --instance-id "$INSTANCE_ID" \
  --command-id RunShellScript \
  --scripts '
API_FQDN="'"$API_FQDN"'"

echo "=== DNS resolution ==="
getent ahostsv4 "$API_FQDN" |
  awk '"'"'NR==1 {print "Resolved IP: " $1}'"'"'

echo "=== TCP connectivity ==="
if timeout 10 bash -c "</dev/tcp/$API_FQDN/443"; then
  echo "TCP 443: connected"
else
  echo "TCP 443: failed"
fi

echo "=== HTTPS response ==="
curl -sS -k \
  --connect-timeout 10 \
  --max-time 15 \
  --output /dev/null \
  --write-out \
"HTTP status: %{http_code}
Remote IP: %{remote_ip}
Connect time: %{time_connect}s
TLS time: %{time_appconnect}s
" \
  "https://$API_FQDN/"
' \
  --query "value[0].message" \
  --output tsv

El comando prueba la resolución del Sistema de nombres de dominio (DNS), la conectividad del Protocolo de control de transmisión (TCP) y la conectividad HTTPS. Si la conexión se realiza correctamente, la salida debe ser similar al ejemplo siguiente.

Enable succeeded:
[stdout]
=== DNS resolution ===
Resolved IP: 172.199.220.208
=== TCP connectivity ===
TCP 443: connected
=== HTTPS response ===
HTTP status: 401
Remote IP: 172.199.220.208
Connect time: 0.018883s
TLS time: 0.058870s

[stderr]

Se espera una respuesta HTTP 401 porque la solicitud no incluye credenciales de autenticación. La respuesta confirma que la resolución DNS, la conexión TCP y el protocolo de enlace TLS se realizaron correctamente y que el servidor de API es accesible.

Si se agota el tiempo de espera de la conexión, la salida debe ser similar al ejemplo siguiente.

Enable succeeded:
[stdout]
=== DNS resolution ===
Resolved IP: 20.238.162.102
=== TCP connectivity ===
TCP 443: failed
=== HTTPS response ===
HTTP status: 000
Remote IP:
Connect time: 0.000000s
TLS time: 0.000000s

[stderr]
curl: (28) Connection timeout after 10000 ms

Si se agota el tiempo de espera de la conexión, la instancia de Virtual Machine Scale Sets no puede acceder al servidor de API en el puerto TCP 443. Compruebe las reglas eficaces del grupo de seguridad de red, las rutas definidas por el usuario, los firewalls, las NVA y otros dispositivos de red que podrían bloquear la conexión.

References