Configurar un balanceador de carga de aplicación externo con Ingress

En este tutorial se muestra cómo ejecutar una aplicación web detrás de un balanceador de carga de aplicaciones externo configurando el recurso Ingress.

Esta página está dirigida a especialistas en redes que diseñan y desarrollan la red de su organización, así como instalan, configuran y ofrecen asistencia para los equipos de red. Para obtener más información sobre los roles habituales y las tareas de ejemplo a las que hacemos referencia en el contenido, consulta Roles y tareas de usuario habituales de GKE.Google Cloud

Fondo

Google Kubernetes Engine (GKE) ofrece asistencia integrada para dos tipos de Cloud Load Balancing para una aplicación accesible públicamente:

  1. Entrada

  2. Balanceador de carga de red de paso a través externo

En este tutorial, usarás Ingress.

Entrada

Cuando especifica kind: Ingress en un manifiesto de recursos, indica a GKE que cree un recurso Ingress. Si incluye anotaciones y cargas de trabajo y servicios compatibles, puede crear un controlador de Ingress personalizado. De lo contrario, GKE hará las llamadas a la API adecuadas para crear un balanceador de carga de aplicaciones externo. Google Cloud Las reglas de host y los matchers de ruta del mapa de URLs del balanceador de carga hacen referencia a uno o varios servicios de backend, donde cada servicio de backend corresponde a un Service de GKE de tipo NodePort, tal como se indica en Ingress. Los backends de cada servicio de backend son grupos de instancias o grupos de puntos finales de red (NEGs). Los NEGs se crean cuando configura el balanceo de carga nativo de contenedores como parte de la configuración de su objeto Ingress. Por cada servicio de backend, GKE crea una Google Cloud comprobación del estado basada en los ajustes de la sonda de preparación de la carga de trabajo a la que hace referencia el servicio de GKE correspondiente.

Si expones un servicio HTTP(S) alojado en GKE, el balanceo de carga HTTP(S) es el método recomendado para balancear la carga.

Objetivos

  • Crea un clúster de GKE.
  • Despliega la aplicación web de ejemplo en el clúster.
  • Expón la aplicación de muestra a Internet a través de un balanceador de carga de aplicación externo.

Costes

En este documento, se utilizan los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costes basada en el uso previsto, utiliza la calculadora de precios.

Los usuarios nuevos Google Cloud pueden disfrutar de una prueba gratuita.

Cuando termines las tareas que se describen en este documento, puedes evitar que se te siga facturando eliminando los recursos que has creado. Para obtener más información, consulta la sección Limpiar.

Antes de empezar

Sigue estos pasos para habilitar la API de Kubernetes Engine:
  1. Ve a la página de Kubernetes Engine en la Google Cloud consola.
  2. Crea o selecciona un proyecto.
  3. Espera a que la API y los servicios relacionados se habiliten. Este proceso puede tardar varios minutos.
  4. Verify that billing is enabled for your Google Cloud project.

Instala las siguientes herramientas de línea de comandos utilizadas en este tutorial:

  • gcloud se usa para crear y eliminar clústeres de Kubernetes Engine. gcloud se incluye en la CLI de gcloud.
  • kubectl se usa para gestionar Kubernetes, el sistema de orquestación de clústeres que utiliza Kubernetes Engine. Puedes instalar kubectl con gcloud:
    gcloud components install kubectl

Clona el código de ejemplo de GitHub:

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/networking/load-balancing

Configurar los valores predeterminados de la herramienta de línea de comandos gcloud

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

Crear un clúster de GKE

Crea un clúster de Autopilot de GKE:

gcloud container clusters create-auto loadbalancedcluster

Desplegar una aplicación web

El siguiente manifiesto describe un Deployment que ejecuta la imagen de contenedor de la aplicación web de ejemplo en un servidor HTTP en el puerto 8080:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: default
spec:
  selector:
    matchLabels:
      run: web
  template:
    metadata:
      labels:
        run: web
    spec:
      containers:
      - image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
        imagePullPolicy: IfNotPresent
        name: web
        ports:
        - containerPort: 8080
          protocol: TCP

