Balanceo de cargas HTTP(s) con Ingress

En Google Kubernetes Engine, con un objeto Ingress se definen las reglas del enrutamiento de tráfico HTTP(S) externo a aplicaciones que se ejecutan en un clúster. Un objeto Ingress se asocia con uno o más objetos Service, y cada uno está asociado a un conjunto de pods.

Cuando creas un objeto Ingress, el controlador de Ingress de GKE crea un balanceador de cargas HTTP(S) de Google Cloud Platform y lo configura de acuerdo con la información de Ingress y sus servicios asociados.

Características del balanceo de cargas HTTP(S)

El balanceo de cargas HTTP(S) configurado por Ingress incluye las características siguientes:

Configuración flexible para servicios
Un Ingress define cómo llega el tráfico a tus servicios y la forma en que se enruta a tu aplicación. Además, un Ingress puede proporcionar una única dirección IP para varios servicios en tu clúster.
Integración con servicios de red de GCP
Un Ingress puede configurar características de GCP como certificados SSL administrados por Google (Beta), Google Cloud Armor, Cloud CDN y Cloud Identity-Aware Proxy.
Asistencia para varios certificados TLS
Un Ingress puede especificar el uso de varios certificados TLS para la finalización de solicitudes.

Para aprender más sobre estas características, consulta los Conceptos de balanceo de cargas HTTP(S).

Opciones para proporcionar certificados SSL

Existen tres maneras de proporcionar certificados SSL a un balanceador de cargas HTTPS:

Certificados administrados por Google
Los certificados SSL administrados por Google se aprovisionan, implementan, renuevan y administran para tus dominios. Los certificados administrados no admiten dominios de comodín ni múltiples nombres alternativos de sujeto (SAN).
Certificados autoadministrados compartidos con GCP
Puedes aprovisionar tu propio certificado SSL y crear un recurso de certificado en tu proyecto de GCP. Luego, puedes enumerar el recurso de certificado en una anotación en un Ingress para crear un balanceador de cargas HTTP(S) que use el certificado. Consulta las instrucciones para certificados ya compartidos a fin de obtener más información.
Certificados autoadministrados como recursos secretos
Puedes aprovisionar tu propio certificado SSL y crear un secreto para retenerlo. Luego, puedes hacer referencia al secreto en una especificación Ingress para crear un balanceador de cargas HTTP(S) que use el certificado. Para obtener más información, consulta las instrucciones para usar certificados en secretos.

Limitaciones

  • El largo total del espacio de nombres y el nombre de un Ingress no deben exceder los 40 caracteres. Si incumples esta pauta, puede que el controlador de Ingress de GKE actúe de forma anormal. Para obtener más información, consulta este problema.

  • La cantidad máxima de reglas para un mapa de URL es de 50. Esto significa que puedes especificar un máximo de 50 reglas en un Ingress.

  • Si usas el controlador de Ingress de GKE , tu clúster no puede tener más de 1,000 nodos.

  • A modo de que el controlador de Ingress de GKE use tu readinessProbes como verificaciones de estado, los pods para un Ingress deben existir en el momento de la creación del Ingress. Si tus réplicas se escalan a 0, se aplicará la verificación de estado predeterminada. Para obtener más información, consulta este comentario sobre el problema.

  • Los cambios en readinessProbe de un pod no afectan el Ingress después de que se crea.

  • El balanceador de cargas HTTP(S) finaliza TLS en ubicaciones distribuidas de manera global a fin de minimizar la latencia entre los clientes y el balanceador de cargas. Si necesitas control geográfico sobre la ubicación donde finaliza TLS, debes usar un controlador de Ingress personalizado y el balanceo de cargas de red de GCP y finalizar TLS en backends ubicados en regiones adecuadas para tus necesidades.

Servicios de backend múltiples

Un balanceador de cargas de HTTP(S) proporciona una dirección IP estable que puedes usar para enrutar solicitudes a una variedad de servicios de backend.

Por ejemplo, puedes configurar el balanceador de cargas para enrutar solicitudes a diferentes servicios de backend según la ruta de URL. Las solicitudes enviadas a your-store.example se pueden enrutar a un servicio de backend que muestra artículos a precio completo; las solicitudes enviadas a your-store.example/discounted se pueden enrutar a un servicio de backend que muestra artículos con descuento.

