Ingress configuration on Google Cloud

En esta página, se proporciona una descripción general integral de lo que se puede configurar a través de un Ingress de Kubernetes en Google Cloud y sus compatibilidades.

Comparación de funciones

En la siguiente tabla, se proporciona una lista de las funciones compatibles de Ingress en Google Cloud. También se indica la disponibilidad de la función Disponibilidad general (DG) o Beta.

Clase de Ingress Ingress externo Ingress interno Ingress de varios clústeres
Controlador de Ingress Controlador de Ingress alojado en Google Controlador de Ingress de GKE
Tipo de balanceador de cargas de Google Cloud Balanceo de cargas de HTTP(S) externo Balanceo de cargas de HTTP(S) interno Balanceo de cargas de HTTP(S) externo
Alcance del clúster Un solo clúster Un solo clúster Varios clústeres
Alcance del balanceador de cargas Global Regional Globales
Compatibilidad con el entorno GKE GKE GKE
Compatibilidad con VPC compartida DG DG DG
Anotaciones de Service
Balanceo de cargas nativo del contenedor (NEG) DG DG DG
HTTPS del balanceador de cargas a los backends DG DG DG
HTTP/2 DG DG
Solo TLS
DG
Anotaciones de Ingress
Direcciones IP estáticas DG DG DG
Certificados basados en Secretos de Kubernetes DG DG DG
Certificados SSL autoadministrados DG DG DG
Certificados SSL administrados por Google DG DG
FrontendConfig
Política de SSL DG DG
Redireccionamiento HTTP a HTTPS DG
1.17.13-gke.2600+DG
DG
BackendConfig
Tiempo de espera del servicio de backend DG DG DG
Cloud CDN DG DG
Tiempo de espera para el desvío de conexión DG DG DG
Configuración de la verificación de estado del balanceador de cargas personalizado DG DG DG
Política de seguridad de Google Cloud Armor DG
1.19.10-gke.700G
DG
Configuración del registro de acceso HTTP DG DG DG
Identity-Aware Proxy (IAP) DG DG DG
Afinidad de sesión DG DG DG
Encabezados de solicitud definidos por el usuario DG DG
Encabezados de respuesta personalizados DG DG

BEsta función está disponible en versión Beta a partir de la versión especificada. Las funciones sin una versión en la lista se admiten para todas las versiones de GKE y GKE Enterprise disponibles.

GEsta función se admite como GA a partir de la versión especificada.

Configura Ingress con el controlador predeterminado

No puedes configurar las características de LoadBalancer de forma manual con el SDK de Google Cloud ni con la consola de Google Cloud. Debes usar los recursos BackendConfig o FrontendConfig de Kubernetes.

Cuando creas un Ingress mediante el controlador predeterminado, puedes elegir el tipo de balanceador de cargas (un balanceador de cargas de aplicaciones externo o interno) mediante una anotación en el objeto Ingress. Puedes elegir si GKE crea NEG zonales o si usa grupos de instancias mediante una anotación en cada objeto Service.

Las definiciones de recursos personalizados (CRD) de FrontendConfig y BackendConfig te permiten personalizar aún más el balanceador de cargas. Estas CRD te permiten definir características del balanceador de cargas adicionales de manera jerárquica y de una forma más estructurada que las anotaciones. Para usar Ingress (y estas CRD), debes tener habilitado el complemento de balanceo de cargas de HTTP. Los clústeres de GKE tienen habilitado el balanceo de cargas de HTTP de forma predeterminada; no debes inhabilitarlo.

Se hace referencia a FrontendConfigs en un objeto Ingress y solo se puede usar con Ingress externos. Se hace referencia a BackendConfigs mediante un objeto de servicio. Varios objetos Service o Ingress pueden hacer referencia a las mismas CRD para mantener la coherencia de la configuración. Las CRD de FrontendConfig y BackendConfig tienen el mismo ciclo de vida que sus recursos de Ingress y Service correspondientes y, a menudo, se implementan juntas.

Asocia FrontendConfig con el Ingress

FrontendConfig solo se puede usar con Ingress externos.

Entrada

Usa la anotación networking.gke.io/v1beta1.FrontendConfig:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    networking.gke.io/v1beta1.FrontendConfig: "FRONTENDCONFIG_NAME"
...

Reemplaza FRONTENDCONFIG_NAME por el nombre de tu FrontendConfig.

Asocia un BackendConfig con el Ingress

Puedes usar la anotación cloud.google.com/backend-config o beta.cloud.google.com/backend-config para especificar el nombre de un BackendConfig.

El mismo BackendConfig para todos los puertos de Service

Para usar el mismo BackendConfig para todos los puertos, usa la clave default en la anotación. El controlador de Ingress usa el mismo BackendConfig cada vez que crea un servicio de backend del balanceador de cargas para hacer referencia a uno de los puertos del Service.

apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/backend-config: '{"default": "my-backendconfig"}'
...

BackendConfig único por puerto de Service

Puedes especificar un BackendConfig personalizado para uno o más puertos a través de una clave que coincida con el nombre o el número del puerto. El controlador de Ingress usa el BackendConfig específico cuando crea un servicio de backend del balanceador de cargas de un puerto del Service al que se hace referencia.

GKE 1.16-gke.3 y posterior

apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/backend-config: '{"ports": {
    "SERVICE_REFERENCE_A":"BACKENDCONFIG_REFERENCE_A",
    "SERVICE_REFERENCE_B":"BACKENDCONFIG_REFERENCE_B"
    }}'
spec:
  ports:
  - name: PORT_NAME_1
    port: PORT_NUMBER_1
    protocol: TCP
    targetPort: 50000
  - name: PORT_NAME_2
    port: PORT_NUMBER_2
    protocol: TCP
    targetPort: 8080
...

Todas las versiones compatibles

apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/backend-config: '{"ports": {
      PORT_NAME_1:"BACKENDCONFIG_REFERENCE_A",
      PORT_NAME_2:"BACKENDCONFIG_REFERENCE_B"
    }}'
