Configura el balanceo de cargas HTTP(S) con Ingress

En este instructivo, se muestra cómo ejecutar una aplicación web detrás de un balanceador de cargas HTTP(S) externo mediante la configuración del recurso Ingress.

Información general

Google Kubernetes Engine (GKE) ofrece compatibilidad integrada con dos tipos de Cloud Load Balancing para una aplicación de acceso público:

  • Cuando especificas type:LoadBalancer en el manifiesto de recursos, GKE crea un objeto Service de tipo LoadBalancer. GKE realiza llamadas a la API de Google Cloud adecuadas para crear un balanceador de cargas de red externo o un balanceador de cargas TCP/UDP interno. GKE crea un balanceador de cargas TCP/UDP interno cuando agregas la anotación cloud.google.com/load-balancer-type: "Internal". De lo contrario, GKE crea un balanceador de cargas de red externo.

    Aunque puedes usar cualquiera de estos tipos de balanceadores de cargas para el tráfico HTTP(S) y, además, operan en 3/4 capas de OSI y no conocen las conexiones HTTP ni las solicitudes y respuestas HTTP individuales. Otra característica importante es que las solicitudes no se dirigen al destino.

  • Cuando especificas kind:Ingress en el manifiesto de recursos, le indicas a GKE que cree un recurso Ingress. Si incluyes anotaciones y cargas de trabajo y objetos Service compatibles, puedes crear un controlador Ingress personalizado. De lo contrario, GKE realiza llamadas a la API de Google Cloud adecuadas para crear un balanceador de cargas HTTP(S) externo. Las reglas de host y los comparadores de rutas de acceso de la asignación de URL del balanceador de cargas hacen referencia a uno o más servicios de backend, en el que cada servicio de backend corresponde a un Service de tipo NodePort de GKE, como se indica en Ingress. Los backends para cada servicio de backend son grupos de instancias o grupos de extremos de red (NEG). Los NEG se crean cuando configuras el balanceo de cargas nativo del contenedor como parte de la configuración del Ingress. Para cada servicio de backend, GKE crea una verificación de estado de Google Cloud, según la configuración del sondeo de preparación de la carga de trabajo a la que hace referencia el Service de GKE correspondiente.

    Si estás exponiendo un servicio HTTP(S) alojado en GKE, el método recomendado para el balanceo de cargas es balanceo de cargas HTTP(S).

Antes de comenzar

Sigue los pasos que se indican a continuación para habilitar la API de Kubernetes Engine:
  1. Consulta la página de Kubernetes Engine en Google Cloud Console.
  2. Crea o selecciona un proyecto.
  3. Espera a que la API y los servicios relacionados se habiliten. Esto puede tardar varios minutos.
  4. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud. Obtén información sobre cómo confirmar que tienes habilitada la facturación para tu proyecto.

Instala las siguientes herramientas de línea de comandos de este instructivo:

  • gcloud se usa para crear y borrar clústeres de Kubernetes Engine. gcloud se incluye en el SDK de Google Cloud.
  • kubectl se usa para administrar Kubernetes, el sistema de organización de clústeres que emplea Kubernetes Engine. Puedes instalar kubectl mediante gcloud:
    gcloud components install kubectl

Cómo establecer valores predeterminados para la herramienta de línea de comandos de gcloud

Para ahorrar tiempo cuando escribes las opciones del ID del proyecto y la zona de Compute Engine en la herramienta de línea de comandos de gcloud, puedes establecer los valores predeterminados:
gcloud config set project project-id
gcloud config set compute/zone compute-zone

Crea un clúster de contenedor

Crea un clúster de contenedor llamado loadbalancedcluster. Para ello, ejecuta el comando siguiente:

gcloud container clusters create loadbalancedcluster

Paso 1: Implementa una aplicación web

Crea una implementación con la imagen de muestra del contenedor de la aplicación web que escucha en un servidor HTTP en el puerto 8080:

  1. Descarga el manifiesto web-deployment.yaml.
  2. Aplica el recurso al clúster:

    kubectl apply -f web-deployment.yaml
    

Paso 2: Expón tu objeto Deployment como un Service de forma interna