También puedes configurar el balanceador de cargas para enrutar solicitudes según el nombre de host. Las solicitudes enviadas a your-store.example pueden ir a un servicio de backend y las solicitudes enviadas a your-experimental-store.example pueden ir a otro.

En un clúster de GKE, puedes crear un objeto Ingress de Kubernetes para crear y configurar un balanceador de cargas HTTP(S). Un objeto Ingress debe estar asociado con uno o más objetos Service, cada uno de los cuales está asociado con un conjunto de pods.

A continuación, se detalla un manifiesto para un Ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: my-products
          servicePort: 60000
      - path: /discounted
        backend:
          serviceName: my-discounted-products
          servicePort: 80

Cuando creas el Ingress, el controlador de Ingress de GKE crea y configura un balanceador de cargas HTTP(S) según la información en el Ingress y los Services asociados. Además, se le asigna una dirección IP estable al balanceador de cargas que puedes asociar con un nombre de dominio.

En el ejemplo anterior, supón que asociaste la dirección IP del balanceador de cargas con el nombre de dominio your-store.example. Cuando un cliente envía una solicitud a your-store.example, la solicitud se enruta a un servicio de Kubernetes llamado my-products en el puerto 60000. Cuando un cliente envía una solicitud a your-store.example/discounted, la solicitud se enruta a un servicio de Kubernetes llamado my-discounted-products en el puerto 80.

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.

El manifiesto para el servicio my-products podría verse así:

apiVersion: v1
kind: Service
metadata:
  name: my-products
spec:
  type: NodePort
  selector:
    app: products
    department: sales
  ports:
  - protocol: TCP
    port: 60000
    targetPort: 50000

En el manifiesto de servicio, observa que type es NodePort. Este es el tipo requerido de un Ingress que se usa para configurar un balanceador de cargas HTTP(S).

En el manifiesto de servicio, el campo selector indica que cualquier pod que tenga las etiquetas app: products y department: sales es miembro de este servicio.

Cuando llega una solicitud al Service en el puerto 60000, se enruta a uno de los pods miembros en el puerto TCP 50000.

Ten en cuenta que cada pod miembro debe tener un contenedor que escuche en el puerto TCP 50000.

El manifiesto para el servicio my-discounted-products podría verse así:

apiVersion: v1
kind: Service
metadata:
  name: my-discounted-products
spec:
  type: NodePort
  selector:
    app: discounted-products
    department: sales
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

En el manifiesto de servicio, el campo selector indica que cualquier pod que tenga las etiquetas app: discounted-products y department: sales es miembro de este servicio.

Cuando llega una solicitud al servicio del puerto 80, se enruta a uno de los pods miembros en el puerto TCP 8080.

Ten en cuenta que cada pod miembro debe tener un contenedor que escuche en el puerto TCP 8080.

Backend predeterminado

Puedes especificar un backend predeterminado si proporcionas un campo backend en el manifiesto de Ingress. Todas las solicitudes que no coincidan con las rutas del campo rules se enviarán al servicio y al puerto especificados en el campo backend. Por ejemplo, en el siguiente Ingress, toda solicitud que no coincida con / ni /discounted se enviará a un servicio llamado my-products en el puerto 60001.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
spec:
  backend:
    serviceName: my-products
    servicePort: 60001
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: my-products
          servicePort: 60000
      - path: /discounted
        backend:
          serviceName: my-discounted-products
          servicePort: 80

Si no especificas un backend predeterminado, GKE proporciona uno que muestra 404.

Verificaciones de estado

Un Service expuesto a través de un Ingress debe responder a las verificaciones de estado del balanceador de cargas. Cualquier contenedor que sea el destino final del tráfico del balanceador de cargas debe realizar una de las acciones siguientes para indicar que está en buen estado:

  • Entrega una respuesta con un estado HTTP 200 a las solicitudes GET en la ruta /.

  • Configura una prueba de disponibilidad HTTP. Entrega una respuesta con un estado HTTP 200 a las solicitudes GET en la path especificada por el sondeo de prueba de disponibilidad. Ten en cuenta que el servicio expuesto a través de un Ingress debe apuntar al mismo puerto de contenedor en el que está habilitada la prueba de disponibilidad.

    Por ejemplo, supongamos que un contenedor especifica la siguiente prueba de disponibilidad:

    ...
    readinessProbe:
      httpGet:
        path: /healthy
    

    Luego, si el controlador de la ruta /healthy del contenedor muestra un estado HTTP 200, el balanceador de cargas considera que el contenedor está activo y en buen estado.