spec:
  ports:
  - name: PORT_NAME_1
    port: PORT_NUMBER_1
    protocol: TCP
    targetPort: 50000
  - name: PORT_NAME_2
    port: PORT_NUMBER_2
    protocol: TCP
    targetPort: 8080
...

Reemplaza lo siguiente:

  • BACKENDCONFIG_REFERENCE_A: El nombre de un BackendConfig existente.
  • BACKENDCONFIG_REFERENCE_B: El nombre de un BackendConfig existente.
  • SERVICE_REFERENCE_A: Usa el valor de PORT_NUMBER_1 o PORT_NAME_1. Esto se debe a que la anotación de BackendConfig de un Service puede hacer referencia al nombre del puerto (spec.ports[].name) o al número del puerto (spec.ports[].port).
  • SERVICE_REFERENCE_B: usa el valor de PORT_NUMBER_2 o PORT_NAME_2. Esto se debe a que la anotación de BackendConfig de un Service puede hacer referencia al nombre del puerto (spec.ports[].name) o al número del puerto (spec.ports[].port).

Cuando hagas referencia al puerto del Service por número, debes usar el valor port en lugar del valor targetPort. El número de puerto que se usa aquí es solo para vincular la BackendConfig. no controla el puerto al que el balanceador de cargas envía sondeos de verificación de estado o tráfico:

  • Cuando se usa el balanceo de cargas nativo del contenedor, el balanceador de cargas envía tráfico a un extremo en un grupo de extremos de red (que coincide con una dirección IP del Pod) en el targetPort del puerto del Service de referencia (que debe coincidir con uncontainerPort para un Pod de entrega). De lo contrario, el balanceador de cargas envía tráfico a la dirección IP de un nodo en el nodePort del puerto del Service de referencia.

  • Cuando usas un BackendConfig a fin de proporcionar una verificación de estado del balanceador de cargas personalizado, el número de puerto que usas para esa verificación puede diferir del número spec.ports[].port del Service. Para obtener detalles sobre los números de puerto de las verificaciones de estado, consulta Configuración de la verificación de estado personalizada.

Configura funciones de Ingress a través de parámetros de FrontendConfig

En la siguiente sección, se muestra cómo configurar FrontendConfig para habilitar funciones específicas de Ingress.

Políticas de SSL

Las políticas de SSL te permiten especificar un conjunto de versiones y algoritmos de cifrado de TLS que el balanceador de cargas usa para finalizar el tráfico HTTPS de clientes. Primero debes crear una política de SSL fuera de GKE. Una vez que la creaste, puedes hacer referencia a ella en una CRD de FrontendConfig.

El campo sslPolicy en el FrontendConfig hace referencia al nombre de una política de SSL en el mismo proyecto de Google Cloud que el clúster de GKE. Adjunta la política de SSL al proxy HTTPS de destino, que creó el Ingress para el balanceador de cargas de HTTP(S) externo. Varios recursos de Ingress pueden hacer referencia al mismo recurso FrontendConfig y a la misma política de SSL. Si se cambia una política de SSL a la que se hace referencia, el cambio se propaga a Google Front End (GFE) que potencia tu balanceador de cargas de HTTP(S) externo que creó el Ingress.

En el siguiente manifiesto de FrontendConfig, se habilita una política de SSL llamada gke-ingress-ssl-policy:

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: my-frontend-config
spec:
  sslPolicy: gke-ingress-ssl-policy

Redireccionamientos HTTP a HTTPS

Un balanceador de cargas HTTP externo puede redireccionar las solicitudes HTTP sin encriptar a un balanceador de cargas HTTPS que use la misma dirección IP. Cuando creas un Ingress con redireccionamientos HTTP a HTTPS habilitados, automáticamente se crean ambos balanceadores de cargas. Las solicitudes a la dirección IP externa del Ingress en el puerto 80 se redireccionan de manera automática a la misma dirección IP externa en el puerto 443. Esta funcionalidad se basa en los redireccionamientos de HTTP a HTTPS que proporciona Cloud Load Balancing.

Si quieres admitir el redireccionamiento HTTP a HTTPS, se debe configurar un Ingress para que entregue tráfico HTTP y HTTPS. Si HTTP o HTTPS está inhabilitado, el redireccionamiento no funcionará.

Los redireccionamientos HTTP a HTTPS se configuran con el campo redirectToHttps en un recurso personalizado FrontendConfig. Los redireccionamientos están habilitados para todo el recurso de Ingress, por lo que todos los servicios a los que se hace referencia en Ingress tendrán habilitados los redireccionamientos HTTPS.

El siguiente manifiesto de FrontendConfig habilita los redireccionamientos HTTP a HTTPS. Configura el campo spec.redirectToHttps.enabled como true para habilitar los redireccionamientos HTTPS. El campo spec.responseCodeName es opcional. Si se omite, se utiliza un redireccionamiento 301 Moved Permanently.

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: my-frontend-config
spec:
  redirectToHttps:
    enabled: true
    responseCodeName: RESPONSE_CODE

Reemplaza RESPONSE_CODE por uno de los siguientes valores:

  • MOVED_PERMANENTLY_DEFAULT para mostrar un código de respuesta de redireccionamiento 301 (configuración predeterminada si no se especifica responseCodeName).
  • FOUND para mostrar un código de respuesta de redireccionamiento 302.
  • SEE_OTHER para mostrar un código de respuesta de redireccionamiento 303.
  • TEMPORARY_REDIRECT para mostrar un código de respuesta de redireccionamiento 307.
  • PERMANENT_REDIRECT para mostrar un código de respuesta de redireccionamiento 308.

Cuando los redireccionamientos están habilitados, el controlador de Ingress crea un balanceador de cargas como se muestra en el siguiente diagrama:

Un balanceador de cargas HTTP externo solo de redireccionamiento que consiste en una regla de reenvío, un proxy HTTP de destino y un mapa de URL con un redireccionamiento a un balanceador de cargas HTTPS completo que tiene servicios de backend

Para validar que tu redireccionamiento funciona, usa un comando curl:

curl http://IP_ADDRESS