Aplica el recurso al clúster:

kubectl apply -f web-deployment.yaml

Exponer un Deployment en un clúster

El siguiente manifiesto describe un Service que hace que la implementación de web sea accesible en tu clúster de contenedores:

apiVersion: v1
kind: Service
metadata:
  name: web
  namespace: default
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    run: web
  type: NodePort
  1. 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 de puerto alto seleccionado aleatoriamente (por ejemplo, 32640) en todos los nodos de tu clúster.

  2. 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 ejemplo de salida, el puerto de nodo del servicio web es 32640. Recuerda además que no hay una IP externa asignada para este servicio. Como los nodos de GKE no son accesibles externamente de forma predeterminada, la creación de este servicio no hace que tu aplicación sea accesible desde Internet.

Para que se pueda acceder públicamente a tu aplicación de servidor web HTTP(S), debes crear un recurso Ingress.

Crear un recurso Ingress

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

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

El siguiente manifiesto describe un recurso Ingress que dirige el tráfico a tu servicio web:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: basic-ingress
spec:
  defaultBackend:
    service:
      name: web
      port:
        number: 8080

Aplica el recurso al clúster:

kubectl apply -f basic-ingress.yaml

Después de desplegar este manifiesto, Kubernetes crea un recurso Ingress en tu clúster. El controlador Ingress de GKE crea y configura un balanceador de carga HTTP(S) según la información de Ingress, y dirige todo el tráfico HTTP externo (en el puerto 80) al web servicio NodePort que has expuesto.

Visitar tu aplicación

Busca la dirección IP externa del balanceador de carga que sirve tu aplicación ejecutando:

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

Abre la dirección IP externa de tu aplicación en un navegador y verás una respuesta HTTP de texto sin formato como la siguiente:

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

Puede visitar Balanceo de carga en la consola Google Cloud e inspeccionar los recursos de red creados por el controlador de Ingress de GKE.

(Opcional) Configurar una dirección IP estática

Cuando publicas 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.

De forma predeterminada, GKE asigna direcciones IP externas efímeras a las aplicaciones HTTP expuestas a través de un objeto Ingress. Las direcciones efímeras están sujetas a cambios. Si tienes previsto ejecutar tu aplicación durante mucho tiempo, debes usar una dirección IP externa estática.

Ten en cuenta que, después de configurar una IP estática para el recurso Ingress, si eliminas el recurso Ingress, no se eliminará la dirección IP estática asociada. No olvides eliminar las direcciones IP estáticas que hayas configurado cuando ya no tengas previsto volver a usarlas.

Para configurar una dirección IP estática, sigue estos pasos:

  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: Para este paso se necesita Config Connector. Sigue las instrucciones de instalación para instalar Config Connector en tu clúster.

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

  2. El manifiesto basic-ingress-static.yaml añade una anotación en Ingress para usar el recurso de IP estática llamado web-static-ip:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: basic-ingress
      annotations:
        kubernetes.io/ingress.global-static-ip-name: "web-static-ip"
    spec:
      defaultBackend:
        service:
          name: web
          port:
            number: 8080

    Para ver el archivo de manifiesto, haz lo siguiente:

    cat basic-ingress-static.yaml
    
  3. Aplica el recurso al clúster:

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

    kubectl get ingress basic-ingress
    

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

    Puede que tarde unos minutos en actualizar el recurso Ingress, volver a configurar el balanceador de carga y propagar las reglas de balanceo de carga por todo el mundo. Una vez completada esta operación, GKE libera la dirección IP efímera asignada anteriormente a tu aplicación.

(Opcional) Servir varias aplicaciones en un balanceador de carga

