Un grupo de seguridad de red personalizado bloquea el tráfico

Al acceder a una aplicación hospedada en un clúster de Azure Kubernetes Service (AKS), recibe un mensaje de error "Tiempo de espera agotado". Este error puede producirse incluso si la aplicación se está ejecutando y el resto de la configuración parece ser correcta.

Requisitos previos

  • La herramienta kubectl de Kubernetes, o una herramienta similar, para conectarse al clúster. Para instalar kubectl mediante la CLI de Azure, ejecute el comando az aks install-cli .

  • La herramienta Dirección URL de cliente (cURL) o una herramienta de línea de comandos similar.

  • La herramienta de línea de comandos apt-get para controlar paquetes.

Síntomas

Si ejecuta los siguientes comandos kubectl get y cURL, experimenta errores de "tiempo de espera agotado" similares a los siguientes resultados de la consola:

$ kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
my-deployment-66648877fc-v78jm   1/1     Running   0          5m53s

$ kubectl get service
NAME                      TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)        AGE
my-loadbalancer-service   LoadBalancer   10.0.107.79   10.81.x.x   80:31048/TCP   4m14s

$ curl -Iv http://10.81.124.39  # Use an IP address that fits the "EXTERNAL-IP" pattern.
*   Trying 10.81.x.x:80...
* connect to 10.81.x.x port 80 failed: Timed out
* Failed to connect to 10.81.x.x port 80 after 21033 ms: Timed out
* Closing connection 0
curl: (28) Failed to connect to 10.81.x.x port 80 after 21033 ms: Timed out

Causa

Si experimenta el mismo error "Tiempo de espera agotado" cada vez, esto suele sugerir que un componente de red está bloqueando el tráfico.

Para solucionar este problema, puede empezar comprobando el acceso al pod y, a continuación, pasar al cliente en un enfoque interno .

Para comprobar el pod, ejecute los siguientes kubectl get comandos y kubectl describe :

$ kubectl get pods -o wide
NAME                             READY   STATUS    RESTARTS   AGE   IP            NODE                               
my-deployment-66648877fc-v78jm   1/1     Running   0          53s   172.25.0.93   aks-agentpool-42617579-vmss000000

$ kubectl describe pod my-deployment-66648877fc-v78jm  # Specify the pod name from the previous command.
...
...
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  117s  default-scheduler  Successfully assigned default/my-deployment-66648877fc-v78jm to aks-agentpool-42617579-vmss000000
  Normal  Pulling    116s  kubelet            Pulling image "httpd"
  Normal  Pulled     116s  kubelet            Successfully pulled image "httpd" in 183.532816ms
  Normal  Created    116s  kubelet            Created container webserver
  Normal  Started    116s  kubelet            Started container webserver

En función de esta salida, el pod parece estar ejecutándose correctamente, sin reinicios.

Abra un pod de prueba para comprobar el acceso al pod de aplicación. Ejecute los siguientes kubectl getcomandos , kubectl run, apt-gety cURL:

$ kubectl get pods -o wide  # Get the pod IP address.
NAME                             READY   STATUS    RESTARTS   AGE     IP            NODE                                
my-deployment-66648877fc-v78jm   1/1     Running   0          7m45s   172.25.0.93   aks-agentpool-42617579-vmss000000  

$ kubectl run -it --rm aks-ssh --image=debian:stable  # Launch the test pod.
If you don't see a command prompt, try pressing enter.
$ root@aks-ssh:

$ # Install packages inside the test pod.
$ root@aks-ssh: apt-get update -y && apt-get install dnsutils -y && apt-get install curl -y
Get:1 http://deb.debian.org/debian bullseye InRelease [116 kB]
Get:2 http://deb.debian.org/debian bullseye-updates InRelease [39.4 kB]
...
...
Running hooks in /etc/ca-certificates/update.d...
done.