Reemplaza IP_ADDRESS por la dirección IP de tu Ingress.

En la respuesta, se muestra el código de respuesta de redireccionamiento que configuraste. Por ejemplo, el siguiente ejemplo es para un FrontendConfig configurado con un redireccionamiento 301: MovedPermanently:

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://35.244.160.59/">here</A>.</BODY></HTML>

Configura funciones de Ingress a través de parámetros de BackendConfig

En las siguientes secciones, se muestra cómo configurar tu BackendConfig para habilitar funciones específicas de Ingress. Los cambios en un recurso BackendConfig se concilian de forma constante, por lo que no necesitas borrar y volver a crear el Ingress para comprobar que los cambios de BackendConfig se reflejan.

Para obtener información sobre las limitaciones de BackendConfig, consulta la sección limitaciones.

Tiempo de espera del servicio de backend

Puedes usar un BackendConfig para configurar un tiempo de espera del servicio de backend en segundos. Si no especificas un valor, el predeterminado es de 30 segundos.

En el siguiente manifiesto de BackendConfig, se especifica un tiempo de espera de 40 segundos:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  timeoutSec: 40

Tiempo de espera para vaciado de conexiones

Puedes configurar el tiempo de espera del vaciado de conexiones mediante un BackendConfig. El tiempo de espera para el vaciado de conexiones es el tiempo, en segundos, en que se espera a que las conexiones se vacíen. Durante la duración especificada del tiempo de espera, las solicitudes existentes del backend que se quitó tienen tiempo para completarse. El balanceador de cargas no envía solicitudes nuevas al backend que se quitó. Una vez que transcurre el tiempo de espera, se cierran todas las conexiones restantes al backend. La duración del tiempo de espera puede ser entre 0 y 3,600 segundos. El valor predeterminado es 0, lo que también inhabilita el vaciado de conexiones.

En el siguiente manifiesto de BackendConfig, se especifica un tiempo de espera para el vaciado de conexiones de 60 segundos:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  connectionDraining:
    drainingTimeoutSec: 60

Configuración de la verificación de estado personalizada

GKE tiene diversas formas de configurar las verificaciones de estado del balanceador de cargas de Google Cloud cuando se realiza una implementación a través de Ingress. Para obtener más información sobre cómo GKE Ingress implementa las verificaciones de estado, consulta Verificaciones de estado de Ingress.

BackendConfig te permite controlar con precisión la configuración de la verifición de estado del balanceador de cargas.

Puedes configurar varios objetos Service de GKE para hacer referencia al mismo BackendConfig como una plantilla reutilizable. En el caso de los parámetros de healthCheck, se crea una verificación de estado única de Google Cloud para cada servicio de backend correspondiente a cada Service de GKE.

En el siguiente manifiesto de BackendConfig, se muestran todos los campos disponibles cuando se configura una verificación de estado de un BackendConfig:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  healthCheck:
    checkIntervalSec: INTERVAL
    timeoutSec: TIMEOUT
    healthyThreshold: HEALTH_THRESHOLD
    unhealthyThreshold: UNHEALTHY_THRESHOLD
    type: PROTOCOL
    requestPath: PATH
    port: PORT

Reemplaza lo siguiente:

  • INTERVAL: Especifica el check-interval en segundos para cada sondeador de verificación de estado. Abarca el tiempo desde el inicio de la verificación de un sondeador hasta el comienzo de la siguiente. Si omites este parámetro, se usa el valor predeterminado de 5 segundos de Google Cloud. Para obtener más información sobre la implementación, consulta Varios sondeos y frecuencia.
  • TIMEOUT: Especifica la cantidad de tiempo que Google Cloud espera una respuesta a un sondeo. El valor de TIMEOUT debe ser menor o igual que INTERVAL. Las unidades son segundos. Cada sondeo requiere que se entregue un código de respuesta HTTP 200 (OK) antes de que se agote su tiempo de espera.
  • HEALTH_THRESHOLD y UNHEALTHY_THRESHOLD: Especifican la cantidad de intentos de conexiones secuenciales que deben tener éxito o fallar, al menos para un sondeador, a fin de cambiar el estado de bueno a malo o viceversa. Si omites uno de estos parámetros, Google Cloud usa el valor predeterminado de 2.
  • PROTOCOL: Especifica un protocolo que usan los sistemas de sondeo para la verificación de estado. El BackendConfig solo admite la creación de verificaciones de estado mediante los protocolos HTTP, HTTPS o HTTP2. Si quieres obtener más información, consulta Criterios de éxito para HTTP, HTTPS y HTTP/2. No puedes omitir este parámetro.
  • PATH: Para las verificaciones de estado HTTP, HTTPS o HTTP2, especifica la request-path a la que se debe conectar el sistema de sondeo. Si omites este parámetro, Google Cloud usa el valor predeterminado de /.
  • PORT: BackendConfig solo admite la especificación del puerto de verificación de estado del balanceador de cargas mediante un número de puerto. Si omites este parámetro, Google Cloud usa el valor predeterminado de 80.

    • Cuando usas el balanceo de cargas nativo del contenedor, debes seleccionar un puerto que coincida con un containerPort de un Pod de entrega (sin importar si se hace referencia o no a containerPort mediante un targetPort del objeto Service). Debido a que el balanceador de cargas envía sondeos directamente a la dirección IP del Pod, no estás limitado a las containerPort a las que hace referencia un targetPort del objeto Service. Los sistemas de sondeo de verificación de estado se conectan con la dirección IP de un Pod de entrega en el puerto que especifiques.

    • Para los backends de grupos de instancias, debes seleccionar un puerto que coincida con un nodePort expuesto por el servicio. Entonces, los sistemas de sondeo de verificación de estado se conectan a cada nodo en ese puerto.

Para configurar Ingress de GKE con una verificación de estado HTTP personalizada, consulta Ingress de GKE con verificación de estado HTTP personalizada.

Política de seguridad de Ingress de Google Cloud Armor

Las políticas de seguridad de Google Cloud Armor te ayudan a proteger las aplicaciones con balanceo de cargas de los ataques basados en la Web. Una vez que configuraste una política de seguridad de Google Cloud Armor, puedes hacer referencia a ella mediante un BackendConfig.

