Desplegar objetos Ingress en clústeres


En esta página se explica cómo desplegar un Ingress que sirva una aplicación en varios clústeres de GKE. Para obtener más información sobre Ingress de varios clústeres, consulta Ingress de varios clústeres.

Para ver una comparación detallada entre Multi Cluster Ingress (MCI), Multi-cluster Gateway (MCG) y el balanceador de carga con grupos de endpoints de red independientes (LB y Standalone NEGs), consulta Elegir la API de balanceo de carga multiclúster para GKE.

Tutorial de implementación

En las siguientes tareas, desplegarás una aplicación ficticia llamada whereami y un MultiClusterIngress en dos clústeres. Ingress proporciona una dirección IP virtual (VIP) compartida para las implementaciones de la aplicación.

Esta página se basa en el trabajo realizado en Configurar Ingress con varios clústeres, donde creaste y registraste dos clústeres. Confirma que tienes dos clústeres que también están registrados en una flota:

gcloud container clusters list

El resultado debería ser similar al siguiente:

NAME    LOCATION        MASTER_VERSION  MASTER_IP       MACHINE_TYPE   NODE_VERSION     NUM_NODES  STATUS
gke-eu  europe-west1-b  1.16.8-gke.9    ***             e2-medium      1.16.8-gke.9     2          RUNNING
gke-us  us-central1-b   1.16.8-gke.9    ***             e2-medium      1.16.6-gke.13 *  2          RUNNING

Crear el espacio de nombres

Como las flotas tienen la propiedad de igualdad de espacio de nombres, te recomendamos que coordines la creación y la gestión de espacios de nombres en los clústeres para que el mismo grupo sea el propietario y el gestor de los espacios de nombres idénticos. Puedes crear espacios de nombres por equipo, entorno, aplicación o componente de aplicación. Los espacios de nombres pueden ser tan granulares como sea necesario, siempre que un espacio de nombres ns1 de un clúster tenga el mismo significado y uso que ns1 en otro clúster.

En este ejemplo, se crea un whereami espacio de nombres para cada aplicación de cada clúster.

  1. Crea un archivo llamado namespace.yaml con el siguiente contenido:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: whereami
    
  2. Cambia al contexto gke-us:

    kubectl config use-context gke-us
    
  3. Crea el espacio de nombres:

    kubectl apply -f namespace.yaml
    
  4. Cambia al contexto gke-eu:

    kubectl config use-context gke-eu
    
  5. Crea el espacio de nombres:

    kubectl apply -f namespace.yaml
    

    El resultado debería ser similar al siguiente:

    namespace/whereami created
    

Desplegar la aplicación

  1. Crea un archivo llamado deploy.yaml con el siguiente contenido:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whereami-deployment
      namespace: whereami
      labels:
        app: whereami
    spec:
      selector:
        matchLabels:
          app: whereami
      template:
        metadata:
          labels:
            app: whereami
        spec:
          containers:
          - name: frontend
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
            ports:
            - containerPort: 8080
    
  2. Cambia al contexto gke-us:

    kubectl config use-context gke-us
    
  3. Despliega la aplicación whereami:

    kubectl apply -f deploy.yaml
    
  4. Cambia al contexto gke-eu:

    kubectl config use-context gke-eu
    
  5. Despliega la aplicación whereami:

    kubectl apply -f deploy.yaml
    
  6. Verifica que la aplicación whereami se haya implementado correctamente en cada clúster:

    kubectl get deployment --namespace whereami
    

    La salida debería ser similar a la siguiente en ambos clústeres:

    NAME           READY   UP-TO-DATE   AVAILABLE   AGE
    whereami-deployment   1/1     1            1           12m
    

Desplegar a través del clúster de configuración

Ahora que la aplicación se ha desplegado en gke-us y gke-eu, desplegarás un balanceador de carga desplegando recursos MultiClusterIngress y MultiClusterService en el clúster de configuración. Estos son los equivalentes multiclúster de los recursos Ingress y Service.

En la guía de configuración, has configurado el clúster gke-us como clúster de configuración. El clúster de configuración se usa para desplegar y configurar Ingress en todos los clústeres.

  1. Define el contexto en el clúster de configuración.

    kubectl config use-context gke-us
    

Servicio de varios clústeres

  1. Crea un archivo llamado mcs.yaml con el siguiente contenido:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterService
    metadata:
      name: whereami-mcs
      namespace: whereami
    spec:
      template:
        spec:
          selector:
            app: whereami
          ports:
          - name: web
            protocol: TCP
            port: 8080
            targetPort: 8080
    
  2. Despliega el recurso MultiClusterService que coincida con la aplicación whereami:

    kubectl apply -f mcs.yaml
    
  3. Verifica que el recurso whereami-mcs se haya desplegado correctamente en el clúster de configuración:

    kubectl get mcs -n whereami
    

    El resultado debería ser similar al siguiente:

    NAME       AGE
    whereami-mcs   9m26s
    

    Este MultiClusterService crea un servicio sin encabezado derivado en cada clúster que coincida con los pods con app: whereami. Puedes ver que hay uno en el gke-us clúster kubectl get service -n whereami.

    El resultado debería ser similar al siguiente:

    NAME                                TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
    mci-whereami-mcs-svc-lgq966x5mxwwvvum   ClusterIP   None          <none>        8080/TCP         4m59s
    