$ # Try to check access to the pod using the pod IP address from the "kubectl get" output.
$ curl -Iv http://172.25.0.93
*   Trying 172.25.0.93:80...
* Connected to 172.25.0.93 (172.25.0.93) port 80 (#0)
...
...
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
...
...
* Connection #0 to host 172.25.0.93 left intact

Se puede acceder directamente al pod. Por lo tanto, la aplicación se está ejecutando.

El servicio definido es un LoadBalancer tipo. Esto significa que el flujo de solicitud del cliente final al pod será el siguiente:

Pod de aplicación del nodo de AKS del >> equilibrador de carga de cliente >>>>

En este flujo de solicitud, podemos bloquear el tráfico a través de los siguientes componentes:

  • Directivas de red en el clúster
  • Grupo de seguridad de red (NSG) para la subred de AKS y el nodo de AKS

Para comprobar la directiva de red, ejecute el siguiente kubectl get comando:

$ kubectl get networkpolicy --all-namespaces
NAMESPACE     NAME                 POD-SELECTOR             AGE
kube-system   konnectivity-agent   app=konnectivity-agent   3h8m

Solo existe la directiva predeterminada de AKS. Por lo tanto, la directiva de red no parece bloquear el tráfico.

Para comprobar los NSG y sus reglas asociadas mediante AKS, siga estos pasos:

  1. En el Azure Portal, busque y seleccione Conjuntos de escalado de máquinas virtuales.

  2. En la lista de instancias del conjunto de escalado, seleccione la que está usando.

  3. En el panel de menús de la instancia del conjunto de escalado, seleccione Networking.

Aparece la página Redes de la instancia del conjunto de escalado. En la pestaña Reglas de puerto de entrada , se muestran dos conjuntos de reglas que se basan en los dos NSG que actúan en la instancia del conjunto de escalado:

  • El primer conjunto se compone de reglas de grupo de seguridad de red en el nivel de subred. Estas reglas se muestran en el encabezado de nota siguiente:

    Grupo de seguridad <de red my-aks-nsg> (conectado a la subred: <my-aks-subnet>)

    Esta disposición es común si se usa una red virtual personalizada y una subred personalizada para el clúster de AKS. El conjunto de reglas en el nivel de subred podría ser similar a la tabla siguiente.

    Prioridad Nombre Puerto Protocolo Origen Destino Acción
    65000 AllowVnetInBound Cualquiera Cualquiera VirtualNetwork VirtualNetwork Permitir
    65001 AllowAzureLoadBalancerInBound Cualquiera Cualquiera AzureLoadBalancer Cualquiera Permitir
    65500 DenyAllInBound Cualquiera Cualquiera Cualquiera Cualquiera Denegar
  • El segundo conjunto se compone de reglas de NSG en el nivel de adaptador de red. Estas reglas se muestran en el encabezado de nota siguiente:

    Grupo de seguridad de red aks-agentpool-agentpool-number-nsg<> (conectado a la interfaz de red: aks-agentpool-vm-scale-set-number-vmss<>)

    Este grupo de seguridad de red lo aplica el clúster de AKS y AKS lo administra. El conjunto de reglas correspondiente podría ser similar a la tabla siguiente.

    Prioridad Nombre Puerto Protocolo Origen Destino Acción
    500 <guid-TCP-80-Internet> 80 TCP Internet 10.81.x.X Permitir
    65000 AllowVnetInBound Cualquiera Cualquiera VirtualNetwork VirtualNetwork Permitir
    65001 AllowAzureLoadBalancerInBound Cualquiera Cualquiera AzureLoadBalancer Cualquiera Permitir
    65500 DenyAllInBound Cualquiera Cualquiera Cualquiera Cualquiera Denegar

En el nivel de adaptador de red, hay una regla de entrada de NSG para TCP en la dirección IP 10.81. x. x en el puerto 80 (resaltado en la tabla). Sin embargo, falta una regla equivalente de las reglas del grupo de seguridad de red en el nivel de subred.

¿Por qué AKS no aplicó la regla al grupo de seguridad de red personalizado? Dado que AKS no aplica grupos de seguridad de red a su subred y no modificará ninguno de los grupos de seguridad de red asociados a esa subred. AKS modificará los NSG solo en el nivel de adaptador de red. Para obtener más información, consulte ¿Puedo configurar grupos de seguridad de red con AKS?.

Solución

Si la aplicación está habilitada para el acceso en un puerto determinado, debe asegurarse de que el grupo de seguridad de red personalizado permite ese puerto como regla Inbound . Una vez agregada la regla adecuada en el grupo de seguridad de red personalizado en el nivel de subred, se puede acceder a la aplicación.

$ curl -Iv http://10.81.x.x
*   Trying 10.81.x.x:80...
* Connected to 10.81.x.x (10.81.x.x) port 80 (#0)
...
...
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
...
...
* Connection #0 to host 10.81.x.x left intact

Ponte en contacto con nosotros para obtener ayuda

Si tiene preguntas o necesita ayuda, cree una solicitud de soporte o busque consejo en la comunidad de Azure. También puede enviar comentarios sobre el producto con los comentarios de la comunidad de Azure.