Agrega el nombre de tu política de seguridad al BackendConfig. En el siguiente manifiesto de BackendConfig, se especifica una política de seguridad llamada example-security-policy:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  namespace: cloud-armor-how-to
  name: my-backendconfig
spec:
  securityPolicy:
    name: "example-security-policy"

Dos fuentes de verdad

Aunque se configuran a través de GKE, las APIs de BackendService subyacentes de Compute Engine aún se pueden usar para modificar directamente qué política de seguridad aplicar. Esto crea dos fuentes de información: GKE y Compute Engine. En la siguiente tabla, se documenta el comportamiento del controlador de Ingress de GKE en respuesta al campo securityPolicy dentro de BackendConfig. A fin de evitar conflictos y comportamientos inesperados, te recomendamos usar la BackendConfig de GKE para administrar qué política de seguridad usar.

Campo de BackendConfig Valor Comportamiento
spec.securityPolicy.name CloudArmorPolicyName El controlador de Ingress de GKE establece la política de Google Cloud Armor llamada CloudArmorPolicyName en el balanceador de cargas. El controlador de Ingress de GKE reemplaza cualquier política que se haya configurado antes.
spec.securityPolicy.name String vacía ("") El controlador de Ingress de GKE quita cualquier política configurada de Google Cloud Armor del balanceador de cargas.
spec.securityPolicy nil El controlador de Ingress de GKE usa la configuración establecida en el objeto BackendService configurado a través de la API de Compute Engine con la consola de Google Cloud, la CLI de gcloud o Terraform.

Para configurar Ingress de GKE con la protección de Google Cloud Armor, consulta Ingress con Google Cloud Armor.­­

Afinidad de sesión

Puedes usar un BackendConfig para establecer la afinidad de sesión como la IP de cliente o la cookie generada.

Afinidad de IP de cliente

Para usar un BackendConfig con el fin de establecer la afinidad de IP de cliente, configura affinityType como "CLIENT_IP", como se muestra en el siguiente ejemplo:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  sessionAffinity:
    affinityType: "CLIENT_IP"

Para usar un BackendConfig a fin de establecer la afinidad de cookie generada, configura affinityType como GENERATED_COOKIE en el manifiesto de BackendConfig. También puedes usar affinityCookieTtlSec para establecer el período en el que la cookie permanecerá activa.

En el siguiente manifiesto, se establece el tipo de afinidad para la cookie generada y se les otorga a las cookies un TTL de 50 segundos:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  sessionAffinity:
    affinityType: "GENERATED_COOKIE"
    affinityCookieTtlSec: 50

Encabezados de solicitud definidos por el usuario

Puedes usar un BackendConfig para configurar los encabezados de solicitud definidos por el usuario. El balanceador de cargas agrega los encabezados que especifiques a las solicitudes que reenvía a los backends.

Para habilitar los encabezados de solicitud definidos por el usuario, especifica una lista de encabezados en una propiedad customRequestHeaders del recurso BackendConfig. Especifica cada encabezado como una string header-name:header-value.

En el siguiente manifiesto de BackendConfig, se agregan tres encabezados de solicitud:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  customRequestHeaders:
    headers:
    - "X-Client-Region:{client_region}"
    - "X-Client-City:{client_city}"
    - "X-Client-CityLatLong:{client_city_lat_long}"

Encabezados de respuesta personalizados

Para habilitar los encabezados de respuesta personalizados, debes especificar una lista de encabezados en la propiedad customResponseHeaders del recurso BackendConfig. Especifica cada encabezado como una string header-name:header-value.

El siguiente manifiesto de BackendConfig es un ejemplo para agregar un encabezado de respuesta HTTP con Seguridad de Transporte Estricta (HSTS):

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  customResponseHeaders:
    headers:
    - "Strict-Transport-Security: max-age=28800; includeSubDomains"

Ejercicio: configura tiempos de espera de Ingress mediante un servicio de backend

En el siguiente ejercicio, se muestran los pasos necesarios para configurar los tiempos de espera y el vaciado de conexiones con un Ingress mediante un recurso BackendConfig.

Para configurar las propiedades de backend de un Ingress, completa las siguientes tareas:

  1. Crea un Deployment.
  2. Crea un BackendConfig.
  3. Crea un Service y asocia uno de sus puertos al BackendConfig.
  4. Crea un Ingress y asócialo con el par (Service, puerto).
  5. Valida las propiedades del servicio de backend.
  6. Realiza una limpieza.

Crea un Deployment

Antes de crear un BackendConfig y un Service, debes crear un Deployment.

El siguiente manifiesto de ejemplo es para un Deployment llamado my-deployment.yaml:

# my-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      purpose: bsc-config-demo
  replicas: 2
  template:
    metadata:
      labels:
        purpose: bsc-config-demo
    spec:
      containers:
      - name: hello-app-container
        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0

Ejecuta el siguiente comando para crear el Deployment:

kubectl apply -f my-deployment.yaml

Crea un BackendConfig

Usa el BackendConfig para especificar las funciones de Ingress que deseas usar.

En este manifiesto de BackendConfig, llamado my-backendconfig.yaml, se especifica lo siguiente:

  • Un tiempo de espera de 40 segundos
  • Una conexión que agota el tiempo de espera de 60 segundos
# my-backendconfig.yaml
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  timeoutSec: 40
  connectionDraining:
    drainingTimeoutSec: 60

Ejecuta el siguiente comando para crear el BackendConfig:

kubectl apply -f my-backendconfig.yaml

Crea un Service

Un BackendConfig corresponde a una sola combinación de Service y puerto, incluso si un Service tiene varios puertos. Cada puerto se puede asociar con una sola CRD de BackendConfig. Si un Ingress hace referencia a un puerto de Service, y si el puerto de Service se asocia a un BackendConfig, el servicio de backend del balanceo de cargas de HTTP(S) toma parte de su configuración del BackendConfig.

El siguiente es un ejemplo de manifiesto de Service llamado my-service.yaml:

