Configura Ingress para balanceadores de cargas de aplicaciones externos


En este documento, se muestra cómo configurar un balanceador de cargas de aplicaciones externo mediante la creación de un objeto Ingress de Kubernetes.

Antes de leer este documento, asegúrate de estar familiarizado con los conceptos de herramientas de redes de GKE.

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta gcloud components update para obtener la versión más reciente.

Habilita el complemento HttpLoadBalancing

El clúster debe tener el complemento HttpLoadBalancing habilitado. Este complemento está habilitado de forma predeterminada. En los clústeres de Autopilot, no puedes inhabilitar este complemento.

Puedes habilitar el complemento HttpLoadBalancing con la consola de Google Cloud o la CLI de Google Cloud.

Console

  1. Ve a la página de Google Kubernetes Engine en la consola de Google Cloud.

    Ir a Google Kubernetes Engine

  2. Haz clic en el nombre del clúster que deseas modificar.

  3. En Herramientas de redes, en el campo Balanceo de cargas de HTTP, haz clic en Editar el balanceo de cargas de HTTP.

  4. Selecciona la casilla de verificación Habilitar el balanceo de cargas de HTTP.

  5. Haz clic en Guardar cambios.

gcloud

gcloud container clusters update CLUSTER_NAME --update-addons=HttpLoadBalancing=ENABLED

Reemplaza CLUSTER_NAME por el nombre del clúster.

Crea un balanceador de cargas de aplicaciones externo

En este ejercicio, configurarás un balanceador de cargas de aplicaciones externo para enrutar las solicitudes a diferentes servicios de backend según la ruta de URL.


Para seguir la guía paso a paso en esta tarea directamente en la consola de Google Cloud, haz clic en Guía:

GUIARME


Crea implementaciones y servicios

Crea dos Deployments con Services llamados hello-world-1 y hello-world-2:

  1. Guarda el siguiente manifiesto como hello-world-deployment-1.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-world-deployment-1
    spec:
      selector:
        matchLabels:
          greeting: hello
          version: one
      replicas: 3
      template:
        metadata:
          labels:
            greeting: hello
            version: one
        spec:
          containers:
          - name: hello-app-1
            image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0"
            env:
            - name: "PORT"
              value: "50000"
    

    En este manifiesto, se describe un Deployment de muestra con tres réplicas.

  2. Aplica el manifiesto al clúster:

    kubectl apply -f hello-world-deployment-1.yaml
    
  3. Guarda el siguiente manifiesto como hello-world-service-1.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: hello-world-1
    spec:
      type: NodePort
      selector:
        greeting: hello
        version: one
      ports:
      - protocol: TCP
        port: 60000
        targetPort: 50000
    

    En este manifiesto, se describe un Service con las siguientes propiedades:

    • Cualquier pod que tenga las etiquetas greeting: hello y version: one es miembro del servicio.
    • Con GKE se reenvían las solicitudes enviadas al Service en el puerto TCP 60000 a uno de los Pods miembros en el puerto TCP 50000.
    • El tipo de manifiesto de Service es NodePort, que es necesario, a menos que uses el balanceo de cargas nativo del contenedor. Si es así, no hay restricciones sobre el tipo de servicio. Se recomienda usar type: ClusterIP.
  4. Aplica el manifiesto al clúster:

    kubectl apply -f hello-world-service-1.yaml
    
  5. Guarda el siguiente manifiesto como hello-world-deployment-2.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-world-deployment-2
    spec:
      selector:
        matchLabels:
          greeting: hello
          version: two
      replicas: 3
      template:
        metadata:
          labels:
            greeting: hello
            version: two
        spec:
          containers:
          - name: hello-app-2
            image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
            env:
            - name: "PORT"
              value: "8080"
    

    En este manifiesto, se describe un Deployment de muestra con tres réplicas.

  6. Aplica el manifiesto al clúster:

    kubectl apply -f hello-world-deployment-2.yaml
    
  7. Guarda el siguiente manifiesto como hello-world-service-2.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: hello-world-2
    spec:
      type: NodePort
      selector:
        greeting: hello
        version: two
      ports:
      - protocol: TCP
        port: 80
        targetPort: 8080
    

    En este manifiesto, se describe un Service con las siguientes propiedades:

    • Cualquier pod que tenga las etiquetas greeting: hello y version: two es miembro del servicio.
    • Con GKE se reenvían las solicitudes enviadas al Service en el puerto TCP 80 a uno de los Pods miembros en el puerto TCP 8080.
  8. Aplica el manifiesto al clúster:

    kubectl apply -f hello-world-service-2.yaml
    

Crea un Ingress