Crea un recurso de Service para hacer que la implementación web sea accesible dentro del clúster del contenedor.

  1. Descarga el manifiesto web-service.yaml.
  2. Aplica el recurso al clúster:

    kubectl apply -f web-service.yaml
    

    Cuando creas un servicio de tipo NodePort con este comando, GKE hace que tu servicio esté disponible en un número alto de puerto seleccionado de forma aleatoria (p. ej., 32640) en todos los nodos de tu clúster.

  3. Verifica que se haya creado el servicio y que se haya asignado un puerto de nodo:

    kubectl get service web
    
    Resultado:
    NAME      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
    web       NodePort   10.35.245.219   <none>        8080:32640/TCP   5m
    

    En el resultado de muestra anterior, el puerto de nodo para el servicio web es 32640. Además, ten en cuenta que no hay ninguna IP externa asignada para este servicio. Dado que los nodos GKE no son accesibles externamente de manera predeterminada, crear este servicio no hace que tu aplicación sea accesible desde Internet.

Para que tu aplicación de servidor web HTTP(S) sea de acceso público, debes crear un recurso Ingress.

Paso 3: Crea un recurso Ingress

Ingress es un recurso de Kubernetes que encapsula una colección de reglas y configuración para enrutar el tráfico HTTP(S) externo a los servicios internos.

En GKE, Ingress se implementa con Cloud Load Balancing. Cuando creas un Ingress en tu clúster, GKE crea un balanceador de cargas de HTTP(S) y lo configura para enrutar el tráfico a tu aplicación.

Si bien el Ingress de Kubernetes es un recurso Beta, lo que significa que la forma en que describes el objeto de Ingress está sujeta a cambios, los balanceadores de cargas de Cloud que el GKE dispone a fin de implementar Ingress están listos para la producción.

En el siguiente archivo de configuración, se define un recurso Ingress que dirige el tráfico a tu Service web:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: basic-ingress
spec:
  backend:
    serviceName: web
    servicePort: 8080

A fin de implementar este recurso Ingress, sigue estos pasos:

  1. Descarga el manifiesto basic-ingress.yaml.
  2. Aplica el recurso al clúster:

    kubectl apply -f basic-ingress.yaml
    

Una vez que implementas este manifiesto, Kubernetes crea un recurso Ingress en tu clúster. El controlador de Ingress de GKE crea y configura un balanceador de cargas de HTTP(S) de acuerdo con la información de Ingress y enruta todo el tráfico HTTP externo (en el puerto 80) al Service NodePort web que expones.

Paso 4: Visita tu aplicación

Averigua la dirección IP externa del balanceador de cargas que entrega tu aplicación ejecutando lo siguiente:

kubectl get ingress basic-ingress
Resultado:
NAME            HOSTS     ADDRESS         PORTS     AGE
basic-ingress   *         203.0.113.12    80        2m

Dirige tu navegador a la dirección IP externa de tu aplicación y observa una respuesta HTTP de texto sin formato como el siguiente ejemplo:

Hello, world!
Version: 1.0.0
Hostname: web-6498765b79-fq5q5

Puedes visitar Balanceo de cargas en Cloud Console para inspeccionar los recursos de red que crea el controlador Ingress.

Paso 5: Configura una dirección IP estática (opcional)

Cuando expones un servidor web en un nombre de dominio, necesitas que la dirección IP externa de una aplicación sea una IP estática que no cambie.

Según la configuración predeterminada, GKE asigna direcciones IP externas efímeras a las aplicaciones HTTP expuestas a través de un Ingress. Las direcciones efímeras están sujetas a cambios. Para una aplicación web que planeaste durante mucho tiempo, necesitas usar una dirección IP externa estática.

Ten en cuenta que una vez que configures una IP estática para el recurso Ingress, borrar Ingress no eliminará la dirección IP estática asociada a él. Asegúrate de limpiar las direcciones IP estáticas que configuraste una vez que ya no planees usarlas nuevamente.

Opción 1: Convierte la dirección IP efímera existente en una dirección IP estática

Si ya tienes un Ingress implementado, puedes convertir la dirección IP efímera existente de tu aplicación en una dirección IP estática reservada sin cambiar la dirección IP externa si visitas la sección Direcciones IP externas en Cloud Console.

