Configurar Ingress para balanceadores de carga de aplicaciones externos

En esta página se muestra cómo configurar un balanceador de carga de aplicaciones externo creando un objeto Ingress de Kubernetes.

Antes de leer esta página, asegúrate de que conoces los conceptos de redes de GKE.

Antes de empezar

Antes de empezar, asegúrate de que has realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si quieres usar Google Cloud CLI para esta tarea, instálala y, a continuación, inicialízala. Si ya has instalado la gcloud CLI, obtén la versión más reciente ejecutando gcloud components update.

Habilita el complemento HttpLoadBalancing

Tu clúster debe tener habilitado el complemento HttpLoadBalancing. 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 o la CLI de Google Cloud. Trusted Cloud

Consola

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

    Ir a Google Kubernetes Engine

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

  3. En Redes, en el campo Balanceo de carga de HTTP, haga clic en Editar balanceo de carga de HTTP.

  4. Selecciona la casilla Habilitar balanceo de carga de HTTP.

  5. Haz clic en Guardar cambios.

gcloud

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

Sustituye CLUSTER_NAME por el nombre de tu clúster.

Crear una dirección IP estática

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

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

Crear un balanceador de carga de aplicación externo

En este ejercicio, configurarás un balanceador de carga de aplicaciones externo para enrutar las solicitudes a diferentes servicios en función de la ruta de la URL.

Crear despliegues y servicios

Crea dos implementaciones con servicios llamados hello-world-1 y hello-world-2:

  1. Guarda el siguiente archivo de 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"
    

    Este manifiesto describe un Deployment de ejemplo con tres réplicas.

  2. Aplica el manifiesto al clúster:

    kubectl apply -f hello-world-deployment-1.yaml
    
  3. Guarda el siguiente archivo de 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
    

    Este manifiesto describe un servicio con las siguientes propiedades:

    • Todos los pods que tengan las etiquetas greeting: hello y version: one son miembros del servicio.
    • GKE reenvía las solicitudes enviadas al servicio en el puerto TCP 60000 a uno de los pods miembros en el puerto TCP 50000.
    • El tipo de servicio es NodePort, que es obligatorio a menos que uses el balanceo de carga nativo de contenedores. Si usas el balanceo de carga nativo de contenedores, no hay ninguna restricción en el tipo de servicio. Recomendamos usar type: ClusterIP.
  4. Aplica el manifiesto al clúster:

    kubectl apply -f hello-world-service-1.yaml
    
  5. Guarda el siguiente archivo de 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"
    

    Este manifiesto describe un Deployment de ejemplo con tres réplicas.

  6. Aplica el manifiesto al clúster:

    kubectl apply -f hello-world-deployment-2.yaml
    
  7. Guarda el siguiente archivo de 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
    

    Este manifiesto describe un servicio con las siguientes propiedades:

    • Todos los pods que tengan las etiquetas greeting: hello y version: two son miembros del servicio.
    • GKE reenvía las solicitudes enviadas al servicio 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
    

Crear un Ingress

Crea un Ingress que especifique reglas para enrutar solicitudes en función de la ruta de la URL de la solicitud. Cuando creas el objeto Ingress, el controlador Ingress de GKE crea y configura un balanceador de carga de aplicaciones externo.

  1. Guarda el siguiente archivo de 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
    

    Este manifiesto 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 con spec.ingressClassName.

    • La clase gce implementa un balanceador de carga de aplicación externo.

    • La clase gce-internal implementa un balanceador de carga de aplicación interno.

    • Cuando despliegas un recurso Ingress sin las anotaciones spec.ingressClassName y kubernetes.io/ingress.class, GKE crea un balanceador de carga 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 Trusted Cloud servicio 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 Trusted Cloud comprobación de estado. Esta comprobación del estado es diferente de una comprobación de actividad o de disponibilidad de Kubernetes, ya que se implementa fuera del clúster. Para obtener más información, consulta Comprobaciones del estado.

    • Cuando un cliente envía una solicitud al balanceador de carga 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 carga 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, consulte Rutas de URL.

  2. Aplica el manifiesto al clúster:

    kubectl apply -f my-ingress.yaml
    

Probar el balanceador de carga de aplicación externo

Espera unos cinco minutos a que se configure el balanceador de carga y, a continuación, prueba el balanceador de carga de aplicación externo:

  1. Ver el Ingress:

    kubectl get ingress my-ingress --output yaml
    

    El resultado muestra la dirección IP del balanceador de carga de aplicación externo:

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

    curl LOAD_BALANCER_IP_ADDRESS/
    

    Sustituye LOAD_BALANCER_IP_ADDRESS por la dirección IP externa del balanceador de carga.

    El resultado debería ser similar al siguiente:

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

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

  3. Prueba la ruta /v2:

    curl load-balancer-ip/v2
    

    El resultado debería ser similar al siguiente:

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

