Soluciona problemas de Ingress de GKE

Los problemas con Ingress en Google Kubernetes Engine (GKE) pueden impedir que el tráfico externo o interno llegue a tus servicios.

Usa este documento para encontrar soluciones a errores relacionados con la clase Ingress, las anotaciones de IP estática, los tamaños de claves de certificados y las interacciones con los niveles de red.

Esta información está dirigida a los administradores y operadores de la plataforma, y a los desarrolladores de aplicaciones que implementan y administran aplicaciones expuestas con Ingress en GKE. Para obtener más información sobre los roles comunes y las tareas de ejemplo a los que hacemos referencia en el contenido de Google Cloud , consulta Roles y tareas comunes del usuario de GKE.

Anotación incorrecta para la clase Ingress

Síntoma

Cuando creas un objeto Ingress, es posible que veas el siguiente error:

Missing one or more resources. If resource creation takes longer than expected, you might have an invalid configuration.

Causas posibles

Es posible que hayas configurado incorrectamente la clase de Ingress en el manifiesto cuando creaste el Ingress.

Solución

Para especificar una clase de Ingress, debes usar la anotación kubernetes.io/ingress.class. No puedes especificar un Ingress de GKE con spec.ingressClassName.

  • Para implementar un balanceador de cargas de aplicaciones interno, usa la anotación kubernetes.io/ingress.class: gce-internal.
  • Para implementar un balanceador de cargas de aplicaciones externo, usa la anotación kubernetes.io/ingress.class: gce.

Anotación incorrecta para la dirección IP estática

Síntoma

Cuando configuras un Ingress externo para que use una dirección IP estática, es posible que veas el siguiente error:

Error syncing to GCP: error running load balancer syncing routine: loadbalancer <Name of load balancer> does not exist: the given static IP name <Static IP> doesn't translate to an existing static IP.

Causas posibles

  • No creaste una dirección IP externa estática antes de implementar Ingress.
  • No estás usando la anotación correcta para tu tipo de balanceador de cargas.

Solución

Si configuras un objeto Ingress externo, haz lo siguiente:

Si configuras un Ingress interno, haz lo siguiente:

  • Reserva una dirección IP interna estática regional antes de implementar Ingress.
  • Usa la anotación kubernetes.io/ingress.regional-static-ip-name en tu recurso Ingress.

La dirección IP estática ya está en uso

Síntoma

Es posible que veas el siguiente error cuando especifiques una dirección IP estática para aprovisionar tu recurso Ingress interno o externo:

Error syncing to GCP: error running load balancer syncing
routine: loadbalancer <LB name> does not exist:
googleapi: Error 409: IP_IN_USE_BY_ANOTHER_RESOURCE - IP ''<IP address>'' is already being used by another resource.

Causas posibles

Otro recurso ya está usando la dirección IP estática.

Error al inhabilitar HTTP y usar un certificado administrado por Google

Síntoma

Si configuras un certificado SSL administrado por Google y inhabilitas el tráfico HTTP en tu Ingress, verás el siguiente error:

Error syncing to GCP: error running load balancer syncing
routine: loadbalancer <Load Balancer name> does not exist:
googleapi: Error 404: The resource ''projects/<Project>/global/sslPolicies/<Policy name>' was not found, notFound

Causas posibles

No puedes usar las siguientes anotaciones juntas cuando configures Ingress:

  • networking.gke.io/managed-certificates (para asociar el certificado administrado por Google a un Ingress)
  • kubernetes.io/ingress.allow-http: false (para inhabilitar el tráfico HTTP)

Solución

Inhabilita el tráfico HTTP solo después de que el balanceador de cargas de aplicaciones externo esté completamente programado. Puedes actualizar el Ingress y agregar la anotación kubernetes.io/ingress.allow-http: false al manifiesto.

Falta la subred de solo proxy para un Ingress interno

Síntoma

Cuando implementas un objeto Ingress para un balanceador de cargas de aplicaciones interno, es posible que veas el siguiente error:

