Usa GKE Dataplane V2

En esta página, se explica cómo habilitar y solucionar problemas de GKE Dataplane V2 para clústeres de Google Kubernetes Engine (GKE).

Los clústeres Autopilot nuevos tienen GKE Dataplane V2 habilitado en las versiones 1.22.7-gke.1500 y posteriores, y las versiones 1.23.4-gke.1500 y posteriores. Si tienes problemas para usar GKE Dataplane V2, ve a Solución de problemas.

Crea un clúster de GKE con GKE Dataplane V2

Puedes habilitar GKE Dataplane V2 cuando creas clústeres nuevos con la versión de GKE 1.20.6-gke.700 y posteriores con gcloud CLI o la API de GKE. También puedes habilitar GKE Dataplane V2 en vista previa cuando creas clústeres nuevos con la versión de GKE 1.17.9 y posteriores.

Console

Para crear un clúster nuevo con GKE Dataplane V2, realiza las siguientes tareas:

  1. En la consola de Google Cloud , ve a la página Crea un clúster de Kubernetes.

    Ir a Crea un clúster de Kubernetes

  2. En la sección Herramientas de redes, selecciona la casilla de verificación Habilitar Dataplane V2. La opción Habilitar la política de red de Kubernetes se inhabilita cuando seleccionas Habilitar Dataplane V2 porque la aplicación de la política de red está integrada en GKE Dataplane V2.

  3. Haz clic en Crear.

gcloud

Para crear un clúster nuevo con GKE Dataplane V2, usa el siguiente comando:

gcloud container clusters create CLUSTER_NAME \
    --enable-dataplane-v2 \
    --enable-ip-alias \
    --release-channel CHANNEL_NAME \
    --location COMPUTE_LOCATION

Reemplaza lo siguiente:

  • CLUSTER_NAME: Es el nombre del clúster nuevo.
  • CHANNEL_NAME: Un canal de versiones que incluye la versión 1.20.6-gke.700 de GKE o una posterior. Si prefieres no usar un canal de versiones, también puedes usar la marca --cluster-version en lugar de --release-channel, con la especificación de la versión 1.20.6-gke.700 o posterior.
  • COMPUTE_LOCATION: la ubicación de Compute Engine para el clúster nuevo.

API

Para crear un clúster nuevo con GKE Dataplane V2, especifica el campo datapathProvider en el objeto networkConfig, en la solicitud create del clúster.

En el siguiente fragmento de código JSON, se muestra la configuración necesaria para habilitar GKE Dataplane V2:

"cluster":{
   "initialClusterVersion":"VERSION",
   "ipAllocationPolicy":{
      "useIpAliases":true
   },
   "networkConfig":{
      "datapathProvider":"ADVANCED_DATAPATH"
   },
   "releaseChannel":{
      "channel":"CHANNEL_NAME"
   }
}

Reemplaza lo siguiente:

  • VERSION: Tu versión del clúster, que debe ser GKE 1.20.6-gke.700 o posterior.
  • CHANNEL_NAME: Un canal de versiones que incluye la versión 1.20.6-gke.700 de GKE o una posterior.

Soluciona problemas con GKE Dataplane V2

En esta sección, se muestra cómo investigar y resolver problemas con GKE Dataplane V2.

  1. Confirma que GKE Dataplane V2 esté habilitado:

    kubectl -n kube-system get pods -l k8s-app=cilium -o wide
    

    Si GKE Dataplane V2 está en ejecución, el resultado incluye Pods con el prefijo anetd-. anetd es el controlador de herramientas de redes para GKE Dataplane V2.

  2. Si el problema es con los servicios o la aplicación de la política de red, verifica los registros del Pod anetd: Usa los siguientes selectores de registros en Cloud Logging:

    resource.type="k8s_container"
    labels."k8s-pod/k8s-app"="cilium"
    resource.labels.cluster_name="CLUSTER_NAME"
    
  3. Si falla la creación de un Pod, revisa los registros de kubelet para obtener pistas. Usa los siguientes selectores de registros en Cloud Logging:

    resource.type="k8s_node"
    log_name=~".*/logs/kubelet"
    resource.labels.cluster_name="CLUSTER_NAME"
    

    Reemplaza CLUSTER_NAME por el nombre del clúster o quítalo por completo para ver los registros de todos los clústeres.

  4. Si los Pods de anetd no se están ejecutando, examina el ConfigMap de cilium-config para detectar cualquier modificación. Evita modificar los campos existentes en este ConfigMap, ya que estos cambios pueden desestabilizar el clúster y perturbar anetd. El ConfigMap se vuelve a aplicar al estado predeterminado solo si se le agregan campos nuevos. No se aplican parches a los cambios en los campos existentes, y te recomendamos que no cambies ni personalices el ConfigMap.