También habrá un servicio sin interfaz similar en gke-eu. Estos servicios locales se usan para seleccionar dinámicamente los endpoints de los pods y programar el balanceador de carga de Ingress global con backends.

MultiClusterIngress

  1. Crea un archivo llamado mci.yaml con el siguiente contenido:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: whereami-ingress
      namespace: whereami
    spec:
      template:
        spec:
          backend:
            serviceName: whereami-mcs
            servicePort: 8080
    

    Ten en cuenta que esta configuración dirige todo el tráfico al MultiClusterService llamado whereami-mcs que se encuentra en el espacio de nombres whereami.

  2. Despliega el recurso MultiClusterIngress que hace referencia a whereami-mcs como backend:

    kubectl apply -f mci.yaml
    

    El resultado debería ser similar al siguiente:

    multiclusteringress.networking.gke.io/whereami-ingress created
    

    Ten en cuenta que MultiClusterIngress tiene el mismo esquema que el Ingress de Kubernetes. La semántica del recurso Ingress también es la misma, con la excepción del campo backend.serviceName.

El campo backend.serviceName de un MultiClusterIngress hace referencia a un MultiClusterService en la API de flota, en lugar de a un servicio de un clúster de Kubernetes. Esto significa que cualquiera de los ajustes de Ingress, como la terminación de TLS, se puede configurar de la misma forma.

Validar el estado de un despliegue correcto