# my-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    purpose: bsc-config-demo
  annotations:
    cloud.google.com/backend-config: '{"ports": {"80":"my-backendconfig"}}'
    cloud.google.com/neg: '{"ingress": true}'
spec:
  type: ClusterIP
  selector:
    purpose: bsc-config-demo
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080

La anotación cloud.google.com/backend-config especifica una asignación entre puertos y objetos BackendConfig. En my-service.yaml:

  • Cualquier Pod que tenga la etiqueta purpose: bsc-config-demo es miembro del Service.
  • El puerto TCP 80 del Service está asociado a un BackendConfig denominado my-backendconfig. Esto se especifica en la anotación cloud.google.com/backend-config.
  • Una solicitud enviada al puerto 80 del Service se reenvía a uno de los Pods miembros en el puerto 8080.

Para crear el Service, ejecuta el siguiente comando:

kubectl apply -f my-service.yaml

Crea un Ingress

El siguiente es un manifiesto de Ingress llamado my-ingress.yaml.. En este ejemplo, las solicitudes entrantes se enrutan al puerto 80 del Service denominado my-service.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        pathType: ImplementationSpecific
        backend:
          service:
            name: my-service
            port:
              number: 80

Para crear el Ingress, ejecuta el siguiente comando:

kubectl apply -f my-ingress.yaml

Espera unos minutos hasta que el controlador de Ingress configure un balanceador de cargas de aplicaciones externo y un servicio de backend asociado. Una vez que se completa, configuraste tu Ingress para usar un tiempo de espera de 40 segundos y un tiempo de espera de vaciado de conexiones de 60 segundos.

Valida las propiedades del servicio de backend

Puedes validar que se aplicó la configuración correcta del balanceador de cargas a través del BackendConfig. Para hacerlo, identifica el servicio de backend que Ingress implementó e inspecciona su configuración a fin de validar que coincida con los manifiestos de Deployment.

Primero, describe el recurso my-ingress y filtra la anotación que enumera los servicios de backend asociados con el Ingress. Por ejemplo:

kubectl describe ingress my-ingress | grep ingress.kubernetes.io/backends

Deberías ver un resultado similar al siguiente:

ingress.kubernetes.io/backends: '{"k8s1-27fde173-default-my-service-80-8d4ca500":"HEALTHY","k8s1-27fde173-kube-system-default-http-backend-80-18dfe76c":"HEALTHY"}

En el resultado, se proporciona información sobre los servicios de backend. Por ejemplo, esta anotación contiene dos servicios de backend:

  • "k8s1-27fde173-default-my-service-80-8d4ca500":"HEALTHY" proporciona información sobre el servicio de backend asociado con el Service de Kubernetes my-service.
    • k8s1-27fde173 es un hash que se usa para describir el clúster.
    • default es el espacio de nombres de Kubernetes.
    • HEALTHY indica que el backend está en buen estado.
  • "k8s1-27fde173-kube-system-default-http-backend-80-18dfe76c":"HEALTHY" proporciona información sobre el servicio de backend asociado con el backend predeterminado (404-server).
    • k8s1-27fde173 es un hash que se usa para describir el clúster.
    • kube-system es el espacio de nombres.
    • default-http-backend es el nombre del servicio de Kubernetes.
    • 80 es el puerto del host.
    • HEALTHY indica que el backend está en buen estado.

A continuación, inspecciona el servicio de backend asociado con my-service mediante gcloud. Filtra "drainingTimeoutSec" y "timeoutSec" para confirmar que se configuraron en el plano de control del balanceador de cargas de Google Cloud. Por ejemplo:

# Optionally, set a variable
export BES=k8s1-27fde173-default-my-service-80-8d4ca500

# Filter for drainingTimeoutSec and timeoutSec
gcloud compute backend-services describe ${BES} --global | grep -e "drainingTimeoutSec" -e "timeoutSec"

Resultado:

  drainingTimeoutSec: 60
  timeoutSec: 40

Si ves drainingTimeoutSec y timeoutSec en el resultado, esto significa que los valores se configuraron de forma correcta a través del BackendConfig.

Realice una limpieza

Si deseas evitar que se generen cargos no deseados en tu cuenta, borra los objetos de Kubernetes que creaste para este ejercicio:

kubectl delete ingress my-ingress
kubectl delete service my-service
kubectl delete backendconfig my-backendconfig
kubectl delete deployment my-deployment

Limitaciones de BackendConfig

BackendConfig tiene las siguientes limitaciones:

  • Un par (Service, puerto) puede consumir solo un BackendConfig, incluso si varios objetos Ingress hacen referencia al (Service, puerto). Esto significa que todos los objetos Ingress que hacen referencia al mismo (Service, puerto) deben usar la misma configuración para Google Cloud Armor.
  • Debes usar kubectl 1.7 o posterior para interactuar con BackendConfig.

Quita la configuración especificada en un FrontendConfig o un BackendConfig

Para revocar una función de Ingress, debes inhabilitar de manera explícita la configuración de funciones en la CRD de FrontendConfig o BackendConfig. El controlador de Ingress solo concilia las opciones de configuración especificadas en estas CRD.

Para borrar o inhabilitar una configuración habilitada con anterioridad, establece el valor del campo como una string vacía ("") o un valor booleano de false, según el tipo de campo.

Borra un FrontendConfig o un BackendConfig

FrontendConfig

Para borrar un FrontendConfig, sigue estos pasos:

  1. Quita el nombre del FrontendConfig de la anotación networking.gke.io/v1beta1.FrontendConfig en el manifiesto de Ingress.

  2. Aplica el manifiesto de Ingress modificado a tu clúster. Por ejemplo, usa kubectl apply.

  3. Borra el FrontendConfig. Por ejemplo, usa kubectl delete frontendconfig config my-frontendconfig.

BackendConfig

Para borrar un BackedConfig, sigue estos pasos:

  1. Quita el nombre del BackendConfig de la anotación cloud.google.com/backend-config en el manifiesto de Service.

  2. Aplica el manifiesto de Service modificado tu clúster. Por ejemplo, usa kubectl apply.

  3. Borra el BackendConfig. Por ejemplo, usa kubectl delete backendconfig my-backendconfig.