Problemas conocidos

Problemas de conectividad intermitentes relacionados con conflictos de rango de NodePort en clústeres de GKE Dataplane V2

En los clústeres de GKE Dataplane V2, pueden ocurrir problemas de conectividad intermitentes para el tráfico enmascarado o con el uso de puertos efímeros. Estos problemas se deben a posibles conflictos de puertos con el rango de NodePort reservado y, por lo general, ocurren en las siguientes situaciones:

  • ip-masq-agent personalizado: Si usas un ip-masq-agent personalizado (versión 2.10 o posterior), en el que el clúster tiene servicios de NodePort o de balanceador de cargas, es posible que observes problemas de conectividad intermitente debido a su conflicto con el rango de NodePort. A partir de la versión 2.10 y versiones posteriores, ip-masq-agent tiene el argumento --random-fully implementado internamente de forma predeterminada. Para mitigar esto, configura de forma explícita --random-fully=false (aplicable desde la versión 2.11) en los argumentos de la configuración de ip-masq-agent. Para obtener más información sobre la configuración, consulta Configura un agente de enmascaramiento de IP en clústeres de Standard.

  • Superposición del rango de puertos efímeros: Si el rango de puertos efímeros definido por net.ipv4.ip_local_port_range en tus nodos de GKE se superpone con el rango de NodePort (30000-32767), también puede generar problemas de conectividad. Para evitar este problema, asegúrate de que estos dos rangos no se superpongan.

Revisa la configuración de ip-masq-agent y la configuración del rango de puertos efímero para asegurarte de que no entren en conflicto con el rango de NodePort. Si tienes problemas de conectividad intermitentes, considera estas posibles causas y ajusta tu configuración según corresponda.

Problemas de conectividad con hostPort en clústeres de GKE Dataplane V2

Versiones afectadas de GKE: 1.29 y versiones posteriores

En los clústeres que usan GKE Dataplane V2, es posible que se produzcan errores de conectividad cuando el tráfico se dirige a la IP:puerto de un nodo, en el que el puerto es el hostPort definido en el Pod. Estos problemas surgen en dos situaciones principales:

  • Nodos con hostPort detrás de un balanceador de cargas de red de transferencia:

    hostPort vincula un Pod al puerto de un nodo específico, y un balanceador de cargas de red de transferencia distribuye el tráfico entre todos los nodos. Cuando expones Pods a Internet con hostPort y un balanceador de cargas de red de transferencia, es posible que el balanceador de cargas envíe tráfico a un nodo en el que no se esté ejecutando el Pod, lo que provoca errores de conexión. Esto se debe a una limitación conocida en GKE Dataplane V2 en la que el tráfico del balanceador de cargas de red de transferencia no se reenvía de forma coherente a los Pods hostPort.

    Solución alternativa: Cuando expongas hostPorts de un Pod en el nodo con un balanceador de cargas de red de transferencia, especifica la dirección IP interna o externa del balanceador de cargas de red en el campo hostIP del Pod.

    ports:
    - containerPort: 62000
      hostPort: 62000
      protocol: TCP
      hostIP: 35.232.62.64
    - containerPort: 60000
      hostPort: 60000
      protocol: TCP
      hostIP: 35.232.62.64
      # Assuming 35.232.62.64 is the external IP address of a passthrough Network Load Balancer.
    
  • hostPort conflicto con el rango reservado NodePort:

    Si el hostPort de un Pod entra en conflicto con el rango de NodePort reservado (30000-32767), es posible que Cilium no pueda reenviar el tráfico al Pod. Este comportamiento se observó en las versiones de clúster 1.29 y posteriores, ya que Cilium ahora administra las capacidades de hostPort, lo que reemplaza el método anterior de Portmap. Este es un comportamiento esperado de Cilium y se menciona en su documentación pública.

No planeamos corregir estas limitaciones en versiones posteriores. La causa raíz de estos problemas se relaciona con el comportamiento de Cilium y está fuera del control directo de GKE.

Recomendación: Te recomendamos que migres a los servicios de NodePort en lugar de hostPort para mejorar la confiabilidad. NodePort Los servicios proporcionan capacidades similares.

Los rangos de puertos de la política de red no se aplican

Si especificas un campo endPort en una política de red en un clúster que tiene habilitado GKE Dataplane V2, no se aplicará.

A partir de GKE 1.22, la API de Kubernetes Network Policy te permite especificar un rango de puertos en los que se aplica la política de red. Esta API es compatible con clústeres con la política de red Calico, pero no con clústeres con GKE Dataplane V2.