Error syncing to GCP: error running load balancer syncing routine:
loadbalancer <LB name> does not exist: googleapi: Error 400: Invalid value for field 'resource.target': 'https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/<Region>/targetHttpsProxies/<Target proxy>'.
An active proxy-only subnetwork is required in the same region and VPC as
the forwarding rule.

Causas posibles

No creaste una subred de solo proxy antes de crear el recurso de Ingress. Se requiere una subred de solo proxy para los balanceadores de cargas de aplicaciones internos.

Solución

Crea una subred de solo proxy antes de implementar el Ingress interno.

La clave del certificado SSL es demasiado grande

Síntoma

Si el tamaño de la clave del certificado SSL de tu balanceador de cargas es demasiado grande, es posible que veas el siguiente error:

Error syncing to GCP: error running load balancer syncing routine: loadbalancer gky76k70-load-test-trillian-api-ingress-fliismmb does not exist: Cert creation failures - k8s2-cr-gky76k70-znz6o1pfu3tfrguy-f9be3a4abbe573f7 Error:googleapi: Error 400: The SSL key is too large., sslCertificateKeyTooLarge

Causas posibles

Google Cloud tiene un límite de 2,048 bits para las claves de certificados SSL.

Solución

Reduce el tamaño de la clave del certificado SSL a 2,048 bits o menos.

Error al crear un recurso Ingress en el nivel estándar

Síntoma

Si implementas un objeto Ingress en un proyecto con el nivel de red predeterminado del proyecto configurado como Estándar, aparecerá el siguiente mensaje de error:

Error syncing to GCP: error running load balancer syncing routine: load balancer <LB Name> does not exist: googleapi: Error 400: STANDARD network tier (the project''s default network tier) is not supported: STANDARD network tier is not supported for global forwarding rule., badRequest

Solución

Configura el nivel de red predeterminado del proyecto como Premium.

Se esperaba el error "Not Found" para k8s-ingress-svc-acct-permission-check-probe

El controlador de Ingress realiza comprobaciones periódicas de los permisos de la cuenta de servicio recuperando un recurso de prueba de tu proyecto de Google Cloud . Verás esto como GET de la BackendService global (no existente) con el nombre k8s-ingress-svc-acct-permission-check-probe. Como este recurso, por lo general, no debería existir, la solicitud GET mostrará “no encontrado”. Esto es normal; el controlador verifica que la llamada a la API no se rechace debido a problemas de autorización. Si creas un BackendService con el mismo nombre, la GET se realizará correctamente en lugar de mostrar “no encontrado”.

Errores al usar el balanceo de cargas nativo del contenedor

Usa las siguientes técnicas para verificar tu configuración de red. En las secciones a continuación, se explica cómo resolver problemas específicos relacionados con el balanceo de cargas nativo del contenedor.

  • Consulta la documentación del balanceo de cargas para obtener información sobre cómo enumerar los grupos de extremos de red.

  • Puedes encontrar el nombre y las zonas del NEG que corresponde a un servicio en la anotación neg-status del servicio. Obtén la especificación de servicio con el siguiente comando:

    kubectl get svc SVC_NAME -o yaml
    

    La anotación metadata:annotations:cloud.google.com/neg-status genera una lista del NEG correspondiente del servicio y las zonas del NEG.

  • Puedes verificar el estado del servicio de backend que corresponde a un NEG con el siguiente comando:

    gcloud compute backend-services --project PROJECT_NAME \
        get-health BACKEND_SERVICE_NAME --global
    

    El servicio de backend tiene el mismo nombre que su NEG.

  • Para imprimir los registros de eventos de un servicio, usa el siguiente comando:

    kubectl describe svc SERVICE_NAME
    

    La string de nombre del servicio incluye el nombre y el espacio de nombres del servicio GKE correspondiente.

No se puede crear un clúster con IP de alias

Síntomas

Cuando intentas crear un clúster con IP de alias, tal vez encuentres el error siguiente:

ResponseError: code=400, message=IP aliases cannot be used with a legacy network.
Causas posibles

Este error se produce si intentas crear un clúster con IP de alias que también usan redes heredadas.

Solución

Asegúrate de no crear un clúster con IP de alias y una red heredada habilitadas de forma simultánea. Para obtener más información sobre el uso de IP de alias, consulta Crea un clúster nativo de la VPC.