Opción 2: Reserva una nueva dirección IP estática

  1. Reserva una dirección IP externa estática llamada web-static-ip.

    gcloud

    gcloud compute addresses create web-static-ip --global
    

    Config Connector

    Nota: En este paso, se necesita Config Connector. Sigue las instrucciones de instalación para instalar Config Connector en el clúster.

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: web-static-ip
    spec:
      location: global
    Para implementar este manifiesto, descárgalo en tu máquina como compute-address.yaml y ejecuta lo siguiente:
    kubectl apply -f compute-address.yaml

  2. Configura el recurso Ingress existente para usar la dirección IP reservada. Reemplaza el manifiesto basic-ingress.yaml que usaste antes por el siguiente manifiesto:

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: basic-ingress
      annotations:
        kubernetes.io/ingress.global-static-ip-name: "web-static-ip"
    spec:
      backend:
        serviceName: web
        servicePort: 8080
    

    Este cambio agrega una anotación al Ingress para usar el recurso IP estático llamado web-static-ip.

  3. Aplica esta modificación al Ingress existente:

    kubectl apply -f basic-ingress.yaml
    
  4. Verifica la dirección IP externa:

    kubectl get ingress basic-ingress
    

    Espera hasta que la dirección IP de la aplicación cambie para usar la dirección IP reservada del recurso web-static-ip.

    Puede tomar un par de minutos actualizar el recurso Ingress existente, volver a configurar el balanceador de cargas y propagar las reglas del balanceo de cargas este en todo el mundo. Una vez que se complete esta operación, GKE libera la dirección IP efímera previamente asignada a tu aplicación.

Paso 6: Entrega varias aplicaciones en un balanceador de cargas (opcional)

Puedes ejecutar múltiples servicios en una IP pública y un único balanceador de cargas si configuras las reglas de enrutamiento en el Ingress. Si alojas varios servicios en el mismo Ingress, se evita tener que crear balanceadores de cargas adicionales (que son recursos facturables) para cada servicio que expones en Internet.

Crea otra implementación de servidor web con la versión 2.0 de la misma aplicación web.

Descarga web-deployment-v2.yaml y, luego, aplica el recurso al clúster:

kubectl apply -f web-deployment-v2.yaml

Luego, expón la implementación web2 al clúster de forma interna en un servicio NodePort llamado web2.

Descarga web-service-v2.yaml y, luego, aplica el recurso al clúster:

kubectl apply -f web-service-v2.yaml