Puedes verificar el comportamiento de tus objetos NetworkPolicy si los vuelves a leer después de escribirlos en el servidor de la API. Si el objeto todavía contiene el campo endPort, la función se aplica. Si falta el campo endPort, la función no se aplica. En todos los casos, el objeto almacenado en el servidor de la API es la fuente de información de la política de red.

Para obtener más información, consulta KEP-2079: Política de red que admite rangos de puertos.

Los Pods muestran un mensaje de error de failed to allocate for range 0: no IP addresses available in range set

Versiones afectadas de GKE: 1.22.0 a 1.25

Los clústeres de GKE que ejecutan grupos de nodos que usan containerd y tienen GKE Dataplane V2 habilitado pueden experimentar problemas de filtración de direcciones IP y agotar todas las direcciones IP de Pods en un nodo. Un Pod programado en un nodo afectado muestra un mensaje de error similar al siguiente:

failed to allocate for range 0: no IP addresses available in range set: 10.48.131.1-10.48.131.62

Para obtener más información sobre el problema, consulta el problema número 5768 de containerd.

Versiones fijas

Para solucionar este problema, actualiza tu clúster a una de las siguientes versiones de GKE:

  • 1.22.17-gke.3100 o superior
  • 1.23.16-gke.200 o superior
  • 1.24.9-gke.3200 o superior
  • 1.25.6-gke.200 o superior

Soluciones alternativas para clústeres de GKE estándar

Puedes mitigar este problema si borras las direcciones IP de Pods que se filtraron del nodo.

Para borrar las direcciones IP de Pods que se filtraron, obtén credenciales de autenticación para el clúster y ejecuta los siguientes pasos para limpiar un solo nodo, si conoces su nombre.

  1. Guarda la siguiente secuencia de comandos de shell en un archivo llamado cleanup.sh:

    for hash in $(sudo find /var/lib/cni/networks/gke-pod-network -iregex '/var/lib/cni/networks/gke-pod-network/[0-9].*' -exec head -n1 {} \;); do hash="${hash%%[[:space:]]}"; if [ -z $(sudo ctr -n k8s.io c ls | grep $hash | awk '{print $1}') ]; then sudo grep -ilr $hash /var/lib/cni/networks/gke-pod-network; fi; done | sudo xargs -r rm
    
  2. Ejecuta la secuencia de comandos en un nodo del clúster:

    gcloud compute ssh --zone "ZONE" --project "PROJECT" NODE_NAME --command "$(cat cleanup.sh)"
    

    Reemplaza NODE_NAME por el nombre del conjunto de datos.

También puedes ejecutar una versión de DaemonSet de esta secuencia de comandos para que se ejecute en paralelo en todos los nodos a la vez:

  1. Guarda el siguiente manifiesto como un archivo llamado cleanup-ips.yaml:

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: cleanup-ipam-dir
      namespace: kube-system
    spec:
      selector:
        matchLabels:
          name: cleanup-ipam
      template:
        metadata:
          labels:
            name: cleanup-ipam
        spec:
          hostNetwork: true
          securityContext:
            runAsUser: 0
            runAsGroup: 0
          containers:
          - name: cleanup-ipam
            image: gcr.io/gke-networking-test-images/ubuntu-test:2022
            command:
              - /bin/bash
              - -c
              - |
                while true; do
                for hash in $(find /hostipam -iregex '/hostipam/[0-9].*' -mmin +10 -exec head -n1 {} \; ); do
                hash="${hash%%[[:space:]]}"
                if [ -z $(ctr -n k8s.io c ls | grep $hash | awk '{print $1}') ]; then
                grep -ilr $hash /hostipam
                fi
                done | xargs -r rm
                echo "Done cleaning up /var/lib/cni/networks/gke-pod-network at $(date)"
                sleep 120s
                done
            volumeMounts:
            - name: host-ipam
              mountPath: /hostipam
            - name: host-ctr
              mountPath: /run/containerd
          volumes:
          - name: host-ipam
            hostPath:
              path: /var/lib/cni/networks/gke-pod-network
          - name: host-ctr
            hostPath:
              path: /run/containerd
    
  2. Ejecuta el daemonset en el clúster:

    kubectl apply -f cleanup-ips.yaml
    

    Debes tener acceso de kubectl como administrador del clúster para ejecutar este comando.

  3. Verifica los registros del DaemonSet en ejecución:

    kubectl -n kube-system logs -l name=cleanup-ipam
    

La política de red descarta una conexión debido a una búsqueda de seguimiento de conexión incorrecta