Crea un recurso de Ingress que especifique las reglas para enrutar solicitudes según la ruta de URL en la solicitud. Cuando creas el Ingress, el controlador de Ingress de GKE crea y configura un balanceador de cargas de aplicaciones externo.

  1. Guarda el siguiente manifiesto como my-ingress.yaml:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-ingress
      annotations:
        # If the class annotation is not specified it defaults to "gce".
        kubernetes.io/ingress.class: "gce"
    spec:
      rules:
      - http:
          paths:
          - path: /*
            pathType: ImplementationSpecific
            backend:
              service:
                name: hello-world-1
                port:
                  number: 60000
          - path: /v2
            pathType: ImplementationSpecific
            backend:
              service:
                name: hello-world-2
                port:
                  number: 80
    

    En este manifiesto, se describe un Ingress con las siguientes propiedades:

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

    • La clase gce implementa un balanceador de cargas de aplicaciones externo.

    • La clase gce-internal implementa un balanceador de cargas de aplicaciones interno.

    • Cuando implementas un recurso Ingress sin las anotaciones spec.ingressClassName y kubernetes.io/ingress.class, GKE crea un balanceador de cargas de aplicaciones externo. Este es el mismo comportamiento que se produce si especificas la anotación kubernetes.io/ingress.class: gce. Para obtener más información, consulta Comportamiento del controlador de Ingress de GKE.

    • GKE crea un Service de backend de Google Cloud para cada backend.service.

    • Cuando un cliente envía una solicitud al balanceador de cargas con la ruta de URL /, GKE reenvía la solicitud al servicio hello-world-1 en el puerto 60000. Cuando un cliente envía una solicitud al balanceador de cargas mediante la ruta de URL /v2, GKE reenvía la solicitud al servicio hello-world-2 en el puerto 80. Para obtener más información sobre las propiedades path y pathType, consulta Rutas de URL.

  2. Aplica el manifiesto al clúster:

    kubectl apply -f my-ingress.yaml
    

Prueba el balanceador de cargas de aplicaciones externo

Espera unos cinco minutos para que se configure el balanceador de cargas y, luego, prueba el balanceador de cargas de aplicaciones externo:

  1. Ve el Ingress:

    kubectl get ingress my-ingress --output yaml
    

    En el resultado, se muestra la dirección IP del balanceador de cargas de aplicaciones externo:

    status:
      loadBalancer:
        ingress:
        - ip: 203.0.113.1
    
  2. Prueba la ruta /:

    curl LOAD_BALANCER_IP_ADDRESS/
    

    Reemplaza LOAD_BALANCER_IP_ADDRESS por la dirección IP externa del balanceador de cargas.

    El resultado es similar a este:

    Hello, world!
    Version: 1.0.0
    Hostname: ...
    

    Si el resultado incluye un error 404, espera unos minutos.

  3. Prueba la ruta /v2:

    curl load-balancer-ip/v2
    

    El resultado es similar a este:

    Hello, world!
    Version: 2.0.0
    Hostname: ...
    

Cómo funciona Ingress para el balanceo de cargas externo

Un balanceador de cargas de aplicaciones externo actúa como un proxy entre tus clientes y tu aplicación. Si deseas aceptar solicitudes HTTPS de los clientes, el balanceador de cargas debe contar con un certificado para que pueda demostrar su identidad a los clientes. El balanceador de cargas también debe tener una clave privada para completar el protocolo de enlace HTTPS. Para obtener más información, consulte:

Rutas de URL

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

Un patrón más específico tiene prioridad sobre uno menos específico. Si tienes /foo/* y /foo/bar/*, entonces se considera que /foo/bar/bat coincide con /foo/bar/*. Para obtener más información sobre las limitaciones de ruta y la coincidencia de patrones, consulta la documentación de mapas de URL.

Para los clústeres de GKE que ejecutan versiones anteriores a 1.21.3-gke.1600, el único valor admitido para el campo pathType es ImplementationSpecific. En el caso de los clústeres que ejecutan la versión 1.21.3-gke.1600 o una posterior, los valores Prefix y Exact también son compatibles con pathType.

Inhabilita HTTP

Puedes inhabilitar HTTP si deseas que todo el tráfico entre el cliente y el balanceador de cargas use HTTPS. Para obtener más información, consulta Inhabilita HTTP.

HTTPS entre el balanceador de cargas y la aplicación

Si tu aplicación que se ejecuta en un pod de GKE es capaz de recibir solicitudes HTTPS, puedes configurar el balanceador de cargas para que use HTTPS cuando reenvíe solicitudes a tu aplicación. Para obtener más información, consulta HTTPS (TLS) entre el balanceador de cargas y la aplicación.

HTTP/2 entre el cliente y el balanceador de cargas

Los clientes pueden usar HTTP/2 para enviar solicitudes al balanceador de cargas. No se requiere configuración.

HTTP/2 entre el balanceador de cargas y la aplicación

Si la aplicación, que se ejecuta en un pod de GKE, puede recibir solicitudes HTTP/2, puedes configurar el balanceador de cargas para que use HTTP/2 cuando reenvíe las solicitudes a la aplicación. Si necesitas más información, consulta Usa HTTP/2 para el balanceo de cargas con Ingress.

Grupos de extremos de red

Si tu clúster admite el balanceo de cargas nativo del contenedor, se recomienda usar grupos de extremos de red (NEG). Para los clústeres de GKE 1.17 y versiones posteriores, y en ciertas condiciones, el balanceo de cargas nativo del contenedor viene configurado como predeterminado y no requiere una anotación de Service cloud.google.com/neg: '{"ingress": true}' explícita.

VPC compartida

Si el clúster de GKE en el que implementas los recursos de Ingress está en un proyecto de servicio y deseas que el plano de control de GKE administre los recursos de firewall en tu proyecto host, entonces se deben otorgar a la cuenta de servicio de GKE del proyecto de servicio los permisos de IAM adecuados en el proyecto host según Administra los recursos de firewall para clústeres con una VPC compartida. Esto permite que el controlador de Ingress cree reglas de firewall para permitir el tráfico de entrada y el tráfico de las verificaciones de estado de Google Cloud.

El siguiente es un ejemplo de un evento que podría estar presente en los registros de recursos de Ingress. Este error se produce cuando el controlador de Ingress no puede crear una regla de firewall para permitir el tráfico de entrada para las verificaciones de estado de Google Cloud si los permisos no están configurados de forma correcta.

Firewall change required by security admin: `gcloud compute firewall-rules update <RULE_NAME> --description "GCE L7 firewall rule" --allow tcp:<PORT> --source-ranges 130.211.0.0/22,35.191.0.0/16 --target-tags <TARGET_TAG> --project <HOST_PROJECT>

Si prefieres aprovisionar reglas de firewall de forma manual desde el proyecto host, puedes silenciar los eventos firewallXPNError agregando la anotación networking.gke.io/suppress-firewall-xpn-error: "true" al recurso de Ingress.

Resumen de las anotaciones de Ingress externas

Anotaciones de Ingress

Anotación Descripción
kubernetes.io/ingress.allow-http Especifica si se debe permitir el tráfico HTTP entre el cliente y el balanceador de cargas de HTTP(S). Los valores posibles son “true” y “false”. El valor predeterminado es "true". Consulta Inhabilitar HTTP.
ingress.gcp.kubernetes.io/pre-shared-cert Usa esta anotación para adjuntar recursos de certificado a los recursos de Ingress de GKE. Para obtener más información, consulta Usa varios certificados SSL con balanceadores de cargas de aplicaciones externos.
kubernetes.io/ingress.global-static-ip-name Usa esta anotación para especificar que el balanceador de cargas debe usar la dirección IP externa y estática que creaste antes. Consulta Direcciones IP estáticas para el balanceador de cargas de HTTP(S).
networking.gke.io/v1beta1.FrontendConfig Usa esta anotación para personalizar la configuración orientada al cliente del balanceador de cargas. Para obtener más información, consulta Configuración de Ingress.
networking.gke.io/suppress-firewall-xpn-error En el caso de los balanceadores de cargas de Ingress, si Kubernetes no puede modificar las reglas de firewall debido a que no cuenta con los permisos suficientes, se creará un evento firewallXPNError cada algunos minutos. En GLBC 1.4 y versiones posteriores, puedes silenciar el evento firewallXPNError si agregas la anotación networking.gke.io/suppress-firewall-xpn-error: "true" al recurso de entrada. Podrás quitar esta anotación para dejar de silenciar el evento. Los valores posibles son true y false. El valor predeterminado es false.
Anotación Descripción
cloud.google.com/app-protocols Usa esta anotación a fin de configurar el protocolo para la comunicación entre el balanceador de cargas y la aplicación. Los protocolos posibles son HTTP, HTTPS y HTTP2. Consulta HTTPS entre el balanceador de cargas y la aplicación y HTTP/2 para el balanceo de cargas con Ingress.
cloud.google.com/backend-config Usa esta anotación para configurar el servicio de backend asociado con un Service. Para obtener más información, consulta Configuración de Ingress.
cloud.google.com/neg Usa esta anotación para especificar que el balanceador de cargas debe usar grupos de extremos de red. Consulta Usa el balanceo de cargas nativo del contenedor.

¿Qué sigue?