En el siguiente manifiesto, se describe un recurso Ingress que realiza las acciones siguientes:

  • Enruta las solicitudes con una ruta que comienza con /v2/ al servicio web2.
  • Enruta todas las demás solicitudes al servicio web.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: fanout-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: web
          servicePort: 8080
      - path: /v2/*
        backend:
          serviceName: web2
          servicePort: 8080

Para implementar este manifiesto, guárdalo en un fanout-ingress.yaml y ejecuta lo siguiente:

kubectl create -f fanout-ingress.yaml

Una vez que Ingress se haya implementado, ejecuta kubectl get ingress fanout-ingress para buscar la dirección IP pública del clúster.

Luego, visita la dirección IP para ver si se puede acceder a ambas aplicaciones en el mismo balanceador de cargas:

  • Visita http://<IP_ADDRESS>/ y presta atención a la respuesta, que contiene Version: 1.0.0 (ya que la solicitud se enruta al servicio web)
  • Visita http://<IP_ADDRESS>/v2/ y presta atención a la respuesta, que contiene Version: 2.0.0 (ya que la solicitud se enruta al servicio web2)

El único patrón de comodín compatible que coincide con el campo de path en GKE Ingress es a través del carácter *. Por ejemplo, puedes tener reglas con campos path, como /* o /foo/bar/*. Consulta la documentación de mapas de URL para conocer las limitaciones de path.

Paso 7: Supervisa la disponibilidad y la latencia de tu servicio (opcional)

Las verificaciones de tiempo de actividad de Google Cloud realizan una supervisión de las aplicaciones de caja negra desde el punto de vista del usuario y determinan la latencia y la disponibilidad de varias direcciones IP externas en el balanceador de cargas. En comparación, las verificaciones de estado de Google Cloud realizan una verificación interna de las IP del Pod, lo que determina la disponibilidad a nivel de la instancia. Estas verificaciones son complementarias y proporcionan un panorama integral del estado de la aplicación.

Puedes crear una verificación de tiempo de actividad mediante Google Cloud Console, la API de Cloud Monitoring o las bibliotecas cliente de Cloud Monitoring. Para obtener información, consulta Administra verificaciones de tiempo de actividad. Si deseas crear una verificación de tiempo de actividad mediante Google Cloud Console, haz lo siguiente:

  1. En Google Cloud Console, selecciona Monitoring o haz clic en el siguiente botón:

    Ir a Monitoring

  2. En el panel de navegación Monitoring, selecciona Verificaciones de tiempo de actividad y haz clic en Crear una verificación de tiempo de actividad.

  3. Para el objetivo de tu verificación de tiempo de actividad, configura los siguientes campos:

    • Selecciona el tipo de protocolo como TCP.
    • En Tipo de recurso, selecciona URL.
    • En Nombre de host, ingresa la dirección IP del balanceador de cargas.
    • Ingresa el número de puerto del balanceador de cargas en el campo Puerto.

    Para obtener la documentación completa sobre todos los campos de una verificación de tiempo de actividad, consulta Crea una verificación de tiempo de actividad.

Para supervisar una verificación de tiempo de actividad, puedes crear una política de alertas o ver el panel de verificación de tiempo de actividad. Una política de alertas puede notificarte por correo electrónico o a través de un canal diferente si falla la verificación de tiempo de actividad. Para obtener información general sobre las políticas de alertas, consulta Introducción a las alertas.

Comentarios

De forma predeterminada, Ingress realiza una verificación de estado periódica mediante una solicitud GET en la ruta / a fin de determinar el estado de la aplicación y espera una respuesta HTTP 200. Si deseas verificar una ruta diferente o esperar un código de respuesta diferente, puedes usar una ruta de verificación de estado personalizada.

Ingress admite casos prácticos más avanzados, como los que se muestran a continuación:

  • Hosting virtual basado en nombre: Puedes usar Ingress para volver a usar el balanceador de cargas en varios nombres de dominio, subdominios y exponer diversos servicios en una única dirección IP y balanceador de cargas. Accede a los ejemplos de fanout simple y hosting virtual basado en nombre para aprender a configurar Ingress en estas tareas.

  • Finalización de HTTPS: Puedes configurar Ingress para que finalice el tráfico HTTPS con el balanceador de cargas de Cloud.

Cuando se borra un Ingress, el controlador del Ingress limpia los recursos asociados (excepto las direcciones IP estáticas reservadas) automáticamente.

Limpieza

Sigue estos pasos para evitar que se apliquen cargos a tu cuenta de Google Cloud Platform por los recursos que usaste en el instructivo:

  1. Borra las reglas de reenvío que se crearon de forma manual y los proxies de destino que hagan referencia al Ingress:

    Un proxy de destino que hace referencia a un mapa de URL administrado por el controlador de Ingress hará que la eliminación del Ingress falle en las versiones 1.15.4-gke.22+ de GKE. Se puede inspeccionar el recurso de Ingress para encontrar un evento con un mensaje de error similar al siguiente:

     Error during GC: error running load balancer garbage collection routine: googleapi: Error 400: The url_map resource 'projects/project-id/global/urlMaps/k8s2-um-tlw9rhgp-default-my-ingress-9ifnni82' is already being used by 'projects/project-id/global/targetHttpsProxies/k8s2-um-tlw9rhgp-default-my82-target-proxy', resourceInUseByAnotherResource
     

    En el mensaje de error de muestra anterior, k8s2-um-tlw9rhgp-default-my82-target-proxy es un proxy https de destino creado de forma manual que todavía hace referencia al mapa de URL k8s2-um-tlw9rhgp-default-my-ingress-9ifnni82 que creó y administró el controlador de Ingress.

    Por lo tanto, estos recursos de frontend creados de forma manual (la regla de reenvío y el proxy de destino) deben borrarse antes de continuar con la eliminación del Ingress.

  2. Borra el Ingress: Esto desasigna la dirección IP externa efímera y los recursos de balanceo de cargas asociados a tu aplicación:

    kubectl delete ingress basic-ingress

    Si has seguido el "Paso 6", borra el Ingress ejecutando:

    kubectl delete ingress fanout-ingress

  3. Borra la dirección IP estática: Ejecuta esto solo si seguiste el Paso 5.

    • Si seguiste la “Opción 1” en el Paso 5 para convertir una dirección IP efímera existente en IP estática, visita Cloud Console para borrar la IP estática.

    • Si seguiste la "Opción 2" en el Paso 5, ejecuta el siguiente comando para borrar la dirección IP estática:

      gcloud compute addresses delete web-static-ip --global
  4. Borra el clúster: Esto borra los nodos de procesamiento de tu clúster del contenedor y otros recursos, como las implementaciones en el clúster:

    gcloud container clusters delete loadbalancedcluster

Próximos pasos