El Service de Kubernetes comparado con el servicio de backend de GCP

Un servicio de Kubernetes y un servicio de backend de GCP son elementos diferentes. Existe una relación fuerte entre los dos, pero la relación no tiene por qué ser de uno a uno. El controlador de Ingress de GKE crea un servicio de backend de GCP para cada par (serviceName, servicePort) en un manifiesto de Ingress. Por lo tanto, es posible que un objeto de servicio de Kubernetes esté relacionado con varios servicios de backend de GCP.

Compatibilidad con características de GCP

Puedes usar BackendConfig para configurar un balanceador de cargas HTTP(S) y usar funciones como Google Cloud Armor, Cloud CDN y Cloud IAP.

BackendConfig es un recurso personalizado que contiene información de configuración de las características de GCP.

Un manifiesto de Ingress hace referencia a un servicio, y el manifiesto de servicio a un BackendConfig con una anotación beta.cloud.google.com/backend-config.

...
kind: Ingress
...
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
...

kind: Service
metadata:
  name: my-service
  ...
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"80":"my-backend-config"}}'
spec:
  type: NodePort
  ...
 

Compatibilidad con WebSocket

Con el balanceo de cargas HTTP(S), el protocolo WebSocket funciona a la perfección. No se requiere configuración.

Si pretendes usar el protocolo WebSocket, es posible que quieras usar un valor de tiempo de espera mayor que los 30 segundos predeterminados. A fin de establecer el valor de tiempo de espera para un servicio de backend configurado a través de Ingress, debes crear un objeto BackendConfig y usar la anotación beta.cloud.google.com/backend-config en el manifiesto de servicio.

Para obtener más información, consulta la sección sobre cómo configurar un servicio de backend con un Ingress.

Direcciones IP estáticas para el balanceador de cargas HTTP(S)

Cuando creas un objeto Ingress, obtienes una dirección IP externa estable que los clientes pueden usar para acceder a tus Services y, a su vez, a tus contenedores en ejecución. La dirección IP es estable en el sentido de que dura toda la vida útil del objeto Ingress. Si borras tu Ingress y creas uno nuevo a partir del mismo archivo de manifiesto, no se garantiza que obtengas la misma dirección IP externa.

Si quieres una dirección IP permanente que se mantendrá igual si borras tu Ingress y creas uno nuevo, debes reservar una dirección IP externa estática global. Luego, en el manifiesto del Ingress, debes incluir una anotación que indique el nombre de tu dirección IP estática reservada.

Por ejemplo, supongamos que reservaste una dirección IP externa estática global llamada my-static-address. En tu manifiesto de Ingress, debes incluir una anotación kubernetes.io/ingress.global-static-ip-name como se muestra aquí:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: my-static-address

Si quieres obtener más información sobre cómo crear una dirección IP externa estática para un Ingress, consulta la sección sobre cómo configurar una dirección IP estática y sobre cómo configurar nombres de dominio con direcciones IP estáticas.

Configura HTTPS (TLS) entre el cliente y el balanceador de cargas

Un balanceador de cargas HTTP(S) actúa como un proxy entre tus clientes y tu aplicación. Si deseas aceptar solicitudes HTTPS de tus 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.

Cuando el balanceador de cargas acepta una solicitud HTTP(S) de un cliente, el tráfico entre el cliente y el balanceador de cargas se encripta mediante TLS. Sin embargo, el balanceador de cargas finaliza el cifrado TLS y reenvía la solicitud sin encriptación a la aplicación. Para obtener más información sobre cómo encriptar tráfico entre el balanceador de cargas y tu aplicación, consulta HTTPS entre el balanceador de cargas y tu aplicación.

Tienes la opción de usar certificados SSL administrados por Google (Beta) o certificados que tú mismo administras. Para obtener más información sobre cómo crear un Ingress que use certificados administrados por Google, consulta la sección sobre cómo usar certificados SSL administrados por Google (Beta).

Para proporcionar un balanceador de cargas HTTP(S) con un certificado y una clave que creaste, puedes especificar el nombre de un secreto de Kubernetes en el campo tls del manifiesto de Ingress. El secreto que ya creaste contiene el certificado y la clave.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress-2
spec:
  tls:
  - secretName: my-secret
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: my-metrics
          servicePort: 60000