El tráfico no alcanza los extremos

Síntomas
502/503 o conexiones rechazadas.
Causas posibles

A los extremos nuevos, por lo general, se los puede alcanzar después de adjuntarlos al balanceador de cargas, siempre que respondan a la verificación de estado. Tal vez encuentres errores 502 o conexiones rechazadas si el tráfico no puede alcanzar los extremos.

Un contenedor que no controla SIGTERM, también puede provocar los errores 502 y las conexiones rechazadas. Si un contenedor no controla SIGTERM de forma explícita, termina y deja de controlar solicitudes de inmediato. El balanceador de cargas continúa enviando tráfico entrante al contenedor finalizado, lo que genera errores.

El balanceador de cargas nativo del contenedor solo tiene un extremo de backend. Durante una actualización progresiva, el extremo anterior se desprograma antes de que se programe el nuevo extremo.

Los Pods del backend se implementan en una zona nueva por primera vez después de que se aprovisiona un balanceador de cargas nativo del contenedor. La infraestructura del balanceador de cargas se programa en una zona cuando hay al menos un extremo en la zona. Cuando se agrega un extremo nuevo a una zona, se programa la infraestructura del balanceador de cargas y se interrumpe el servicio.

Solución

Configura los contenedores para manejar SIGTERM y continúa respondiendo a las solicitudes durante todo el período de gracia de terminación (30 segundos de forma predeterminada). Configura pods para comenzar a fallar las verificaciones de estado cuando reciben SIGTERM. Esto le indica al balanceador de cargas que deje de enviar tráfico al Pod mientras la desprogramación del extremo está en progreso.

Si la aplicación no se cierra de forma correcta y deja de responder a las solicitudes cuando se recibe un SIGTERM, el hook preStop puede usarse para manejar SIGTERM y seguir entregando tráfico mientras la desprogramación del extremo está en curso.

lifecycle:
  preStop:
    exec:
      # if SIGTERM triggers a quick exit; keep serving traffic instead
      command: ["sleep","60"]

Consulta la documentación sobre la terminación de Pods.

Si el backend del balanceador de cargas tiene una sola instancia, configura la estrategia de implementación para evitar que se destruya la única instancia antes de que la instancia nueva se programe por completo. En el caso de los pods de aplicaciones administrados por la carga de trabajo de Deployment, esto se puede lograr a través de la configuración de la estrategia de lanzamiento con el parámetro maxUnavailable igual a 0.

strategy:
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0

Para solucionar problemas de tráfico que no llega a los extremos, verifica que las reglas de firewall permitan el tráfico entrante de TCP a tus extremos en los rangos 130.211.0.0/22 y 35.191.0.0/16. Para obtener más información, consulta Crea verificaciones de estado en la documentación de Cloud Load Balancing.

Revisa los servicios de backend de tu proyecto. La string de nombre del servicio de backend relevante incluye el nombre y el espacio de nombres del servicio de GKE correspondiente:

gcloud compute backend-services list

Recupera el estado del backend desde el servicio de backend:

gcloud compute backend-services get-health BACKEND_SERVICE_NAME

Si todos los backends están en mal estado, puede que tu firewall, Ingress o servicio estén mal configurados.

Si algunos backends están en mal estado durante un período breve, la causa podría ser la latencia de programación de la red.

Si algunos backends no aparecen en la lista de servicios de backend, la causa podría ser la latencia de programación de la red. Puedes verificar esto con la ejecución del comando siguiente, en que NEG_NAME es el nombre del servicio de backend. (Los NEG y los servicios de backend comparten el mismo nombre):

gcloud compute network-endpoint-groups list-network-endpoints NEG_NAME

Verifica que todos los extremos esperados estén en el NEG.

Si tienes una pequeña cantidad de backends (por ejemplo, 1 Pod) seleccionados por un balanceador de cargas nativo del contenedor, considera aumentar la cantidad de réplicas y distribuir los Pods de backend en todas las zonas que abarca el clúster de GKE. Esto garantizará que la infraestructura del balanceador de cargas subyacente esté por completo programada. De lo contrario, considera restringir los Pods del backend a una sola zona.