Soluciona problemas

Puedes detectar opciones de configuración incorrectas comunes con la herramienta de diagnóstico de Ingress. También debes asegurarte de que las verificaciones de estado estén configuradas de forma correcta.

No se encontró el BackendConfig

Este error ocurre cuando un BackendConfig de un puerto de Service se especifica en la anotación de Service, pero no se pudo encontrar el recurso BackendConfig.

Para evaluar un evento de Kubernetes, ejecuta el siguiente comando:

kubectl get event

En el siguiente resultado de ejemplo, se indica que no se encontró tu BackendConfig:

KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: error getting BackendConfig for port 80 on service "default/my-service":
no BackendConfig for service port exists

Para resolver este problema, asegúrate de no haber creado el recurso BackendConfig en el espacio de nombres incorrecto ni escrito mal su referencia en la anotación del Service.

No se encontró la política de seguridad de Ingress

Después de crear el objeto Ingress, si la política de seguridad no está asociada de forma correcta al Service LoadBalancer, evalúa el evento de Kubernetes para ver si hay un error de configuración. Si el BackendConfig especifica una política de seguridad que no existe, se emite un evento de advertencia de forma periódica.

Para evaluar un evento de Kubernetes, ejecuta el siguiente comando:

kubectl get event

En el siguiente resultado de ejemplo, se indica que no se encontró la política de seguridad:

KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: The given security policy "my-policy" does not exist.

Para resolver este problema, especifica el nombre de la política de seguridad correcto en tu BackendConfig.

Aborda los errores 500 de la serie con NEG durante el escalamiento de las cargas de trabajo en GKE

Síntoma:

Cuando usas NEG aprovisionados por GKE para el balanceo de cargas, es posible que experimentes errores 502 o 503 en los servicios durante la reducción vertical de escala de la carga de trabajo. Los errores 502 se producen cuando los Pods finalizan antes de que se cierren las conexiones existentes, mientras que los errores 503 se producen cuando el tráfico se dirige a Pods borrados.

Este problema puede afectar a los clústeres si usas productos de balanceo de cargas administrados por GKE que usan NEG, incluidos los NEG independientes, de puerta de enlace y de Ingress. Si escalas tus cargas de trabajo con frecuencia, tu clúster tiene un mayor riesgo de verse afectado.

Diagnóstico:

Quitar un Pod en Kubernetes sin desviar su extremo ni quitarlo del NEG primero genera errores de la serie 500. Para evitar problemas durante la finalización de los Pods, debes considerar el orden de las operaciones. En las siguientes imágenes, se muestran situaciones en las que BackendService Drain Timeout no está configurado y BackendService Drain Timeout se establece con BackendConfig.

Situación 1: BackendService Drain Timeout no está configurado.

En la siguiente imagen, se muestra una situación en la que BackendService Drain Timeout no está configurado.

Tiempo de espera del desvío de BackendService no está configurado

Situación 2: BackendService Drain Timeout está configurado.

En la siguiente imagen, se muestra una situación en la que BackendService Drain Timeout está configurado.

Tiempo de espera del desvío de BackendService está configurado

El momento exacto en el que se producen los errores de la serie 500 depende de los siguientes factores:

  • Latencia de desconexión de la API de NEG: La latencia de desconexión de la API de NEG representa el tiempo actual que tarda la operación de desconexión en finalizar en Google Cloud. Esto depende de una variedad de factores externos a Kubernetes, incluidos el tipo de balanceador de cargas y la zona específica.

  • Latencia de desvío: La latencia de desvío representa el tiempo que tarda el balanceador de cargas en comenzar a dirigir el tráfico fuera de una parte específica del sistema. Una vez que se inicia el desvío, el balanceador de cargas deja de enviar solicitudes nuevas al extremo. Sin embargo, aún hay una latencia en la activación del desvío (latencia de desvío) que puede causar errores 503 temporales si el Pod ya no existe.

  • Configuración de la verificación de estado: Los umbrales de verificación de estado más sensibles mitigan la duración de los errores 503, ya que pueden indicarle al balanceador de cargas que deje de enviar solicitudes a los extremos, incluso si la operación de desconexión no ha finalizado.

  • Período de gracia de finalización: El período de gracia de finalización determina el tiempo máximo que tiene un Pod para salir. Sin embargo, un Pod puede salir antes de que se complete el período de gracia de finalización. Si un Pod tarda más que este período, se fuerza la salida del Pod al final de este período. Este es un parámetro de configuración del Pod y debe configurarse en la definición de la carga de trabajo.

Resolución posible:

Para evitar esos errores 5XX, aplica la siguiente configuración. Los valores de tiempo de espera son sugeridos y es posible que debas ajustarlos para tu aplicación específica. En la siguiente sección, se te guiará a través del proceso de personalización.

En la siguiente imagen, se muestra cómo mantener el Pod activo con preStopHook:

Tiempo de espera del desvío de BackendService está configurado

Para evitar errores de la serie 500, sigue estos pasos:

  1. Establece el BackendService Drain Timeout del servicio en 1 minuto.

  2. Extiende terminationGracePeriod en el Pod.

    Establece terminationGracePeriodSeconds en el Pod en 3.5 minutos. Cuando se combina con la configuración recomendada, esto les da a los Pods un período de 30 a 45 segundos para un cierre ordenado después de que el extremo del Pod se quite del NEG. Si necesitas más tiempo para el cierre ordenado, puedes extender el período de gracia o seguir las instrucciones mencionadas en la sección Personaliza los tiempos de espera.

    En el siguiente manifiesto de BackendConfig, se especifica un tiempo de espera de vaciado de conexiones de 210 segundos (3.5 minutos):

    apiVersion: v1
    kind: BackendConfig
    metadata:
      name: my-backendconfig
    spec:
      terminationGracePeriodSeconds: 210
      containers:
      - name: my-app
        image: my-app-image:latest
        ports:
        - containerPort: 80
    
  3. Aplica un preStopHook a todos los contenedores.

    Aplica un preStopHook que garantizará que el Pod esté activo durante 120 segundos más mientras el extremo del Pod se vacía en el balanceador de cargas y se quita el extremo del NEG.

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    spec:
      containers:
      - name: my-app
        # Container configuration details...
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "sleep 120s"]
    