Es posible ejecutar múltiples servicios en un solo balanceador de carga e IP pública configurando reglas de enrutamiento en el Ingress. Si alojas varios servicios en el mismo Ingress, puedes evitar crear balanceadores de carga adicionales (que son recursos facturables) para cada servicio que expongas en Internet.

El siguiente archivo de manifiesto describe una implementación con la versión 2.0 de la misma aplicación web:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web2
  namespace: default
spec:
  selector:
    matchLabels:
      run: web2
  template:
    metadata:
      labels:
        run: web2
    spec:
      containers:
      - image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
        imagePullPolicy: IfNotPresent
        name: web2
        ports:
        - containerPort: 8080
          protocol: TCP

Aplica el recurso al clúster:

kubectl apply -f web-deployment-v2.yaml

El siguiente manifiesto describe un servicio que expone web2 internamente al clúster en un servicio NodePort llamado web2:

apiVersion: v1
kind: Service
metadata:
  name: web2
  namespace: default
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    run: web2
  type: NodePort

Aplica el recurso al clúster:

kubectl apply -f web-service-v2.yaml

El siguiente manifiesto describe un recurso Ingress que realiza lo siguiente:

  • Enruta las solicitudes con la ruta que empieza por /v2/ al servicio web2.
  • ruta todas las demás solicitudes al web servicio
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: fanout-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        pathType: ImplementationSpecific
        backend:
          service:
            name: web
            port:
              number: 8080
      - path: /v2/*
        pathType: ImplementationSpecific
        backend:
          service:
            name: web2
            port:
              number: 8080

Aplica el recurso al clúster:

kubectl create -f fanout-ingress.yaml

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

A continuación, visita la dirección IP para comprobar que se puede acceder a ambas aplicaciones en el mismo balanceador de carga:

  • Visita http://<IP_ADDRESS>/ y observa que la respuesta contiene Version: 1.0.0 (ya que la solicitud se ha dirigido al servicio web).
  • Visita http://<IP_ADDRESS>/v2/ y observa que la respuesta contiene Version: 2.0.0 (ya que la solicitud se ha dirigido al servicio web2).

El único carácter comodín admitido en el campo path de un Ingress es el carácter *. El carácter * debe ir después de una barra diagonal (/) y ser el último carácter del patrón. Por ejemplo, /*, /foo/* y /foo/bar/* son formatos válidos, pero *, /foo/bar* y /foo/*/bar no lo son.