Si configuras una política de red para el extremo, asegúrate de que se permita la entrada desde la subred de solo proxy.

Lanzamiento suspendido

Síntomas
El lanzamiento de un Deployment actualizado se suspende, y la cantidad de réplicas actualizadas no coincide con la cantidad seleccionada de réplicas.
Causas posibles

Las verificaciones de estado de la implementación están fallando. La imagen del contenedor puede ser mala o la verificación de estado puede estar mal configurada. El reemplazo continuo de pods espera hasta que el pod recién iniciado pase su puerta de preparación de pod. Esto solo ocurre si el Pod responde a las verificaciones de estado del balanceador de cargas. Si el Pod no responde o la verificación de estado está mal configurada, no se pueden cumplir las condiciones de la puerta de preparación y el lanzamiento no puede continuar.

Si usas kubectl 1.13 o superior, puedes verificar el estado de las puertas de preparación de un pod con el siguiente comando:

kubectl get pod POD_NAME -o wide

Verifica la columna READINESS GATES.

Esta columna no existe en kubectl 1.12 y versiones anteriores. Un pod que está marcado en estado READY puede tener una puerta de preparación con errores. Para verificar esto, usa el siguiente comando:

kubectl get pod POD_NAME -o yaml

Las puertas de preparación y sus estados se enumeran en la salida.

Solución

Verifica que la imagen del contenedor en la especificación de su pod de implementación funcione de forma correcta y pueda responder a las verificaciones de estado. Comprueba que las verificaciones de estado estén configuradas de forma correcta.

Errores de modo degradado

Síntomas

A partir de la versión 1.29.2-gke.1643000 de GKE, es posible que recibas las siguientes advertencias en tu servicio en el Explorador de registros cuando se actualicen los NEG:

Entering degraded mode for NEG <service-namespace>/<service-name>-<neg-name>... due to sync err: endpoint has missing nodeName field
Causas posibles

Estas advertencias indican que GKE detectó parámetros de configuración incorrectos de extremo durante una actualización de NEG basada en objetos EndpointSlice, lo que activa un proceso de cálculo más detallado llamado modo degradado. GKE continúa actualizando los NEG sobre la base del mejor esfuerzo, ya que corrige la configuración incorrecta o excluye los extremos no válidos de las actualizaciones del NEG.

A continuación, se indican algunos de los errores comunes:

  • endpoint has missing pod/nodeName field
  • endpoint corresponds to an non-existing pod/node
  • endpoint information for attach/detach operation is incorrect
Solución

Por lo general, los estados transitorios generan estos eventos y se fijan por sí solos. Sin embargo, los eventos causados por parámetros de configuración incorrectos en objetos EndpointSlice personalizados no se resuelven. Para comprender la configuración incorrecta, examina los objetos EndpointSlice correspondientes al servicio:

kubectl get endpointslice -l kubernetes.io/service-name=<service-name>

Valida cada extremo según el error en el evento.

Para resolver el problema, debes modificar de forma manual los objetos EndpointSlice. La actualización activa los NEG para que se actualicen de nuevo. Una vez que la configuración incorrecta ya no existe, el resultado es similar al siguiente:

NEG <service-namespace>/<service-name>-<neg-name>... is no longer in degraded mode

Errores al usar certificados SSL administrados por Google

En esta sección, se proporciona información para resolver problemas con los certificados administrados por Google.

Verifica eventos en ManagedCertificate y recursos de Ingress

Si excedes la cantidad de certificados permitidos, se agrega un evento con un motivo TooManyCertificates a ManagedCertificate. Puedes verificar los eventos en un objeto ManagedCertificate con el siguiente comando:

kubectl describe managedcertificate CERTIFICATE_NAME

Reemplaza CERTIFICATE_NAME por el nombre del ManagedCertificate.

Si conectas un ManagedCertificate no existente a un Ingress, se agrega un evento con un motivo MissingCertificate al Ingress. Puedes verificar los eventos en un recurso Ingress con el siguiente comando:

kubectl describe ingress INGRESS_NAME

