Configura Ingress para balanceadores de cargas de aplicaciones externos

En esta página, 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 el comando gcloud components update para obtener la versión más reciente. Es posible que las versiones anteriores de gcloud CLI no admitan la ejecución de los comandos de este documento.

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 Google Cloud consola o la Google Cloud CLI.

Console

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

    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 una dirección IP estática

Un balanceador de cargas de aplicaciones externo proporciona una dirección IP estable que puedes usar para enrutar solicitudes a uno o más servicios. Si deseas obtener una dirección IP permanente, debes reservar una dirección IP externa estática global antes de crear un Ingress.

Si modificas un Ingress existente para que use una dirección IP estática en lugar de una dirección IP efímera, GKE podría cambiar la dirección IP del balanceador de cargas cuando GKE vuelva a crear la regla de reenvío del balanceador de cargas.

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 sobre esta tarea directamente en la Google Cloud consola, haz clic en Guiarme:

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, pero te recomendamos que uses un Service de type ClusterIP, a menos que necesites de forma explícita el nodePort proporcionado por un Service NodePort. Los objetos Service LoadBalancer no son compatibles como backends de Ingress.
  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 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 Google Cloud Service de backend para cada backend.service. Cada uno de los servicios de backend corresponde a un servicio de Kubernetes, y cada servicio de backend debe hacer referencia a una Google Cloud verificación de estado. Esta verificación de estado es diferente de una prueba de funcionamiento o disponibilidad de Kubernetes porque la verificación de estado se implementa fuera del clúster. Para obtener más información, consulta Verificaciones de estado

    • 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.

    • Si deseas reservar una dirección IP externa estática global, incluye una kubernetes.io/ingress.global-static-ip-name anotación en el objeto Ingress como se muestra aquí:

     apiVersion: networking.k8s.io/v1
     kind: Ingress
     metadata:
       name: my-ingress
       annotations:
         kubernetes.io/ingress.global-static-ip-name: my-static-address
     ```
    
  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
    

    El resultado 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

En esta sección, se describen los componentes y las configuraciones que habilitan el balanceo de cargas externo para tus aplicaciones de GKE, incluida la coincidencia de rutas de URL, los grupos de extremos de red y la integración de VPC compartida.

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.

Grupos de extremos de red

Si tu clúster admite el balanceo de cargas nativo del contenedor, te recomendamos que uses grupos de extremos de red (NEG). Cuando creas el Ingress, GKE crea un balanceador de cargas de aplicaciones en el proyecto y se crean NEGs en cada zona en la que se ejecuta el clúster. Los extremos en el NEG y los del servicio se mantienen sincronizados. Para los clústeres de GKE 1.17 y versiones posteriores, el balanceo de cargas nativo del contenedor viene configurado como predeterminado y no requiere una anotación de Service explícita, en ciertas condiciones.cloud.google.com/neg: '{"ingress": true}' Para los clústeres en los que los NEG no son la configuración predeterminada, aún se recomienda usar el balanceo de cargas nativo del contenedor, pero se debe habilitar explícitamente para cada Service. La anotación se debe aplicar a los Services de la siguiente manera:

kind: Service
...
  annotations:
    cloud.google.com/neg: '{"ingress": true}'
...

Cuando agregas esta anotación, se crea un BackendService nuevo para el Service existente. Esto puede provocar una interrupción temporal de tu Service.

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 Google Cloud verificaciones de estado.

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 Google Cloud verificaciones de estado 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 host proyecto, puedes silenciar los eventos firewallXPNError agregando la networking.gke.io/suppress-firewall-xpn-error: "true" anotación al recurso de Ingress.

Resumen de las anotaciones de Ingress externas

Puedes usar las siguientes anotaciones para configurar el comportamiento de tus recursos de Ingress externos y los objetos Service de Kubernetes asociados.

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.
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?