Cómo funciona Ingress para el balanceo de carga externo

Un balanceador de carga de aplicación externo actúa como proxy entre tus clientes y tu aplicación. Si quieres aceptar solicitudes HTTPS de tus clientes, el balanceador de carga debe tener un certificado para poder demostrar su identidad a tus clientes. El balanceador de carga también debe tener una clave privada para completar el handshake de HTTPS. Para obtener más información, consulta estos artículos:

Rutas de URL

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.

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

Inhabilitar HTTP

Si quieres que todo el tráfico entre el cliente y el balanceador de carga use HTTPS, puedes inhabilitar HTTP. Para obtener más información, consulta Inhabilitar HTTP.

HTTPS entre el balanceador de carga y la aplicación

Si tu aplicación, que se ejecuta en un pod de GKE, puede recibir solicitudes HTTPS, puedes configurar el balanceador de carga 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 carga y tu aplicación.

HTTP/2 entre el cliente y el balanceador de carga

Los clientes pueden usar HTTP/2 para enviar solicitudes al balanceador de carga. No es necesario configurar nada.

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

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

Grupos de puntos finales de red

Si tu clúster admite el balanceo de carga nativo de contenedores, te recomendamos que uses grupos de puntos finales de red (NEGs). En los clústeres de GKE 1.17 y versiones posteriores, y en determinadas condiciones, el balanceo de carga nativo de contenedor está activado de forma predeterminada y no requiere una anotación cloud.google.com/neg: '{"ingress": true}' Service explícita.

VPC compartida

Si el clúster de GKE en el que vas a implementar los recursos Ingress está en un proyecto de servicio y quieres que el plano de control de GKE gestione los recursos de firewall de tu proyecto host, debes conceder a la cuenta de servicio de GKE del proyecto de servicio los permisos de gestión de identidades y accesos adecuados en el proyecto host, tal como se indica en el artículo Gestionar recursos de firewall de clústeres con VPC compartida. De esta forma, el controlador Ingress puede crear reglas de cortafuegos para permitir tanto el tráfico de entrada como el tráfico de las Trusted Cloud comprobaciones del estado.

A continuación, se muestra un ejemplo de un evento que puede estar presente en los registros de recursos de entrada. Este error se produce cuando el controlador de Ingress no puede crear una regla de cortafuegos para permitir el tráfico de entrada de las comprobaciones del estado si los permisos no están configurados correctamente. Trusted Cloud

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 manualmente las reglas de cortafuegos desde el proyecto host, puedes silenciar los eventos firewallXPNError añadiendo la anotación networking.gke.io/suppress-firewall-xpn-error: "true" al recurso Ingress.

Resumen de las anotaciones de Ingress externas

Anotaciones de Ingress

Anotación Descripción
kubernetes.io/ingress.allow-http Especifica si se permite el tráfico HTTP entre el cliente y el balanceador de carga 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 recursos de Ingress de GKE. Para obtener más información, consulta Usar varios certificados SSL con balanceadores de carga de aplicaciones externos.
kubernetes.io/ingress.global-static-ip-name Usa esta anotación para especificar que el balanceador de carga debe usar una dirección IP externa estática que hayas creado anteriormente. Consulta Direcciones IP estáticas para balanceadores de carga HTTP(S).
networking.gke.io/v1beta1.FrontendConfig Usa esta anotación para personalizar la configuración del balanceador de carga que se muestra al cliente. Para obtener más información, consulta la sección sobre la configuración de Ingress.
networking.gke.io/suppress-firewall-xpn-error En el caso de los balanceadores de carga de entrada, si Kubernetes no puede cambiar las reglas de cortafuegos debido a que no tiene permisos suficientes, se crea un evento firewallXPNError cada varios minutos. En GLBC 1.4 y versiones posteriores, puedes silenciar el evento firewallXPNError añadiendo la anotación networking.gke.io/suppress-firewall-xpn-error: "true" al recurso ingress. Puedes quitar esta anotación para reactivar el audio. 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 para definir el protocolo de comunicación entre el balanceador de carga y la aplicación. Los protocolos posibles son HTTP, HTTPS y HTTP2. Consulta HTTPS entre el balanceador de carga y tu aplicación y HTTP/2 para el balanceo de carga con Ingress.
cloud.google.com/backend-config Use esta anotación para configurar el servicio de backend asociado a un servicio. Para obtener más información, consulta la sección sobre la configuración de Ingress.
cloud.google.com/neg Usa esta anotación para especificar que el balanceador de carga debe usar grupos de puntos de conexión de red. Consulta Usar el balanceo de carga nativo de contenedores.

Siguientes pasos