Personaliza los tiempos de espera

Para garantizar la continuidad del Pod y evitar errores de la serie 500, el Pod debe estar activo hasta que se quite el extremo del NEG. Especialmente para evitar errores 502 y 503, considera implementar una combinación de tiempos de espera y un preStopHook.

Para mantener el Pod activo por más tiempo durante el proceso de cierre, agrega un preStopHook al Pod. Ejecuta preStopHook antes de que se le indique a un Pod que debe salir, por lo que preStopHook se puede usar para mantener al Pod activo hasta que se quite su extremo correspondiente del NEG.

Para extender el período en que un Pod permanece activo durante el proceso de cierre, inserta preStopHook en la configuración del Pod de la siguiente manera:

spec:
  containers:
  - name: my-app
    ...
    lifecycle:
      preStopHook:
        exec:
          command: ["/bin/sh", "-c", "sleep <latency time>"]

Puedes establecer tiempos de espera y parámetros de configuración relacionados para administrar el cierre ordenado de Pods durante las reducciones verticales de escala de las cargas de trabajo. Puedes ajustar los tiempos de espera según casos de uso específicos. Te recomendamos que comiences con tiempos de espera más largos y reduzcas la duración según sea necesario. Puedes personalizar los tiempos de espera configurando parámetros relacionados con el tiempo de espera y el preStopHook de las siguientes maneras:

Tiempo de espera de desvío del servicio de backend

El parámetro Backend Service Drain Timeout no está configurado de forma predeterminada y no tendrá efecto. Si configuras el parámetro Backend Service Drain Timeout y lo activas, el balanceador de cargas dejará de enrutar solicitudes nuevas al extremo y esperará el tiempo de espera antes de finalizar las conexiones existentes.

Puedes establecer el parámetro Backend Service Drain Timeout mediante BackendConfig con Ingress, GCPBackendPolicy con la puerta de enlace o de forma manual en BackendService con NEG independientes. El tiempo de espera debe ser de 1.5 a 2 veces más extenso que el tiempo que lleva procesar una solicitud. Esto garantiza que si una solicitud llega justo antes de que se inicie el desvío, se completará antes de que se complete el tiempo de espera. Establecer el parámetro Backend Service Drain Timeout en un valor mayor que 0 ayuda a mitigar los errores 503 porque no se envían solicitudes nuevas a los extremos programados para su eliminación. Para que este tiempo de espera sea eficaz, debes usarlo junto con el preStopHook a fin de asegurarte de que el Pod permanezca activo mientras se produce el desvío. Sin esta combinación, las solicitudes existentes que no se completen recibirán un error 502.

Tiempo de preStopHook

El preStopHook debe retrasar el cierre del Pod lo suficiente para que se completen la latencia de desvío y el tiempo de espera de desvío del servicio de backend, lo que garantiza que el vaciado de conexiones y la eliminación de extremos del NEG se realicen correctamente antes de que se cierre el Pod.

Para obtener resultados óptimos, asegúrate de que el tiempo de ejecución de preStopHook sea menor o igual que la suma de los valores de Backend Service Drain Timeout y latencia de desvío.

Esto se puede calcular con la siguiente fórmula:

preStopHook >= Backend Service Drain Timeout + Drain Latency

Te recomendamos establecer la latencia de desvío en 1 minuto. Si los errores 500 persisten, calcula la duración total del caso y agrega el doble de ese tiempo a la latencia. Esto garantiza que tu Pod tenga tiempo suficiente para desviarse de forma ordenada antes de quitarse del servicio. Puedes ajustar este valor si es demasiado largo para tu caso de uso específico.

Como alternativa, puedes estimar el tiempo analizando la marca de tiempo de eliminación del Pod y la marca de tiempo en la que el extremo se quitó del NEG en los Registros de auditoría de Cloud.

Parámetro de período de gracia de finalización

Debes configurar el parámetro terminationGracePeriod a fin de permitir el tiempo suficiente para que el preStopHook finalice y para que el Pod complete un cierre ordenado.

De forma predeterminada, cuando no se establece de forma explícita, el terminationGracePeriod es 30 segundos. Puedes calcular el terminationGracePeriod óptimo con la siguiente fórmula:

terminationGracePeriod >= preStopHook Time + Pod shutdown time

Puedes definir terminationGracePeriod dentro de la configuración del Pod de la siguiente manera:

  spec:
    terminationGracePeriodSeconds: <terminationGracePeriod>
    containers:
    - name: my-app
      ...
    ...

No se encontró el NEG cuando se creó un recurso Ingress interno

El siguiente error puede ocurrir cuando creas un Ingress interno en GKE:

Error syncing: error running backend syncing routine: googleapi: Error 404: The resource 'projects/PROJECT_ID/zones/ZONE/networkEndpointGroups/NEG' was not found, notFound

Este error se produce porque Ingress para los balanceadores de cargas de aplicaciones internos requiere grupos de extremos de red (NEG) como backends.

En entornos de VPC compartida o clústeres con las Políticas de red habilitadas, agrega la anotación cloud.google.com/neg: '{"ingress": true}' al manifiesto del Service.

504 Gateway Timeout: tiempo de espera de solicitud ascendente

El siguiente error puede ocurrir cuando accedes a un Service desde un Ingress interno en GKE:

HTTP/1.1 504 Gateway Timeout
content-length: 24
content-type: text/plain

upsteam request timeout

Este error se produce porque los proxies de Envoy envían el tráfico a los balanceadores de cargas de aplicaciones internos en el rango de subredes de solo proxy.

Para permitir el tráfico desde el rango de subred de solo proxy, crea una regla de firewall en el targetPort del Service.

Error 400: Valor no válido para el campo “resource.target”