Los cambios en los secretos se captan de manera periódica, así que, si modificas los datos dentro del secreto, esos cambios se aplicarán en el balanceador de cargas en un máximo de 10 minutos.

Si quieres obtener más información sobre el uso de secretos para proporcionar certificados al balanceador de cargas, consulta el tema usa varios certificados SSL en el balanceo de cargas HTTP(S) con Ingress.

Inhabilita HTTP

Si deseas que todo el tráfico entre el cliente y el balanceador de cargas HTTP(S) use HTTPS, puedes inhabilitar HTTP con la inclusión de la anotación kubernetes.io/ingress.allow-http en el manifiesto de Ingress. Establece el valor de la anotación en "false".

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress-2
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: my-secret
  ...

Certificados ya compartidos para balanceadores de cargas

Una alternativa al uso de secretos de Kubernetes a fin de proporcionar certificados al balanceador de cargas para la finalización de HTTP(S) es usar certificados ya subidos a tu proyecto de GCP. Para obtener más información, consulta la sección sobre el uso de certificados ya compartidos y del uso de varios certificados SSL en el balanceo de cargas HTTP(S) con Ingress.

HTTPS (TLS) entre el balanceador de cargas y tu aplicación

Un balanceador de cargas HTTP(S) actúa como un proxy entre tus clientes y tu aplicación. Los clientes pueden usar HTTP o HTTPS para comunicarse con el proxy del balanceador de cargas. Sin embargo, la conexión del proxy del balanceador de cargas a tu aplicación usa HTTP de forma predeterminada. 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 usar HTTPS cuando reenvíe solicitudes a tu aplicación.

Para configurar el protocolo que se usa entre el balanceador de cargas y tu aplicación, debes usar la anotación cloud.google.com/app-protocols en el manifiesto de servicio.

En el manifiesto del servicio siguiente, se especifican dos puertos. La anotación indica que cuando un balanceador de cargas HTTP(S) se dirige al puerto 80 del servicio, se debe usar HTTP. Y cuando se dirige al puerto 443 del servicio, se debe usar HTTPS.

apiVersion: v1
kind: Service
metadata:
  name: my-service-3
  annotations:
    cloud.google.com/app-protocols: '{"my-https-port":"HTTPS","my-http-port":"HTTP"}'
spec:
  type: NodePort
  selector:
    app: metrics
    department: sales
  ports:
  - name: my-https-port
    port: 443
    targetPort: 8443
  - name: my-http-port
    port: 80
    targetPort: 50001

La anotación cloud.google.com/app-protocols tiene el mismo propósito que la anotación service.alpha.kubernetes.io/app-protocols anterior. Los nombres de anotaciones antiguos y los nuevos pueden coexistir, como se muestra en el manifiesto de servicio siguiente. Cuando ambas anotaciones aparecen en el mismo manifiesto de servicio, service.alpha.kubernetes.io/app-protocols tiene prioridad.

apiVersion: v1
kind: Service
metadata:
  name: my-service-3
  annotations:
    cloud.google.com/app-protocols: '{"my-https-port":"HTTPS","my-http-port":"HTTP"}'
    service.alpha.kubernetes.io/app-protocols: '{"my-first-port":"HTTPS","my-second-port":"HTTP"}'
spec:
  type: NodePort
  selector:
    app: metrics
    department: sales
  ports:
  - name: my-first-port
    port: 443
    targetPort: 8443
  - name: my-second-port
    port: 80
    targetPort: 50001

Usa varios certificados TLS

Supongamos que quieres usar un balanceador de cargas HTTP(S) para entregar contenido de dos nombres de host: your-store.example y your-experimental-store.example. Además, necesitarás que el balanceador de cargas use un certificado con your-store.example y uno diferente con your-experimental-store.example.

Puedes especificar varios certificados en un manifiesto de Ingress y el balanceador de cargas elegirá un certificado si el nombre común del certificado coincide con el nombre de host que se usa en la solicitud. Para obtener más información sobre cómo configurar varios certificados, consulta Usa varios certificados SSL en el balanceo de cargas HTTP(S) con Ingress.

Pasos siguientes

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...

Documentación de Kubernetes Engine