En esta página se explica cómo habilitar y solucionar problemas de GKE Dataplane V2 en clústeres de Google Kubernetes Engine (GKE).
Los nuevos clústeres de Autopilot tienen habilitado GKE Dataplane V2 en las versiones 1.22.7-gke.1500 y posteriores, y en las versiones 1.23.4-gke.1500 y posteriores. Si tienes problemas al usar Dataplane V2 de GKE, ve a la sección Solución de problemas.
Crear un clúster de GKE con GKE Dataplane V2
Puedes habilitar GKE Dataplane V2 al crear clústeres con GKE versión 1.20.6-gke.700 y posteriores mediante la CLI de gcloud o la API de GKE. También puedes habilitar GKE Dataplane V2 en Vista previa al crear clústeres con la versión 1.17.9 de GKE o una posterior.
Consola
Para crear un clúster con GKE Dataplane V2, realiza las siguientes tareas:
En la Trusted Cloud consola, ve a la página Crear un clúster de Kubernetes.
En la sección Redes, marca la casilla Habilitar Dataplane V2. La opción Habilitar política de red de Kubernetes está inhabilitada cuando se selecciona Habilitar Dataplane V2 porque la aplicación de la política de red está integrada en GKE Dataplane V2.
Haz clic en Crear.
gcloud
Para crear un clúster 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
Haz los cambios siguientes:
CLUSTER_NAME
: el nombre del nuevo clúster.CHANNEL_NAME
: un canal de lanzamiento que incluya la versión 1.20.6-gke.700 o posterior de GKE. Si prefieres no usar un canal de lanzamiento, puedes usar la marca--cluster-version
en lugar de--release-channel
y especificar la versión 1.20.6-gke.700 o posterior.COMPUTE_LOCATION
: la ubicación de Compute Engine del nuevo clúster.
API
Para crear un clúster con GKE Dataplane V2, especifica el campo datapathProvider
en el objeto networkConfig
de la solicitud create
de tu clúster.
El siguiente fragmento de JSON muestra la configuración necesaria para habilitar Dataplane V2 de GKE:
"cluster":{
"initialClusterVersion":"VERSION",
"ipAllocationPolicy":{
"useIpAliases":true
},
"networkConfig":{
"datapathProvider":"ADVANCED_DATAPATH"
},
"releaseChannel":{
"channel":"CHANNEL_NAME"
}
}
Haz los cambios siguientes:
- VERSION: la versión de tu clúster, que debe ser GKE 1.20.6-gke.700 o una posterior.
- CHANNEL_NAME: un canal de lanzamiento que incluya la versión 1.20.6-gke.700 de GKE o una posterior.
Solucionar problemas con GKE Dataplane V2
En esta sección se explica cómo investigar y resolver problemas con GKE Dataplane V2.
Confirma que GKE Dataplane V2 está habilitado:
kubectl -n kube-system get pods -l k8s-app=cilium -o wide
Si se está ejecutando GKE Dataplane V2, el resultado incluye pods con el prefijo
anetd-
. anetd es el controlador de redes de GKE Dataplane V2.Si el problema está relacionado con los servicios o la aplicación de la política de red, consulta los registros de
anetd
pod. Usa los siguientes selectores de registro en Cloud Logging:resource.type="k8s_container" labels."k8s-pod/k8s-app"="cilium" resource.labels.cluster_name="CLUSTER_NAME"
Si no se pueden crear pods, consulta los registros de kubelet para obtener información. Usa los siguientes selectores de registro en Cloud Logging:
resource.type="k8s_node" log_name=~".*/logs/kubelet" resource.labels.cluster_name="CLUSTER_NAME"
Sustituye
CLUSTER_NAME
por el nombre del clúster o elimínalo por completo para ver los registros de todos los clústeres.Si los pods
anetd
no se están ejecutando, examina el ConfigMap cilium-config para ver si hay alguna modificación. No modifiques los campos de este ConfigMap, ya que estos cambios pueden desestabilizar el clúster e interrumpiranetd
. El ConfigMap vuelve al estado predeterminado solo si se le añaden campos nuevos. Los cambios en los campos no se aplican y le recomendamos que no cambie ni personalice el ConfigMap.
Problemas conocidos
Problemas de conectividad intermitentes relacionados con conflictos de intervalos de NodePort
en clústeres de GKE Dataplane V2
En los clústeres de GKE Dataplane V2, pueden producirse problemas de conectividad intermitentes con el tráfico enmascarado o con el uso de puertos efímeros. Estos problemas se deben a posibles conflictos de puertos con el intervalo NodePort
reservado y suelen producirse en los siguientes casos:
Personalizado
ip-masq-agent
: si usas unip-masq-agent
personalizado (versión 2.10 o posterior) en el que el clúster tiene serviciosNodePort
o de balanceador de carga, es posible que observes problemas de conectividad intermitentes debido a su conflicto con el intervaloNodePort
. Desde la versión 2.10 y posteriores,ip-masq-agent
tiene el argumento--random-fully
implementado de forma interna de forma predeterminada. Para evitarlo, define explícitamente--random-fully=false
(aplicable desde la versión 2.11) en los argumentos de tu configuración deip-masq-agent
. Para obtener información sobre la configuración, consulta Configurar un agente de enmascaramiento de IP en clústeres estándar.Solapamiento del intervalo de puertos efímeros: si el intervalo de puertos efímeros definido por
net.ipv4.ip_local_port_range
en tus nodos de GKE se solapa con el intervaloNodePort
(30000-32767), también puede provocar problemas de conectividad. Para evitar este problema, asegúrese de que estos dos intervalos no se solapen.
Revisa la configuración de ip-masq-agent
y los ajustes del intervalo de puertos efímeros para asegurarte de que no entran en conflicto con el intervalo de NodePort
. Si tienes problemas de conectividad intermitentes, ten en cuenta estas posibles causas y ajusta tu configuración en consecuencia.
Problemas de conectividad con hostPort
en clústeres de GKE Dataplane V2
Versiones de GKE afectadas: 1.29 y posteriores
En los clústeres que usan GKE Dataplane V2, es posible que se produzcan fallos de conectividad cuando el tráfico se dirija a la dirección IP y el puerto de un nodo, donde el puerto es el hostPort
definido en el pod. Estos problemas se producen en dos situaciones principales:
Nodos con
hostPort
detrás de un balanceador de carga de red con paso a través:hostPort
vincula un pod al puerto de un nodo específico, y un balanceador de carga de red de transferencia directa distribuye el tráfico entre todos los nodos. Cuando expones pods a Internet mediantehostPort
y un balanceador de carga de red de tipo pasarela, el balanceador de carga puede enviar 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 de GKE Dataplane V2, donde el tráfico del balanceador de carga de red de transferencia no se reenvía de forma coherente a los pods dehostPort
.Solución alternativa: Cuando expongas los
hostPort
de un pod en el nodo con un balanceador de carga de red de pases, especifica la dirección IP interna o externa del balanceador de carga de red en el campohostIP
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 intervalo reservadoNodePort
:Si el
hostPort
de un pod entra en conflicto con el intervaloNodePort
reservado (30000-32767), es posible que Cilium no pueda reenviar el tráfico al pod. Este comportamiento se ha observado en las versiones de clúster 1.29 y posteriores, ya que Cilium ahora gestiona las funcioneshostPort
, lo que sustituye al método Portmap anterior. Este es el comportamiento esperado de Cilium y se menciona en su documentación pública.
No tenemos previsto solucionar estas limitaciones en versiones posteriores. La causa principal de estos problemas está relacionada 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 a hostPort
para mejorar la fiabilidad. NodePort
Los servicios ofrecen funciones similares.
Los intervalos de puertos de la política de red no se aplican
Si especifica un campo endPort
en una política de red de un clúster que tiene habilitado GKE Dataplane V2, no tendrá efecto.
A partir de GKE 1.22, la API de políticas de red de Kubernetes te permite especificar un intervalo de puertos en el que se aplica la política de red. Esta API se admite en clústeres con la política de red de Calico, pero no en clústeres con GKE Dataplane V2.
Puedes verificar el comportamiento de tus objetos NetworkPolicy
leyéndolos después de escribirlos en el servidor de la API. Si el objeto sigue conteniendo 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 veraz de la política de red.
Para obtener más información, consulta KEP-2079: Network Policy to support Port Ranges (KEP-2079: política de red para admitir intervalos de puertos).
Los pods muestran el mensaje de error failed to allocate for range 0: no IP addresses available in range set
Versiones de GKE afectadas: de la 1.22 a la 1.25
Los clústeres de GKE que ejecutan grupos de nodos que usan containerd y tienen habilitado GKE Dataplane V2 pueden experimentar problemas de filtración de direcciones IP y agotar todas las direcciones IP de los pods de 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 #5768 de containerd.
Versiones corregidas
Para solucionar este problema, actualiza tu clúster a una de las siguientes versiones de GKE:
- 1.22.17-gke.3100 o una versión posterior.
- 1.23.16-gke.200 o una versión posterior.
- 1.24.9-gke.3200 o una versión posterior.
- 1.25.6-gke.200 o una versión posterior.
Soluciones alternativas para clústeres de GKE estándar
Puedes mitigar este problema eliminando las direcciones IP de los pods filtradas del nodo.
Para eliminar las direcciones IP de Pod filtradas, obtén las credenciales de autenticación del clúster y sigue estos pasos para limpiar un solo nodo, si conoces su nombre.
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
Ejecuta la secuencia de comandos en un nodo del clúster:
gcloud compute ssh --zone "ZONE" --project "PROJECT" NODE_NAME --command "$(cat cleanup.sh)"
Sustituye
NODE_NAME
por el nombre del nodo.
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:
Guarda el siguiente manifiesto en 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
Ejecuta el daemonset en el clúster:
kubectl apply -f cleanup-ips.yaml
Para ejecutar este comando, debes tener acceso a kubectl como administrador del clúster.
Consulta los registros del DaemonSet en ejecución:
kubectl -n kube-system logs -l name=cleanup-ipam
Network Policy elimina una conexión debido a una búsqueda de seguimiento de conexiones incorrecta
Cuando un pod de cliente se conecta a sí mismo mediante un servicio o la dirección IP virtual de un balanceador de carga de red de transferencia interno, el paquete de respuesta no se identifica como parte de una conexión existente debido a una búsqueda incorrecta de conntrack en el plano de datos. Esto significa que una política de red que restringe el tráfico de entrada del pod se aplica incorrectamente al paquete.
El impacto de este problema depende del número de pods configurados para el servicio. Por ejemplo, si el servicio tiene un pod de backend, la conexión siempre falla. Si el servicio tiene dos pods backend, la conexión falla el 50% de las veces.
Versiones corregidas
Para solucionar este problema, actualiza tu clúster a una de las siguientes versiones de GKE:
- 1.28.3-gke.1090000 o versiones posteriores.
Soluciones
Para mitigar este problema, configure los valores de port
y containerPort
en el manifiesto de servicio para que sean iguales.
Paquetes descartados en flujos de conexión en bucle
Cuando un pod crea una conexión TCP consigo mismo mediante un servicio, de forma que el pod es tanto el origen como el destino de la conexión, el seguimiento de conexiones eBPF de Dataplane V2 de GKE registra incorrectamente los estados de la conexión, lo que provoca que se filtren entradas de conntrack.
Cuando se ha filtrado una tupla de conexión (protocolo, IP de origen o destino y puerto de origen o destino), las nuevas conexiones que usen la misma tupla de conexión pueden provocar que se descarten los paquetes de retorno.
Versiones corregidas
Para solucionar este problema, actualiza tu clúster a una de las siguientes versiones de GKE:
- 1.28.3-gke.1090000 o posterior
- 1.27.11-gke.1097000 o versiones posteriores
Soluciones
Usa una de las siguientes soluciones alternativas:
Habilita la reutilización de TCP (keep-alives) para las aplicaciones que se ejecutan en pods que pueden comunicarse entre sí mediante un servicio. De esta forma, se evita que se emita la marca FIN de TCP y que se filtre la entrada de conntrack.
Cuando se usan conexiones de corta duración, expón el pod mediante un balanceador de carga de proxy, como Gateway, para exponer el servicio. De este modo, el destino de la solicitud de conexión se establece en la dirección IP del balanceador de carga, lo que impide que GKE Dataplane V2 realice SNAT en la dirección IP de bucle de retorno.
La actualización del plano de control de GKE provoca un anetd
bloqueo de pods
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 sufran interrupciones debido a la imposibilidad de finalizar pods antiguos o programar componentes necesarios, como anetd
.
Causa
El proceso de actualización del clúster aumenta los requisitos de recursos de los componentes de GKE Dataplane V2. Este aumento puede provocar una contención de recursos, lo que interrumpe la comunicación entre el complemento de interfaz de red de contenedores (CNI) de Cilium y el daemon de Cilium.
Síntomas
Es posible que veas los siguientes síntomas:
- Los
anetd
pods se quedan atascados en el estadoPending
. - Los pods de carga de trabajo se bloquean en el estado
Terminating
. - Errores que indican fallos de comunicación de Cilium, como
failed to connect to Cilium daemon
. Errores durante la limpieza de recursos de red de los sandboxes de pods. 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
Clústeres estándar: para resolver el problema y permitir que se programe el anetd
pod, aumenta temporalmente los recursos asignables en el nodo afectado.
Para identificar el nodo afectado y comprobar la CPU y la memoria asignables, ejecuta el siguiente comando:
kubectl get nodes $NODE_NAME -o json | jq '.status.allocatable | {cpu, memory}'
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 eliminando el pod afectado de forma forzada:
kubectl delete pod POD_NAME -n NAMESPACE --grace-period=0 --force
Haz los cambios siguientes:
POD_NAME
: el nombre del pod.NAMESPACE
: el espacio de nombres del pod.
Después de aumentar los recursos asignables del 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.
Siguientes pasos
- Usa el registro de políticas de red para registrar cuándo se permiten o se deniegan las conexiones a los pods mediante las políticas de red de tu clúster.
- Consulta cómo funciona GKE Dataplane V2.