Un patrón más específico tiene prioridad sobre un patrón menos específico. Si tienes /foo/* y /foo/bar/*, se considera que /foo/bar/bat coincide con /foo/bar/*.

Para obtener más información sobre las limitaciones de las rutas y la coincidencia de patrones, consulta la documentación de mapas de URLs.

(Opcional) Monitorizar la disponibilidad y la latencia de tu servicio

LasGoogle Cloud comprobaciones de tiempo de actividad monitorizan las aplicaciones de caja negra desde el punto de vista del usuario, lo que permite determinar la latencia y la disponibilidad de varias IPs externas a la dirección IP del balanceador de carga. En cambio, las comprobaciones de estado Google Cloud realizan una comprobación interna de las IPs de los pods para determinar la disponibilidad a nivel de instancia. Estas comprobaciones son complementarias y ofrecen una visión integral del estado de las aplicaciones.

Puedes crear una comprobación de disponibilidad mediante la Google Cloud consola, la API de Cloud Monitoring o las bibliotecas de cliente de Cloud Monitoring. Para obtener más información, consulta Gestionar comprobaciones de disponibilidad del servicio. Si quieres crear una comprobación de disponibilidad con la consola Google Cloud , sigue estos pasos:

  1. Ve a la página Servicios y entrada de la Google Cloud consola.

    Ir a Servicios e Ingress

  2. Haz clic en el nombre del servicio para el que quieras crear una comprobación de disponibilidad.

  3. Haz clic en Crear comprobación de disponibilidad.

  4. En el panel Crear comprobación de tiempo de actividad, introduce un título para la comprobación de tiempo de actividad y, a continuación, haz clic en Siguiente para ir a los ajustes de Destino.

    Los campos Destino de la comprobación de tiempo de actividad se rellenan automáticamente con la información del balanceador de carga de servicio.

    Para consultar la documentación completa sobre todos los campos de una comprobación de disponibilidad, consulta el artículo Crear una comprobación de disponibilidad.

  5. Haz clic en Siguiente para ir a la configuración de Validación de respuestas.

  6. Haz clic en Siguiente para ir a la sección Alertas y notificaciones.

    Para monitorizar una comprobación de disponibilidad, puedes crear una política de alertas o consultar el panel de control de comprobaciones de disponibilidad. Una política de alertas puede enviarte una notificación por correo electrónico o a través de otro canal si falla la comprobación de disponibilidad. Para obtener información general sobre las políticas de alertas, consulta el artículo Introducción a las alertas.

    .
  7. Haz clic en Crear.

Observaciones

De forma predeterminada, Ingress realiza una comprobación de estado periódica enviando una solicitud GET a la ruta / para determinar el estado de la aplicación y espera una respuesta HTTP 200. Si quieres comprobar otra ruta o esperar un código de respuesta diferente, puedes usar una ruta de comprobación de estado personalizada.

Ingress admite casos prácticos más avanzados, como:

  • Hosting virtual basado en nombres: puedes usar Ingress para reutilizar el balanceador de carga en varios nombres de dominio y subdominios, así como para exponer varios servicios en una sola dirección IP y un solo balanceador de carga. Consulta los ejemplos de fanout simple y de hosting virtual basado en nombres para saber cómo configurar Ingress para estas tareas.

  • Anulación de HTTPS: puedes configurar el recurso Ingress para anular el tráfico HTTPS mediante el balanceador de carga de Cloud.

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

Limpieza

Para evitar que los recursos utilizados en este tutorial se cobren en tu cuenta de Google Cloud, elimina el proyecto que contiene los recursos o conserva el proyecto y elimina los recursos.

  1. Elimina las reglas de reenvío y los proxies de destino creados manualmente que hagan referencia al Ingress:

    .

    Un proxy de destino huérfano que haga referencia a un mapa de URLs gestionado por un controlador de Ingress de GKE provocará que no se pueda eliminar el Ingress en las versiones 1.15.4-gke.22 y posteriores de GKE. Inspecciona el recurso 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 anterior, k8s2-um-tlw9rhgp-default-my82-target-proxy es un proxy https de destino creado manualmente que sigue haciendo referencia al mapa de URLs k8s2-um-tlw9rhgp-default-my-ingress-9ifnni82, que fue creado y gestionado por un controlador de entrada.

    Estos recursos de frontend creados manualmente (tanto la regla de reenvío como el proxy de destino) deben eliminarse antes de eliminar el recurso Ingress.

  2. Elimina el Ingress: este paso desasigna la dirección IP externa efímera y los recursos de balanceo de carga asociados a tu aplicación:

    kubectl delete ingress basic-ingress

    Si has seguido el paso opcional para crear un Ingress que enrute las solicitudes por ruta, elimina el Ingress:

    kubectl delete ingress fanout-ingress

  3. Eliminar la dirección IP estática: completa este paso solo si has seguido el paso opcional para crear una dirección IP estática.

    • Si has seguido la opción 1 para convertir una dirección IP efímera en estática, ve a la Google Cloud consola para eliminar la dirección IP estática.

    • Si has seguido la opción 2 para crear una dirección IP estática, ejecuta el siguiente comando para eliminarla:

      gcloud compute addresses delete web-static-ip --global
  4. Elimina el clúster: en este paso se eliminan los nodos de computación de tu clúster de contenedores y otros recursos, como las implementaciones del clúster:

    gcloud container clusters delete loadbalancedcluster

Siguientes pasos