El siguiente error puede ocurrir cuando accedes a un Service desde un Ingress interno en GKE:

Error syncing:LB_NAME does not exist: googleapi: Error 400: Invalid value for field 'resource.target': 'https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION_NAME/targetHttpProxies/LB_NAME. A reserved and active subnetwork is required in the same region and VPC as the forwarding rule.

Para resolver este problema, crea una subred de solo proxy.

Error durante la sincronización: error durante la ejecución de la rutina de sincronización del balanceador de cargas: el balanceador de cargas no existe

Uno de los siguientes errores puede ocurrir cuando se actualiza el plano de control de GKE o cuando modificas un objeto Ingress:

"Error during sync: error running load balancer syncing routine: loadbalancer
INGRESS_NAME does not exist: invalid ingress frontend configuration, please
check your usage of the 'kubernetes.io/ingress.allow-http' annotation."

Como alternativa, puedes hacer lo siguiente:

Error during sync: error running load balancer syncing routine: loadbalancer LOAD_BALANCER_NAME does not exist:
googleapi: Error 400: Invalid value for field 'resource.IPAddress':'INGRESS_VIP'. Specified IP address is in-use and would result in a conflict., invalid

Para resolver estos problemas, prueba los siguientes pasos:

  • Agrega el campo hosts en la sección tls del manifiesto de Ingress y, luego, borra el Ingress. Espera cinco minutos para que GKE borre los recursos de Ingress sin usar. Luego, vuelve a crear el Ingress. Para obtener más información, consulta El campo de hosts de un objeto Ingress.
  • Revierte los cambios que realizaste al Ingress. Luego, agrega un certificado a través de una anotación o un Secret de Kubernetes.

Problemas conocidos

No se pueden habilitar los redireccionamientos HTTPS con el esquema de nombres de Ingress V1

No puedes habilitar los redireccionamientos HTTPS en los recursos Ingress de GKE creados en las versiones de GKE 1.16.8-gke.12 y anteriores. Debes volver a crear el Ingress antes de que puedas habilitar los redireccionamientos a HTTPS o se creará un evento de error y el Ingress no se sincronizará.

El mensaje de evento de error es similar al siguiente:

Error syncing: error running load balancer syncing routine: loadbalancer lb-name does not exist: ensureRedirectUrlMap() = error: cannot enable HTTPS Redirects with the V1 Ingress naming scheme. Please recreate your ingress to use the newest naming scheme.

Se quitaron los campos de la política de seguridad de Google Cloud Armor de BackendConfig

Existe un problema conocido en el que la actualización de un recurso BackendConfig mediante la API de v1beta1 quita una política de seguridad activa de Google Cloud Armor del Service. Este problema afecta a las siguientes versiones de GKE:

  • De 1.18.19-gke.1400 a 1.18.20-gke.5099
  • De 1.19.10-gke.700 a 1.19.14-gke.299
  • De 1.20.6-gke.700 a 1.20.9-gke.899

Si no configuras Google Cloud Armor en tus recursos de Ingress a través de BackendConfig, este problema no afecta a tus clústeres.

Para los clústeres de GKE que configuran Google Cloud Armor a través de BackendConfig, se recomienda enfáticamente que solo actualices los recursos de BackendConfig mediante la API de v1. Si aplicas un BackendConfig a tu clúster mediante los recursos v1beta1 de BackendConfig, se quitará la política de seguridad de Google Cloud Armor del Service al que hace referencia.

Para mitigar este problema, solo realiza actualizaciones en tu BackendConfig con la API de BackendConfig v1. BackendConfig v1 admite los mismos campos que v1beta1 y no realiza cambios rotundos, por lo que el campo de la API se puede actualizar de manera transparente. Reemplaza el campo apiVersion de cualquier manifiesto de BackendConfig activo con cloud.google.com/v1 y no uses cloud.google.com/v1beta1. En el siguiente manifiesto de muestra, se describe un recurso de BackendConfig que usa la API de v1:

  apiVersion: cloud.google.com/v1
  kind: BackendConfig
  metadata:
    name: my-backend-config
  spec:
    securityPolicy:
      name: "ca-how-to-security-policy"

Si tienes sistemas o herramientas de CI/CD que actualizan recursos de BackendConfig con regularidad, asegúrate de usar el grupo de API cloud.google.com/v1 en esos sistemas.

Si tu BackendConfig ya se actualizó con la API v1beta1, es posible que se haya quitado la política de seguridad de Google Cloud Armor. Para determinar si esto ocurrió, ejecuta el siguiente comando:

kubectl get backendconfigs -A -o json | jq -r '.items[] | select(.spec.securityPolicy == {}) | .metadata | "\(.namespace)/\(.name)"'

Si la respuesta muestra un resultado, entonces, tu clúster se vio afectado por el problema. En el resultado de este comando, se muestra una lista de los recursos de BackendConfig (<namespace>/<name>) que se ven afectados por el problema. Si el resultado está vacío, entonces, tu BackendConfig no se ha actualizado mediante la API de v1beta1 desde que se presentó el problema. Las actualizaciones futuras de tu BackendConfig solo deben usar v1.

Si se quitó la política de seguridad de Google Cloud Armor, puedes determinar cuándo se quitó mediante la siguiente consulta de Logging:

resource.type="gce_backend_service"
protoPayload.methodName="v1.compute.backendServices.setSecurityPolicy"
protoPayload.authenticationInfo.principalEmail:"container-engine-robot.iam.gserviceaccount.com"
protoPayload.response.status = "RUNNING"
NOT protoPayload.authorizationInfo.permission:"compute.securityPolicies.use"

Si alguno de tus clústeres se vio afectado, envía una actualización a tu recurso de BackendConfig que usa la API de v1 para corregir esto.

Actualiza tu plano de control de GKE a una de las siguientes versiones actualizadas que aplican parches a este problema y permiten que los recursos de BackendConfig v1beta1 se usen de forma segura:

  • 1.18.20-gke.5100 y posteriores
  • 1.19.14-gke.300 y posteriores
  • 1.20.9-gke.900 y posteriores

¿Qué sigue?