Cuando un Pod de cliente se conecta consigo mismo a través de un Service o la dirección IP virtual de un balanceador de cargas de red de transferencia interno, el paquete de respuesta no se identifica como parte de una conexión existente debido a una búsqueda de conntrack incorrecta en el plano de datos. Esto significa que una política de red que restringe el tráfico de entrada para el Pod se aplica de forma incorrecta en el paquete.

El impacto de este problema depende de la cantidad de Pods configurados para el Service. Por ejemplo, si el Service tiene 1 Pod de backend, la conexión siempre falla. Si el Service tiene 2 Pods de backend, la conexión falla el 50% del tiempo.

Versiones fijas

Para solucionar este problema, actualiza tu clúster a una de las siguientes versiones de GKE:

  • 1.28.3-gke.1090000 o superior.

Soluciones alternativas

Puedes mitigar este problema si configuras port y containerPort en el manifiesto del Service para que tengan el mismo valor.

Pérdida de paquetes para los flujos de conexión en horquilla

Cuando un Pod crea una conexión TCP a sí misma usando un Service, de modo que el Pod sea la fuente y el destino de la conexión, el seguimiento de conexión de eBPF de GKE Dataplane V2 realiza un seguimiento incorrecto de los estados de conexión, lo que genera entradas de conntrack filtradas.

Cuando se filtra una tupla de conexión (protocolo, IP de origen/destino y puerto de origen/destino), las conexiones nuevas que usan la misma tupla de conexión pueden provocar que se pierdan paquetes de retorno.

Versiones fijas

Para solucionar este problema, actualiza tu clúster a una de las siguientes versiones de GKE:

  • 1.28.3-gke.1090000 o superior
  • 1.27.11-gke.1097000 o superior

Soluciones alternativas

Aplica una de las siguientes soluciones:

  • Habilita la reutilización de TCP (keep-alive) para las aplicaciones que se ejecutan en Pods que pueden comunicarse con sí mismas a través de un Service. Esto evita que se emita la marca TCP FIN y se evite que se filtre la entrada de conntrack.

  • Cuando uses conexiones de corta duración, expón el Pod con un balanceador de cargas de proxy, como Gateway, para exponer el Service. Esto hace que el destino de la solicitud de conexión se establezca en la dirección IP del balanceador de cargas, lo que evita que GKE Dataplane V2 realice SNAT a la dirección IP de bucle invertido.

La actualización del plano de control de GKE provoca un bloqueo del pod anetd

Cuando actualizas un clúster de GKE que tiene habilitado GKE Dataplane V2 (ruta de datos avanzada) de la versión 1.27 a la 1.28, es posible que se produzca un interbloqueo. Es posible que las cargas de trabajo experimenten interrupciones debido a la incapacidad de finalizar Pods antiguos o programar componentes necesarios, como anetd.

Causa

El proceso de actualización del clúster aumenta el requisito de recursos para los componentes de GKE Dataplane V2. Este aumento puede generar contención de recursos, lo que interrumpe la comunicación entre el complemento de la interfaz de red de contenedor (CNI) de Cilium y el daemon de Cilium.

Síntomas

Es posible que veas los siguientes síntomas:

  • Los Pods anetd permanecen atascados en el estado Pending.
  • Los Pods de carga de trabajo se atascan en el estado Terminating.
  • Errores que indican fallas de comunicación de Cilium, como failed to connect to Cilium daemon.
  • Se producen errores durante la limpieza de los recursos de red para las zonas de pruebas de Pod, por ejemplo:

    1rpc error: code = Unknown desc = failed to destroy network for sandbox "[sandbox_id]": plugin type="cilium-cni" failed (delete): unable to connect to Cilium daemon... connection refused
    

Solución alternativa

Clústeres de Standard: Para resolver el problema y permitir que se programe el Pod anetd, aumenta temporalmente los recursos asignables en el nodo afectado.

  1. Para identificar el nodo afectado y verificar su CPU y memoria asignables, ejecuta el siguiente comando:

    kubectl get nodes $NODE_NAME -o json | jq '.status.allocatable | {cpu, memory}'
    
  2. Para aumentar temporalmente la CPU y la memoria asignables, ejecuta el siguiente comando:

    kubectl patch
    

Clústeres de Autopilot: Para resolver el problema de interbloqueo en los clústeres de Autopilot, libera recursos borrando a la fuerza el Pod afectado:

kubectl delete pod POD_NAME -n NAMESPACE --grace-period=0 --force

Reemplaza lo siguiente:

  • POD_NAME: el nombre del Pod.
  • NAMESPACE: Es el espacio de nombres del Pod.

Después de aumentar los recursos asignables en el nodo y cuando se complete la actualización de la versión 1.27 a la 1.28 de GKE, el Pod anetd se ejecutará en la versión más reciente.

¿Qué sigue?