Reemplaza INGRESS_NAME por el nombre de tu Ingress.

El certificado administrado no se aprovisiona cuando el dominio se resuelve en direcciones IP de varios balanceadores de cargas

Cuando tu dominio se resuelve en direcciones IP de varios balanceadores de cargas (varios objetos Ingress), debes crear un solo objeto ManagedCertificate y adjuntarlo a todos los objetos Ingress. Si, en cambio, creas muchos objetos ManagedCertificate y adjuntas cada uno a un Ingress distinto, es posible que la autoridad certificadora no pueda verificar la propiedad del dominio y algunos de tus certificados no lo hagan. Para que la verificación sea exitosa, el certificado debe estar visible en todas las direcciones IP a las que se resuelve el dominio.

De manera específica, cuando el dominio se resuelve en una dirección IPv4 y otra IPv6 configuradas con diferentes objetos del Ingress, debes crear un solo objeto de ManagedCertificate y conectarlo a ambos Ingress.

Comunicación interrumpida entre los certificados administrados por Google e Ingress

Los certificados administrados se comunican con el Ingress mediante la anotación ingress.gcp.kubernetes.io/pre-shared-cert. Puedes interrumpir esta comunicación, por ejemplo, si realizas estas acciones:

  • Ejecutas un proceso automatizado que borre la anotación ingress.gcp.kubernetes.io/pre-shared-cert.
  • Almacenas una instantánea del Ingress y, luego, borras y restableces el Ingress a partir de la instantánea. Mientras tanto, es posible que se haya borrado un recurso SslCertificate enumerado en la anotación ingress.gcp.kubernetes.io/pre-shared-cert. Ingress no funciona si falta alguno de sus certificados adjuntos.

Si se interrumpe la comunicación entre los certificados administrados por Google e Ingress, borra el contenido de la anotación ingress.gcp.kubernetes.io/pre-shared-cert y espera a que el sistema se concilie. Para evitar la recurrencia, asegúrate de que la anotación no se modifique ni se borre de forma involuntaria.

Errores de validación cuando se crea un certificado administrado por Google

Las definiciones de ManagedCertificate se validan antes de crear el objeto ManagedCertificate. Si la validación falla, el objeto ManagedCertificate no se crea y se imprime un mensaje de error. Los diferentes mensajes de error y los motivos se explican de la siguiente manera:

spec.domains in body should have at most 100 items

El manifiesto ManagedCertificate enumera más de 100 dominios en el campo spec.domains. Los certificados administrados por Google solo admiten hasta 100 dominios.

spec.domains in body should match '^(([a-zA-Z0-9]+|[a-zA-Z0-9][-a-zA-Z0-9]*[a-zA-Z0-9])\.)+[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]\.?$'

Especificaste un nombre de dominio no válido o un nombre de dominio comodín en el campo spec.domains. El objeto ManagedCertificate no admite dominios comodines (por ejemplo, *.example.com).

spec.domains in body should be at most 63 chars long

Especificaste un nombre de dominio que es demasiado largo. Los certificados administrados por Google admiten nombres de dominio con un máximo de 63 caracteres.

Actualiza de manera manual un certificado administrado por Google

Para actualizar el certificado de forma manual a fin de que el certificado del dominio anterior continúe funcionando hasta que se aprovisione el certificado del dominio nuevo, sigue estos pasos:

  1. Crea un ManagedCertificate para el dominio nuevo.
  2. Agrega el nombre de ManagedCertificate a la anotación networking.gke.io/managed-certificates en el Ingress mediante una lista separada por comas. No quites el nombre del certificado anterior.
  3. Espera hasta que ManagedCertificate se active.
  4. Desconecta el certificado anterior del Ingress y bórralo.

Cuando creas un ManagedCertificate, Google Cloud crea un certificado SSL administrado por Google. No puedes actualizar este certificado. Si actualizas el ManagedCertificate, Google Cloud borra y vuelve a crear el certificado SSL administrado por Google.

Para proporcionar Ingress encriptado con HTTPS seguro para tus clústeres de GKE, consulta el ejemplo Ingress seguro.

¿Qué sigue?