Google Cloud El despliegue de Load Balancer puede tardar varios minutos en completarse para los nuevos balanceadores de carga. La actualización de los balanceadores de carga se completa más rápido porque no es necesario implementar recursos nuevos. El recurso MultiClusterIngress detalla los recursos subyacentes de Compute Engine que se han creado en nombre de MultiClusterIngress.

  1. Verifica que la implementación se ha realizado correctamente:

    kubectl describe mci whereami-ingress -n whereami
    

    El resultado debería ser similar al siguiente:

    Name:         whereami-ingress
    Namespace:    whereami
    Labels:       <none>
    Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                    {"apiVersion":"networking.gke.io/v1","kind":"MultiClusterIngress","metadata":{"annotations":{},"name":"whereami-ingress","namespace":"whe...
    API Version:  networking.gke.io/v1
    Kind:         MultiClusterIngress
    Metadata:
      Creation Timestamp:  2020-04-10T23:35:10Z
      Finalizers:
        mci.finalizer.networking.gke.io
      Generation:        2
      Resource Version:  26458887
      Self Link:         /apis/networking.gke.io/v1/namespaces/whereami/multiclusteringresses/whereami-ingress
      UID:               62bec0a4-8a08-4cd8-86b2-d60bc2bda63d
    Spec:
      Template:
        Spec:
          Backend:
            Service Name:  whereami-mcs
            Service Port:  8080
    Status:
      Cloud Resources:
        Backend Services:
          mci-8se3df-8080-whereami-whereami-mcs
        Firewalls:
          mci-8se3df-default-l7
        Forwarding Rules:
          mci-8se3df-fw-whereami-whereami-ingress
        Health Checks:
          mci-8se3df-8080-whereami-whereami-mcs
        Network Endpoint Groups:
          zones/europe-west1-b/networkEndpointGroups/k8s1-e4adffe6-whereami-mci-whereami-mcs-svc-lgq966x5m-808-88670678
          zones/us-central1-b/networkEndpointGroups/k8s1-a6b112b6-whereami-mci-whereami-mcs-svc-lgq966x5m-808-609ab6c6
        Target Proxies:
          mci-8se3df-whereami-whereami-ingress
        URL Map:  mci-8se3df-whereami-whereami-ingress
      VIP:        34.98.102.37
    Events:
      Type    Reason  Age                    From                              Message
      ----    ------  ----                   ----                              -------
      Normal  ADD     3m35s                  multi-cluster-ingress-controller  whereami/whereami-ingress
      Normal  UPDATE  3m10s (x2 over 3m34s)  multi-cluster-ingress-controller  whereami/whereami-ingress
    

    Hay varios campos que indican el estado de esta implementación de Ingress:

    • Events es el primer sitio al que acudir. Si se ha producido un error, se mostrará aquí.

    • Cloud Resourcemuestra los recursos de Compute Engine, como las reglas de reenvío, los servicios de backend y las reglas de cortafuegos que ha creado el controlador Ingress multiclúster. Si no aparecen en la lista, significa que aún no se han creado. Puedes inspeccionar recursos de Compute Engine concretos con la consola o el comando gcloud para obtener su estado.

    • VIP muestra una dirección IP cuando se ha asignado una. Ten en cuenta que es posible que el balanceador de carga aún no esté procesando el tráfico aunque exista la IP virtual. Si no ves una dirección IP virtual después de un par de minutos o si el balanceador de carga no devuelve una respuesta 200 en un plazo de 10 minutos, consulta Solución de problemas y operaciones.

    Si los eventos de salida son Normal, es probable que la implementación de MultiClusterIngress se haya realizado correctamente, pero la única forma de determinar si la ruta de tráfico completa funciona es probarla.

  2. Valida que la aplicación esté sirviendo en el VIP con el endpoint /ping:

    curl INGRESS_VIP/ping
    

    Sustituye INGRESS_VIP por la dirección IP virtual (VIP).

    El resultado debería ser similar al siguiente:

    {
    "cluster_name": "gke-us",
    "host_header": "34.120.175.141",
    "pod_name": "whereami-deployment-954cbf78-mtlpf",
    "pod_name_emoji": "😎",
    "project_id": "my-project",
    "timestamp": "2021-11-29T17:01:59",
    "zone": "us-central1-b"
    }
    

    La salida debe indicar la región y el backend de la aplicación.

  3. También puedes ir a la http://INGRESS_VIP URL en tu navegador para ver una versión gráfica de la aplicación que muestra la región desde la que se sirve.

    El clúster al que se reenvía el tráfico depende de tu ubicación. El balanceador de carga de Google Cloud (GCLB) está diseñado para reenviar el tráfico de los clientes al backend disponible más cercano que tenga capacidad.

Especificaciones de recursos

Especificación de MultiClusterService

La definición de MultiClusterService consta de dos partes:

  1. Una sección template que define el servicio que se va a crear en los clústeres de Kubernetes. Ten en cuenta que, aunque la sección template contiene campos admitidos en un servicio típico, solo hay dos campos que se admiten en un MultiClusterService: selector y ports. Se ignoran los demás campos.

  2. Una sección clusters opcional que define qué clústeres reciben tráfico y las propiedades de balanceo de carga de cada clúster. Si no se especifica ninguna sección clusters o no se indica ningún clúster, se usarán todos los clústeres de forma predeterminada.

El siguiente manifiesto describe un MultiClusterService estándar:

apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
  name: NAME
  namespace: NAMESPACE
spec:
  template:
    spec:
      selector:
        app: POD_LABEL
      ports:
      - name: web
        protocol: TCP
        port: PORT
        targetPort: TARGET_PORT

Haz los cambios siguientes:

  • NAME: el nombre del MultiClusterService. Este nombre se hace referencia en el campo serviceName de los recursos MultiClusterIngress.
  • NAMESPACE: el espacio de nombres de Kubernetes en el que se ha desplegado el MultiClusterService. Debe estar en el mismo espacio de nombres que MultiClusterIngress y los pods de todos los clústeres de la flota.
  • POD_LABEL: etiqueta que determina qué pods se seleccionan como back-ends de este MultiClusterService en todos los clústeres de la flota.
  • PORT: debe coincidir con el puerto al que hace referencia el MultiClusterIngress que hace referencia a este MultiClusterService.
  • TARGET_PORT: el puerto que se usa para enviar tráfico al pod desde el balanceador de carga de Google Cloud. Se crea un NEG en cada clúster con este puerto como puerto de servicio.

Especificación de MultiClusterIngress

En el siguiente mci.yaml se describe el frontend del balanceador de carga:

apiVersion: networking.gke.io/v1
kind: MultiClusterIngress
metadata:
  name: NAME
  namespace: NAMESPACE
spec:
  template:
    spec:
      backend:
       serviceName: DEFAULT_SERVICE
       servicePort: PORT
      rules:
        - host: HOST_HEADER
          http:
            paths:
            - path: PATH
              backend:
                serviceName: SERVICE
                servicePort: PORT

Haz los cambios siguientes:

  • NAME: el nombre del recurso MultiClusterIngress.
  • NAMESPACE: el espacio de nombres de Kubernetes en el que se ha desplegado el MultiClusterIngress. Debe estar en el mismo espacio de nombres que MultiClusterService y los pods de todos los clústeres de la flota.
  • DEFAULT_SERVICE: actúa como backend predeterminado para todo el tráfico que no coincida con ninguna regla de host o de ruta. Este campo es obligatorio y se debe especificar un backend predeterminado en MultiClusterIngress, aunque haya otras coincidencias de host o de ruta configuradas.
  • PORT: cualquier número de puerto válido. Debe coincidir con el campo port de los recursos MultiClusterService.
  • HOST_HEADER: coincide con el tráfico por el campo de encabezado de host HTTP. El campo host es opcional.
  • PATH: coincide con el tráfico por la ruta de la URL HTTP. El campo path es opcional.
  • SERVICE: el nombre de un MultiClusterService que se ha desplegado en el mismo espacio de nombres y clúster de configuración que este MultiClusterIngress.

Funciones de Multi Cluster Ingress

En esta sección se explica cómo configurar funciones adicionales de Ingress de varios clústeres.

Selección de clústeres

De forma predeterminada, los servicios derivados de Multi Cluster Ingress se programan en todos los clústeres miembros. Sin embargo, puede que quieras aplicar reglas de entrada a clústeres específicos. Estos son algunos casos prácticos:

  • Aplica Multi Cluster Ingress a todos los clústeres, excepto al clúster de configuración, para aislarlo.
  • Migrar cargas de trabajo entre clústeres de forma gradual.
  • Dirigir el tráfico a back-ends de aplicaciones que solo existen en un subconjunto de clústeres.
  • Usar un único VIP de nivel 7 para el enrutamiento de hosts o de rutas a back-ends que se encuentran en clústeres diferentes.

La selección de clústeres te permite seleccionar clústeres por región o nombre en el objeto MultiClusterService. Controla a qué clústeres apunta tu MultiClusterIngress y dónde se programan los servicios derivados. Los clústeres de la misma flota y región no deben tener el mismo nombre para que se pueda hacer referencia a ellos de forma única.

  1. Abrir mcs.yaml

    apiVersion: networking.gke.io/v1
    kind: MultiClusterService
    metadata:
      name: whereami-mcs
      namespace: whereami
    spec:
      template:
        spec:
          selector:
            app: whereami
          ports:
          - name: web
            protocol: TCP
            port: 8080
            targetPort: 8080
    

    Esta especificación crea servicios derivados en todos los clústeres, que es el comportamiento predeterminado.

  2. Añada las siguientes líneas en la sección de clústeres:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterService
    metadata:
      name: whereami-mcs
      namespace: whereami
    spec:
      template:
        spec:
          selector:
            app: whereami
          ports:
          - name: web
            protocol: TCP
            port: 8080
            targetPort: 8080
      clusters:
      - link: "us-central1-b/gke-us"
      - link: "europe-west1-b/gke-eu"
    

    En este ejemplo, solo se crean recursos de servicio derivado en los clústeres gke-us y gke-eu. Debes seleccionar clústeres para aplicar reglas de entrada de forma selectiva. Si no se especifica la sección "clusters" del MultiClusterService o no se indica ningún clúster, se interpretará como el valor predeterminado "all".

Compatibilidad con HTTPS

El secreto de Kubernetes admite HTTPS. Antes de habilitar la compatibilidad con HTTPS, debes crear una dirección IP estática. Esta IP estática permite que HTTP y HTTPS compartan la misma dirección IP. Para obtener más información, consulta Crear una IP estática.

Una vez que hayas creado una dirección IP estática, podrás crear un secreto.

  1. Crear un secreto:

    kubectl -n whereami create secret tls SECRET_NAME --key PATH_TO_KEYFILE --cert PATH_TO_CERTFILE
    

    Haz los cambios siguientes:

    • SECRET_NAME con el nombre de tu secreto.
    • PATH_TO_KEYFILE con la ruta al archivo de clave TLS.
    • PATH_TO_CERTFILE con la ruta al archivo del certificado TLS.
  2. Actualiza el archivo mci.yaml con el nombre del secreto:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: whereami-ingress
      namespace: whereami
      annotations:
        networking.gke.io/static-ip: STATIC_IP_ADDRESS
    spec:
      template:
        spec:
          backend:
            serviceName: whereami-mcs
            servicePort: 8080
          tls:
          - secretName: SECRET_NAME
    

    Sustituye SECRET_NAME por el nombre de tu secreto. STATIC_IP_ADDRESS es la dirección IP o la URL completa de la dirección que has asignado en la sección Crear una IP estática.

  3. Vuelve a implementar el recurso MultiClusterIngress:

    kubectl apply -f mci.yaml
    

    El resultado debería ser similar al siguiente:

    multiclusteringress.networking.gke.io/whereami-ingress configured
    

Compatibilidad con BackendConfig

El siguiente CRD de BackendConfig te permite personalizar la configuración del recurso BackendService de Compute Engine:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: whereami-health-check-cfg
  namespace: whereami
spec:
  healthCheck:
    checkIntervalSec: [int]
    timeoutSec: [int]
    healthyThreshold: [int]
    unhealthyThreshold: [int]
    type: [HTTP | HTTPS | HTTP2 | TCP]
    port: [int]
    requestPath: [string]
  timeoutSec: [int]
  connectionDraining:
    drainingTimeoutSec: [int]
  sessionAffinity:
    affinityType: [CLIENT_IP | CLIENT_IP_PORT_PROTO | CLIENT_IP_PROTO | GENERATED_COOKIE | HEADER_FIELD | HTTP_COOKIE | NONE]
    affinityCookieTtlSec: [int]
  cdn:
    enabled: [bool]
    cachePolicy:
      includeHost: [bool]
      includeQueryString: [bool]
      includeProtocol: [bool]
      queryStringBlacklist: [string list]
      queryStringWhitelist: [string list]
  securityPolicy:
    name: ca-how-to-security-policy
  logging:
    enable: [bool]
    sampleRate: [float]
  iap:
    enabled: [bool]
    oauthclientCredentials:
      secretName: [string]

Para usar BackendConfig, adjúntalo a tu recurso MultiClusterService mediante una anotación:

apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
  name: whereami-mcs
  namespace: whereami
  annotations:
    cloud.google.com/backend-config: '{"ports": {"8080":"whereami-health-check-cfg"}}'
spec:
 template:
   spec:
     selector:
       app: whereami
     ports:
     - name: web
       protocol: TCP
       port: 8080
       targetPort: 8080

Para obtener más información sobre la semántica de BackendConfig, consulta Asociar un puerto de servicio a un BackendConfig.

Compatibilidad con gRPC

Para configurar aplicaciones gRPC en Ingress con varios clústeres, se necesita una configuración muy específica. A continuación, te ofrecemos algunos consejos para asegurarte de que tu balanceador de carga esté configurado correctamente:

  1. Asegúrate de que el tráfico del balanceador de carga a tu aplicación sea HTTP/2. Para configurarlo, usa protocolos de aplicación.
  2. Asegúrate de que tu aplicación esté configurada correctamente para SSL, ya que es un requisito de HTTP/2. Ten en cuenta que se pueden usar certificados autofirmados.
  3. Debe desactivar mTLS en su aplicación porque no se admite en los balanceadores de carga externos de nivel 7.

Ciclo de vida de los recursos

Cambios en la configuración

Los recursos MultiClusterIngress y MultiClusterService se comportan como objetos estándar de Kubernetes, por lo que los cambios en los objetos se reflejan de forma asíncrona en el sistema. Los cambios que provoquen una configuración no válida harán que los objetosGoogle Cloud asociados no se modifiquen y generen un error en el flujo de eventos del objeto. Los errores asociados a la configuración se registrarán como eventos.

Gestionar recursos de Kubernetes

Si se elimina el objeto Ingress, se desactiva el balanceador de carga HTTP(S), por lo que el tráfico ya no se reenvía a ningún MultiClusterService definido.

Si eliminas el MultiClusterService, se quitarán los servicios derivados asociados de cada uno de los clústeres.

Gestionar clústeres

El conjunto de clústeres a los que se dirige el balanceador de carga se puede cambiar añadiendo o quitando clústeres de la flota.

Por ejemplo, para quitar el clúster gke-eu como backend de un ingress, ejecuta el siguiente comando:

gcloud container fleet memberships unregister CLUSTER_NAME \
  --gke-uri=URI

Haz los cambios siguientes:

  • CLUSTER_NAME: el nombre de tu clúster.
  • URI: el URI del clúster de GKE.

Para añadir un clúster en Europa, ejecuta el siguiente comando:

gcloud container fleet memberships register europe-cluster \
  --context=europe-cluster --enable-workload-identity

Para obtener más información sobre las opciones de registro de clústeres, consulta Registrar un clúster de GKE.

Ten en cuenta que, al registrar o anular el registro de un clúster, se cambia su estado como backend de todos los Ingresses. Si das de baja el clúster gke-eu, dejará de estar disponible como backend para todos los Ingresses que crees. Lo contrario ocurre al registrar un clúster nuevo.

Inhabilitar entrada de varios clústeres

Antes de inhabilitar Multi Cluster Ingress, debes eliminar los recursos MultiClusterIngress y MultiClusterService, y verificar que se han eliminado los recursos de red asociados.

A continuación, para inhabilitar Multi Cluster Ingress, usa el siguiente comando:

gcloud container fleet ingress disable

Si no eliminas los recursos MultiClusterIngress y MultiClusterService antes de inhabilitar Multi Cluster Ingress, puede que se produzca un error similar al siguiente:

Feature has associated resources that should be cleaned up before deletion.

Si quieres inhabilitar Multi Cluster Ingress, usa el siguiente comando:

gcloud container fleet ingress disable --force

Anotaciones

Se admiten las siguientes anotaciones en los recursos MultiClusterIngress y MultiClusterService.

Anotaciones de MultiClusterIngress

Anotación Descripción
networking.gke.io/frontend-config Hace referencia a un recurso FrontendConfig en el mismo espacio de nombres que el recurso MultiClusterIngress.
networking.gke.io/static-ip Hace referencia a la dirección IP literal de una IP estática global.
networking.gke.io/pre-shared-certs Hace referencia a un recurso SSLCertificate global.

Anotaciones de MultiClusterService

Anotación Descripción
networking.gke.io/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 HTTP/2. 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 Usa esta anotación para configurar el servicio de backend asociado a un servicePort. Para obtener más información, consulta la sección sobre la configuración de Ingress.

Políticas de SSL y redirecciones HTTPS

Puedes usar el recurso FrontendConfig para configurar políticas de SSL y redirecciones HTTPS. Las políticas de SSL te permiten especificar qué conjuntos de cifrado y versiones de TLS acepta el balanceador de carga. Las redirecciones HTTPS te permiten forzar la redirección de HTTP o del puerto 80 a HTTPS o al puerto 443. En los siguientes pasos se configuran una política de SSL y un redireccionamiento HTTPS al mismo tiempo. Ten en cuenta que también se pueden configurar de forma independiente.

  1. Crea una política de SSL que rechace las solicitudes que usen una versión inferior a TLS 1.2.

    gcloud compute ssl-policies create tls-12-policy \
     --profile MODERN \
     --min-tls-version 1.2 \
     --project=PROJECT_ID
    

    Sustituye PROJECT_ID por el ID del proyecto en el que se ejecutan tus clústeres de GKE.

  2. Consulta tu política para asegurarte de que se ha creado.

    gcloud compute ssl-policies list --project=PROJECT_ID
    

    El resultado debería ser similar al siguiente:

    NAME           PROFILE  MIN_TLS_VERSION
    tls-12-policy  MODERN   TLS_1_2
    
  3. Crea un certificado para foo.example.com como en este ejemplo. Una vez que tengas el key.pem y el cert.pem, almacena estas credenciales como un secreto al que hará referencia el recurso MultiClusterIngress.

    kubectl -n whereami create secret tls SECRET_NAME --key key.pem --cert cert.pem
    
  4. Guarda el siguiente recurso FrontendConfig como frontendconfig.yaml. Consulta Configurar recursos de FrontendConfig para obtener más información sobre los campos admitidos en un FrontendConfig.

    apiVersion: networking.gke.io/v1beta1
    kind: FrontendConfig
    metadata:
      name: frontend-redirect-tls-policy
      namespace: whereami
    spec:
      sslPolicy: tls-12-policy
      redirectToHttps:
        enabled: true
    

    Este FrontendConfig habilitará las redirecciones HTTPS y una política de SSL que aplique una versión mínima de TLS de 1.2.

  5. Despliega frontendconfig.yaml en tu clúster de configuración.

    kubectl apply -f frontendconfig.yaml --context MCI_CONFIG_CLUSTER
    

    Sustituye MCI_CONFIG_CLUSTER por el nombre de tu clúster de configuración.

  6. Guarda el siguiente MultiClusterIngress como mci-frontendconfig.yaml.

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: foo-ingress
      namespace: whereami
      annotations:
        networking.gke.io/frontend-config: frontend-redirect-tls-policy
        networking.gke.io/static-ip: STATIC_IP_ADDRESS
    spec:
      template:
        spec:
          backend:
            serviceName: default-backend
            servicePort: 8080
          rules:
          - host: foo.example.com
            http:
              paths:
                - backend:
                    serviceName: whereami-mcs
                    servicePort: 8080
          tls:
          - secretName: SECRET_NAME
    
    • Sustituye STATIC_IP_ADDRESS por una dirección IP global estática que ya hayas aprovisionado.
    • Sustituye SECRET_NAME por el secreto en el que se almacena tu certificado foo.example.com.

    Para habilitar las redirecciones HTTPS, debes cumplir dos requisitos:

    • TLS debe estar habilitado, ya sea a través del campo spec.tls o de la anotación de certificado compartido networking.gke.io/pre-shared-certs. El recurso MultiClusterIngress no se desplegará si los redireccionamientos HTTPS están habilitados, pero HTTPS no.
    • Se debe hacer referencia a una IP estática mediante la anotación networking.gke.io/static-ip. Se necesitan IPs estáticas para habilitar HTTPS en un MultiClusterIngress.
  7. Despliega MultiClusterIngress en tu clúster de configuración.

    kubectl apply -f mci-frontendconfig.yaml --context MCI_CONFIG_CLUSTER
    
  8. Espera un minuto o dos e inspecciona foo-ingress.

    kubectl describe mci foo-ingress --context MCI_CONFIG_CLUSTER
    

    El resultado correcto es similar al siguiente:

    • El estado Cloud Resources se rellena con nombres de recursos
    • El campo VIP se rellena con la dirección IP del balanceador de carga.
    Name:         foobar-ingress
    Namespace:    whereami
    
    ...
    
    Status:
      Cloud Resources:
        Backend Services:
          mci-otn9zt-8080-whereami-bar
          mci-otn9zt-8080-whereami-default-backend
          mci-otn9zt-8080-whereami-foo
        Firewalls:
          mci-otn9zt-default-l7
        Forwarding Rules:
          mci-otn9zt-fw-whereami-foobar-ingress
          mci-otn9zt-fws-whereami-foobar-ingress
        Health Checks:
          mci-otn9zt-8080-whereami-bar
          mci-otn9zt-8080-whereami-default-backend
          mci-otn9zt-8080-whereami-foo
        Network Endpoint Groups:
          zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluste-mci-default-backend-svc--80-9e362e3d
          zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluster--mci-bar-svc-067a3lzs8-808-89846515
          zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluster--mci-foo-svc-820zw3izx-808-8bbcb1de
          zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluste-mci-default-backend-svc--80-a528cc75
          zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluster--mci-bar-svc-067a3lzs8-808-36281739
          zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluster--mci-foo-svc-820zw3izx-808-ac733579
        Target Proxies:
          mci-otn9zt-whereami-foobar-ingress
          mci-otn9zt-whereami-foobar-ingress
        URL Map:  mci-otn9zt-rm-whereami-foobar-ingress
      VIP:        34.149.29.76
    Events:
      Type     Reason  Age                From                              Message
      ----     ------  ----               ----                              -------
      Normal   UPDATE  38m (x5 over 62m)  multi-cluster-ingress-controller  whereami/foobar-ingress
    
  9. Para comprobar que las redirecciones HTTPS funcionan correctamente, envía una solicitud HTTP a través de curl.

    curl VIP
    

    Sustituye VIP por la dirección IP de MultiClusterIngress.

    El resultado debe mostrar que la solicitud se ha redirigido al puerto HTTPS, lo que indica que las redirecciones funcionan correctamente.

  10. Verifica que la política de TLS funciona correctamente enviando una solicitud HTTPS con la versión 1.1 de TLS. Como el DNS no está configurado para este dominio, usa la opción --resolve para indicar a curl que resuelva la dirección IP directamente.

    curl https://foo.example.com --resolve foo.example.com:443:VIP --cacert CERT_FILE -v
    

    Para completar este paso, se necesita el archivo PEM del certificado que se usa para proteger el MultiClusterIngress. Si la operación se realiza correctamente, el resultado será similar al siguiente:

    ...
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=foo.example.com
    *  start date: Sep  1 10:32:03 2021 GMT
    *  expire date: Aug 27 10:32:03 2022 GMT
    *  common name: foo.example.com (matched)
    *  issuer: O=example; CN=foo.example.com
    *  SSL certificate verify ok.
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * Using Stream ID: 1 (easy handle 0x7fa10f00e400)
    > GET / HTTP/2
    > Host: foo.example.com
    > User-Agent: curl/7.64.1
    > Accept: */*
    >
    * Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
    < HTTP/2 200
    < content-type: application/json
    < content-length: 308
    < access-control-allow-origin: *
    < server: Werkzeug/1.0.1 Python/3.8.6
    < date: Wed, 01 Sep 2021 11:39:06 GMT
    < via: 1.1 google
    < alt-svc: clear
    <
    {"cluster_name":"gke-us","host_header":"foo.example.com","metadata":"foo","node_name":"gke-gke-us-default-pool-22cb07b1-r5r0.c.mark-church-project.internal","pod_name":"foo-75ccd9c96d-dkg8t","pod_name_emoji":"👞","project_id":"mark-church-project","timestamp":"2021-09-01T11:39:06","zone":"us-central1-b"}
    * Connection #0 to host foo.example.com left intact
    * Closing connection 0
    

    El código de respuesta es 200 y se está usando TLSv1.2, lo que indica que todo funciona correctamente.

    A continuación, puedes verificar que la política de SSL aplica la versión correcta de TLS intentando conectarte con TLS 1.1. Para que este paso funcione, tu política de SSL debe estar configurada con una versión mínima de 1.2.

  11. Envía la misma solicitud que en el paso anterior, pero fuerza la versión 1.1 de TLS.

    curl https://foo.example.com --resolve foo.example.com:443:VIP -v \
      --cacert CERT_FILE \
      --tls-max 1.1
    

    Si la operación se realiza correctamente, el resultado será similar al siguiente:

    * Added foo.example.com:443:34.149.29.76 to DNS cache
    * Hostname foo.example.com was found in DNS cache
    *   Trying 34.149.29.76...
    * TCP_NODELAY set
    * Connected to foo.example.com (34.149.29.76) port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    *   CAfile: cert.pem
      CApath: none
    * TLSv1.1 (OUT), TLS handshake, Client hello (1):
    * TLSv1.1 (IN), TLS alert, protocol version (582):
    * error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert protocol version
    * Closing connection 0
    curl: (35) error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert protocol version
    

    Si no se completa el handshake de TLS, significa que la política de SSL ha bloqueado correctamente TLS 1.1.

Crear una IP estática

  1. Asigna una IP estática:

    gcloud compute addresses create ADDRESS_NAME --global
    

    Sustituye ADDRESS_NAME por el nombre de la IP estática que quieras asignar.

    La salida contiene la URL completa de la dirección que has creado, similar a la siguiente:

    Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses/ADDRESS_NAME].
    
  2. Para ver la dirección IP que acabas de crear, sigue estos pasos:

    gcloud compute addresses list
    

    El resultado debería ser similar al siguiente:

    NAME          ADDRESS/RANGE  TYPE      STATUS
    ADDRESS_NAME  STATIC_IP_ADDRESS  EXTERNAL  RESERVED
    

    Este resultado incluye lo siguiente:

    • El ADDRESS_NAME que has definido.
    • El STATIC_IP_ADDRESS asignado.
  3. Actualiza el archivo mci.yaml con la IP estática:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: whereami-ingress
      namespace: whereami
      annotations:
        networking.gke.io/static-ip: STATIC_IP_ADDRESS
    spec:
      template:
        spec:
          backend:
            serviceName: whereami-mcs
            servicePort: 8080
    

    Sustituye STATIC_IP_ADDRESS por una de las siguientes opciones:

    • La dirección IP asignada, similar a la siguiente: 34.102.201.47
    • La URL completa de la dirección que has creado, similar a la siguiente: "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses/ADDRESS_NAME"

    El STATIC_IP_ADDRESS no es el nombre del recurso (ADDRESS_NAME).

  4. Vuelve a implementar el recurso MultiClusterIngress:

    kubectl apply -f mci.yaml
    

    El resultado debería ser similar al siguiente:

    multiclusteringress.networking.gke.io/whereami-ingress configured
    
  5. Sigue los pasos que se indican en Validar el estado de un despliegue correcto para comprobar que el despliegue se está publicando en STATIC_IP_ADDRESS.

Certificados precompartidos

Los certificados precompartidos son certificados que se suben a Google Cloud y que el balanceador de carga puede usar para la terminación TLS en lugar de los certificados almacenados en secretos de Kubernetes. Estos certificados se suben fuera de banda desde GKE a Google Cloud y se hace referencia a ellos mediante un recurso MultiClusterIngress. También se admiten varios certificados, ya sea mediante certificados compartidos previamente o secretos de Kubernetes.

Para usar los certificados en Multi Cluster Ingress, se necesitan la anotación networking.gke.io/pre-shared-certs y los nombres de los certificados. Cuando se especifican varios certificados para un MultiClusterIngress determinado, se sigue un orden predeterminado para decidir qué certificado se presenta al cliente.

Para ver la lista de certificados SSL disponibles, ejecuta el siguiente comando:

gcloud compute ssl-certificates list

En el siguiente ejemplo se describe el tráfico de clientes a uno de los hosts especificados que coincide con el nombre común de los certificados precompartidos, de modo que se presentará el certificado correspondiente que coincida con el nombre de dominio.

kind: MultiClusterIngress
metadata:
  name: shopping-service
  namespace: whereami
  annotations:
    networking.gke.io/pre-shared-certs: "domain1-cert, domain2-cert"
spec:
  template:
    spec:
      rules:
      - host: my-domain1.gcp.com
        http:
          paths:
          - backend:
              serviceName: domain1-svc
              servicePort: 443
      - host: my-domain2.gcp.com
        http:
          paths:
          - backend:
              serviceName: domain2-svc
              servicePort: 443

Certificados gestionados por Google

Los certificados gestionados por Google se admiten en los recursos de MultiClusterIngress mediante la anotación networking.gke.io/pre-shared-certs. Multi Cluster Ingress permite adjuntar certificados gestionados por Google a un recurso MultiClusterIngress. Sin embargo, a diferencia de Ingress de un solo clúster, no se admite la generación declarativa de un recurso ManagedCertificate de Kubernetes en los recursos MultiClusterIngress. El certificado gestionado por Google se debe crear directamente a través de la API compute ssl-certificates create antes de poder adjuntarlo a un MultiClusterIngress. Para ello, sigue estos pasos:

  1. Crea un certificado gestionado por Google como se indica en el paso 1 de este artículo. No pases al paso 2, ya que Ingress de varios clústeres adjuntará este certificado por ti.

    gcloud compute ssl-certificates create my-google-managed-cert \
        --domains=my-domain.gcp.com \
        --global
    
  2. Haz referencia al nombre del certificado en tu MultiClusterIngress mediante la anotación networking.gke.io/pre-shared-certs.

    kind: MultiClusterIngress
    metadata:
    name: shopping-service
    namespace: whereami
    annotations:
      networking.gke.io/pre-shared-certs: "my-google-managed-cert"
    spec:
    template:
      spec:
        rules:
        - host: my-domain.gcp.com
          http:
            paths:
            - backend:
                serviceName: my-domain-svc
                servicePort: 8080
    

El manifiesto anterior adjunta el certificado a tu MultiClusterIngress para que pueda finalizar el tráfico de tus clústeres de backend de GKE. Google Cloud renovará automáticamente tu certificado antes de que caduque. Las renovaciones se producen de forma transparente y no requieren ninguna actualización de Multi Cluster Ingress.

Protocolos de aplicación

La conexión del proxy del balanceador de carga a tu aplicación usa HTTP de forma predeterminada. Con la anotación networking.gke.io/app-protocols, puedes configurar el balanceador de carga para que use HTTPS o HTTP/2 cuando reenvíe solicitudes a tu aplicación. En el campo annotation del siguiente ejemplo, http2 hace referencia al nombre del puerto MultiClusterService y HTTP2 hace referencia al protocolo que usa el balanceador de carga.

kind: MultiClusterService
metadata:
  name: shopping-service
  namespace: whereami
  annotations:
    networking.gke.io/app-protocols: '{"http2":"HTTP2"}'
spec:
  template:
    spec:
      ports:
      - port: 443
        name: http2

BackendConfig

Consulta la sección anterior sobre cómo configurar la anotación.

Siguientes pasos