Protege el tráfico de Ingress de GKE

En esta página, se muestra cómo proteger y optimizar el tráfico de Ingress de Google Kubernetes Engine (GKE). Puedes configurar certificados SSL entre el cliente y el balanceador de cargas, y proteger el tráfico entre el balanceador de cargas y tu aplicación de backend. Antes de continuar, asegúrate de saber cómo GKE protege Ingress con HTTPS.

Esta página está dirigida a especialistas en redes que diseñan la red para su organización y que instalan, configuran y brindan asistencia técnica para el equipo de redes. Para obtener más información sobre los roles comunes y las tareas de ejemplo a las que hacemos referencia en el contenido deGoogle Cloud , consulta Roles y tareas comunes del usuario de GKE.

Protege y optimiza el tráfico entre el cliente y el balanceador de cargas

Para aceptar solicitudes HTTPS de tus clientes, el balanceador de cargas debe tener un certificado para demostrar su identidad a los clientes. El balanceador de cargas también debe tener una clave privada para completar el protocolo de enlace HTTPS. Para obtener más información sobre cómo proporcionar certificados SSL a un balanceador de cargas HTTP(S), consulta Configura TLS entre el cliente y el balanceador de cargas.

Usa certificados administrados por Google

Para configurar uno o más certificados SSL administrados por Google y asociarlos con un Ingress, debes seguir estos pasos:

  • Crea uno o más objetos ManagedCertificate en el mismo espacio de nombres que el Ingress. Puedes especificar hasta 15 certificados para el balanceador de cargas.
  • Agrega la anotación networking.gke.io/managed-certificates al Ingress para asociar los objetos ManagedCertificate a un Ingress. Esta anotación es una lista separada por comas de objetos ManagedCertificate.

Limitaciones

En esta sección, se describen las limitaciones de los certificados administrados por Google. Si necesitas certificados autoadministrados o si ya posees certificados SSL que deseas configurar en el Ingress, consulta Configura HTTPS (TLS) entre el cliente y el balanceador de cargas.

  • Los certificados administrados por Google son menos flexibles que los certificados que tú obtienes y administras. Los certificados administrados por Google admiten hasta 100 dominios sin comodines. A diferencia de los certificados autoadministrados, los certificados administrados por Google no admiten dominios comodines.

  • La cantidad y el tipo de certificados admitidos por un Ingress están definidos por los límites de los certificados SSL administrados por Google.

  • No se admiten las actualizaciones en los certificados administrados por Google. Para obtener más información, consulta Actualiza un certificado administrado por Google de forma manual.

  • Si el certificado se revoca directamente con la autoridad certificadora, Google no lo rotará de forma automática. Debes borrar el ManagedCertificate y crear uno nuevo.

  • GKE Ingress no admite certificados administrados por el Administrador de certificados. Para usar los certificados administrados por el Administrador de certificados, usa la API de Gateway.

Requisitos previos

  • Debes ser dueño del nombre de dominio. El nombre de dominio no debe tener más de 63 caracteres. Puedes usar cualquier registrador de nombres de dominio para obtener un nombre de dominio.

  • Si usas un clúster de GKE Standard, el complemento HttpLoadBalancing debe estar habilitado.

  • Tu manifiesto de Ingress debe incluir la anotación kubernetes.io/ingress.class: "gce". No se admite el campo ingressClassName.

  • Debes aplicar los recursos Ingress y ManagedCertificate en el mismo proyecto y el mismo espacio de nombres.

  • Crea una dirección IP externa (estática) reservada. Reservar una dirección IP estática garantiza que te pertenece, incluso si borras el Ingress. Si no reservas una dirección IP, es posible que esta cambie y requiera que vuelvas a configurar los registros DNS de tu dominio. Usa Google Cloud CLI o la consola de Google Cloud para crear una dirección IP reservada.

    gcloud

    Para crear una dirección IP reservada, ejecuta el siguiente comando:

    gcloud compute addresses create ADDRESS_NAME --global
    

    Reemplaza ADDRESS_NAME por el nombre de la dirección IP reservada que creas.

    Para encontrar la dirección IP estática que creaste, ejecuta el siguiente comando:

    gcloud compute addresses describe ADDRESS_NAME --global
    

    El resultado es similar a este:

    address: 203.0.113.32
    ...
    

    Console

    Para crear una dirección IP reservada, sigue estos pasos:

    1. Ve a la página Direcciones IP externas en la consola de Google Cloud .

      Ir a Direcciones IP externas

    2. Especifica un nombre para la dirección IP (por ejemplo, example-ip-address).

    3. Especifica si deseas una dirección IPv4 o IPv6.

    4. Selecciona la opción Global para Tipo.

    5. Haz clic en Reservar. La dirección IP aparece en la columna Dirección externa.

    Config Connector

    Nota: En este paso, se necesita Config Connector. Sigue las instrucciones de instalación para instalar Config Connector en el clúster.

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: example-ip-address
    spec:
      location: global
    Para implementar este manifiesto, descárgalo en tu máquina como compute-address.yaml y ejecuta lo siguiente:

    kubectl apply -f compute-address.yaml
    

Configura un certificado administrado por Google

  1. Crea un objeto ManagedCertificate. Este recurso especifica los dominios para el certificado SSL. Los dominios de comodín no son compatibles.

    El siguiente manifiesto describe un objeto ManagedCertificate. Guarda el manifiesto como managed-cert.yaml.

    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: FIRST_CERT_NAME
    spec:
      domains:
        - FIRST_DOMAIN
    ---
    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: SECOND_CERT_NAME
    spec:
      domains:
        - SECOND_DOMAIN
    

    Reemplaza lo siguiente:

    • FIRST_CERT_NAME: Es el nombre de tu primer objeto ManagedCertificate.
    • FIRST_DOMAIN: Es el primer dominio que posees.
    • SECOND_CERT_NAME: Es el nombre del segundo objeto ManagedCertificate.
    • SECOND_DOMAIN: Es el segundo dominio que posees.

    Los nombres de los objetos ManagedCertificate son diferentes de los nombres de los certificados reales que crean. Solo necesitas conocer los nombres de los objetos ManagedCertificate para usarlos en tu Ingress.

  2. Aplica el manifiesto al clúster:

    kubectl apply -f managed-cert.yaml
    
  3. Sigue las instrucciones para crear una Deployment y un servicio para exponer tu aplicación a Internet.

  4. Para que este objeto ManagedCertificate se convierta en Active, adjúntalo a tu Ingress con la anotación networking.gke.io/managed-certificates, como en el siguiente ejemplo. No es necesario que ManagedCertificate sea Active para que puedas conectarlo a un Ingress.

     apiVersion: networking.k8s.io/v1
     kind: Ingress
     metadata:
       name: my-gmc-ingress
       annotations:
         networking.gke.io/managed-certificates: "FIRST_CERT_NAME,SECOND_CERT_NAME"
     spec:
       rules:
       - host: FIRST_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60001
       - host: SECOND_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60002
     ```
    
    Replace <code><var>FIRST_DOMAIN</var></code> and
    <code><var>SECOND_DOMAIN</var></code> with your domain names.
    
    This manifest describes an Ingress that lists pre-shared certificate
    resources in an annotation.
    
    Note: It might take several hours for Google Cloud to provision the load
    balancer and the managed certificates, and for the load balancer to begin
    using the new certificates. For more information, see
    [Deploy a Google-managed certificate with load balancer authorization](/certificate-manager/docs/deploy-google-managed-lb-auth#wait_until_the_certificate_has_been_activated).
    
  5. Espera a que los certificados administrados por Google terminen de aprovisionarse. Este proceso puede llevar hasta 60 minutos. Puedes verificar el estado de los certificados con el siguiente comando:

    kubectl describe managedcertificate managed-cert
    

    El resultado es similar a lo siguiente:

    Name:         managed-cert
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1
    Kind:         ManagedCertificate
    (...)
    Spec:
     Domains:
       FQDN_1
       FQDN_2
    Status:
     CertificateStatus: Active
    (...)
    

    El valor del campo Status.CertificateStatus indica que se aprovisionó el certificado. Si Status.CertificateStatus no es Active, el certificado aún no se aprovisionó.

  6. Para verificar que SSL funcione, visita los dominios con el prefijo https://. Tu navegador indica que la conexión es segura y puedes ver los detalles del certificado.

Migra a certificados administrados por Google desde certificados autoadministrados

Cuando migras un Ingress desde el uso de certificados SSL autoadministrados a certificados SSL administrados por Google, no debes borrar ningún certificado SSL autoadministrado antes de que los certificados SSL administrados por Google se activen. Una vez que los certificados SSL administrados por Google se aprovisionan de forma correcta, estos se activan de forma automática. Cuando los certificados SSL administrados por Google están activos, puedes borrar tus certificados SSL autoadministrados.

Usa estas instrucciones para migrar desde los certificados autoadministrados hasta los SSL administrados por Google.

  1. Agrega un nuevo certificado administrado por Google al Ingress, como se describe en la sección anterior.
  2. Espera hasta que el estado del recurso del certificado administrado por Google sea Active. Verifica el estado del certificado con el siguiente comando:

    kubectl describe managedcertificate managed-cert
    
  3. Cuando el estado sea Active, actualiza el Ingress para quitar las referencias al certificado autoadministrado.

Quita un certificado administrado por Google

Para quitar un certificado administrado por Google de tu clúster, debes borrar el objeto ManagedCertificate y quitar la anotación de Ingress que hace referencia a él.

  1. Borra el objeto ManagedCertificate:

    kubectl delete -f managed-cert.yaml
    

    El resultado es similar a este:

    managedcertificate.networking.gke.io "managed-cert" deleted
    
  2. Quita la anotación del Ingress:

    kubectl annotate ingress managed-cert-ingress networking.gke.io/managed-certificates-
    

    Observa el signo menos, -, al final del comando.

  3. Libera la dirección IP estática que reservaste para tu balanceador de cargas.

    Puedes usar Google Cloud CLI, la consola de Google Cloud o Config Connector para liberar una dirección IP reservada.

    gcloud

    Usa el siguiente comando para liberar la dirección IP reservada:

    gcloud compute addresses delete ADDRESS_NAME --global
    

    Reemplaza ADDRESS_NAME por el nombre de la dirección IP.

    Console

    Para liberar la dirección IP reservada, sigue estos pasos:

    1. Ve a la página Direcciones IP externas en la consola de Google Cloud .

      Ir a Direcciones IP externas

    2. Selecciona la casilla de verificación junto a la dirección IP que deseas liberar.

    3. Haz clic en Liberar dirección IP.

    Config Connector

    Nota: En este paso, se necesita Config Connector. Sigue las instrucciones de instalación para instalar Config Connector en el clúster.

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: example-ip-address
    spec:
      location: global

    Para implementar este manifiesto, descárgalo en tu máquina como compute-address.yaml y ejecuta lo siguiente:

    kubectl delete -f compute-address.yaml
    

Crea certificados y claves

Para usar certificados compartidos previamente o secretos de Kubernetes, primero necesitas uno o más certificados con las claves privadas correspondientes. Cada certificado debe tener un nombre común (CN) que sea igual a un nombre de dominio que poseas. Si ya tienes dos archivos de certificado con los valores adecuados para el nombre común, puedes pasar a la siguiente sección.

  1. Crea tu primera clave:

    openssl genrsa -out test-ingress-1.key 2048
    
  2. Crea tu primera solicitud de firma de certificado:

    openssl req -new -key test-ingress-1.key -out test-ingress-1.csr \
        -subj "/CN=FIRST_DOMAIN"
    

    Reemplaza FIRST_DOMAIN por un nombre de dominio de tu propiedad, como example.com.

  3. Crea el primer certificado:

    openssl x509 -req -days 365 -in test-ingress-1.csr -signkey test-ingress-1.key \
        -out test-ingress-1.crt
    
  4. Crea tu segunda clave:

    openssl genrsa -out test-ingress-2.key 2048
    
  5. Crea tu segunda solicitud de firma de certificado:

    openssl req -new -key test-ingress-2.key -out test-ingress-2.csr \
        -subj "/CN=SECOND_DOMAIN"
    

    Reemplaza SECOND_DOMAIN por otro nombre de dominio de tu propiedad, como examplepetstore.com.

  6. Crea el segundo certificado:

    openssl x509 -req -days 365 -in test-ingress-2.csr -signkey test-ingress-2.key \
        -out test-ingress-2.crt
    

Para obtener más información sobre los certificados y las claves, consulta la Descripción general de certificados SSL.

Ahora tienes dos archivos de certificado y dos archivos de claves.

En las tareas restantes, se usan los siguientes marcadores de posición para hacer referencia a tus dominios, certificados y claves:

  • FIRST_CERT_FILE es la ruta de acceso a tu primer archivo de certificado.
  • FIRST_KEY_FILE es la ruta al archivo de claves que acompaña a tu primer certificado.
  • FIRST_DOMAIN es un nombre de dominio de tu propiedad.
  • FIRST_SECRET_NAME: El nombre del Secret que contiene tu primer certificado y clave.
  • SECOND_CERT_FILE es la ruta a tu segundo archivo de certificado.
  • SECOND_KEY_FILE es la ruta al archivo de claves que acompaña a tu segundo certificado.
  • SECOND_DOMAIN es un segundo nombre de dominio de tu propiedad.
  • SECOND_SECRET_NAME: El nombre del Secret que contiene tu segundo certificado y clave.

Usa certificados ya compartidos

Puedes usar certificados SSL autoadministrados que subas a tu proyecto de Google Cloud . Estos se denominan certificados ya compartidos. Puedes especificar uno o más certificados ya compartidos para un Ingress.

Para usar varios certificados ya compartidos, sigue estos pasos:

  1. Para cada par de certificado y clave, crea un recurso de certificado SSL visible públicamente en Google Cloud.

     gcloud compute ssl-certificates create FIRST_CERT_NAME \
         --certificate=FIRST_CERT_FILE \
         --private-key=FIRST_KEY_FILE
     ```
    
    ```sh
     gcloud compute ssl-certificates create SECOND_CERT_NAME \
         --certificate=SECOND_CERT_FILE \
         --private-key=SECOND_KEY_FILE
     ```
    
    Replace the following:
    
    • FIRST_CERT_NAME y SECOND_CERT_NAME: Son los nombres de tu primer y segundo certificado.
    • FIRST_CERT_FILE, SECOND_CERT_FILE: Son el primer y el segundo archivo de certificado.
    • FIRST_KEY_FILE: SECOND_KEY_FILE son tu primer y segundo archivo de claves.
  2. En tu manifiesto de Ingress, agrega la anotación ingress.gcp.kubernetes.io/pre-shared-cert. El valor de la anotación es una lista separada por comas de los nombres de tus certificados. Además, en la sección spec.rules, incluye los campos host para especificar los dominios de tus servicios.

     apiVersion: networking.k8s.io/v1
     kind: Ingress
     metadata:
       name: my-psc-ingress
       annotations:
         ingress.gcp.kubernetes.io/pre-shared-cert: "FIRST_CERT_NAME,SECOND_CERT_NAME"
     spec:
       rules:
       - host: FIRST_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60001
       - host: SECOND_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60002
     ```
    
    Replace <code><var>FIRST_DOMAIN</var></code> and
    <code><var>SECOND_DOMAIN</var></code> with your domain names.
    
    This manifest describes an Ingress that lists pre-shared certificate
    resources in an annotation.
    

Usa Secrets de Kubernetes

Para proporcionar un balanceador de cargas de HTTP(S) con certificados y claves que creaste, crea uno o más objetos Secret de Kubernetes. Cada Secret contiene un certificado y una clave. Debes agregar los Secrets al campo tls del manifiesto de Ingress. El balanceador de cargas usa la indicación de nombre del servidor (SNI) para determinar qué certificado presentar al cliente, según el nombre de dominio en el protocolo de enlace TLS.

Para usar varios certificados, sigue estos pasos:

  1. Crea un Secret para cada par de certificados y claves:

     kubectl create secret tls FIRST_SECRET_NAME \
         --cert=FIRST_CERT_FILE \
         --key=FIRST_KEY_FILE
     ```
    
    ```sh
     kubectl create secret tls SECOND_SECRET_NAME \
         --cert=SECOND_CERT_FILE \
         --key=SECOND_KEY_FILE
     ```
    
  2. En el manifiesto de Ingress, en la sección spec.tls, enumera los Secrets que creaste. Además, en la sección spec.rules, incluye los campos host para especificar los dominios de tus servicios.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-mc-ingress
    spec:
      tls:
      - secretName: FIRST_SECRET_NAME
      - secretName: SECOND_SECRET_NAME
      rules:
      - host: FIRST_DOMAIN
        http:
          paths:
          - pathType: ImplementationSpecific
            backend:
              service:
                name: my-mc-service
                port:
                  number: 60001
      - host: SECOND_DOMAIN
        http:
          paths:
          - pathType: ImplementationSpecific
            backend:
              service:
                name: my-mc-service
                port:
                  number: 60002
    

    Reemplaza FIRST_DOMAIN y SECOND_DOMAIN por nombres de dominio de tu propiedad, como example.com y examplepetstore.com.

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.

Para proteger el Ingress encriptado con HTTPS en tus clústeres de GKE, consulta el ejemplo Ingress seguro.

Inhabilita HTTP

Si deseas que todo el tráfico entre el cliente y el balanceador de cargas 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: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress-2
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: SECRET_NAME
  ...

Este manifiesto incluye el SECRET_NAME que es el nombre del Secret que creaste.

HTTP/2 entre el cliente y el balanceador de cargas

Los clientes pueden usar HTTP/2 para enviar solicitudes al balanceador de cargas. No se requiere configuración.

Protege y optimiza el tráfico entre el balanceador de cargas y la aplicación

Puedes configurar el protocolo que se usa para la comunicación entre el balanceador de cargas y los Pods de tu aplicación para garantizar la seguridad de extremo a extremo o para optimizar el rendimiento del tráfico interno. Si bien el balanceador de cargas usa de forma predeterminada HTTP/1.1 sin encriptar para las conexiones de backend, puedes habilitar HTTPS o HTTP/2 para satisfacer los requisitos específicos de tu aplicación.

HTTPS entre el balanceador de cargas y la aplicación

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 que use HTTPS cuando reenvíe solicitudes a tu aplicación. Para obtener más información, consulta HTTPS (TLS) entre el balanceador de cargas y la 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 del Service. Este manifiesto de Service debe incluir type: NodePort, a menos que uses el balanceo de cargas nativo del contenedor. Si usas el balanceo de cargas nativo del contenedor, usa type: ClusterIP.

El siguiente manifiesto del Service especifica 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.

El manifiesto del Service debe incluir un valor name en la anotación del puerto. Solo puedes editar el puerto del Service si haces referencia a su name asignado, no a su valor targetPort.

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

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

Si tu aplicación, que se ejecuta en un pod de GKE, puede recibir solicitudes HTTP/2, puedes configurar el balanceador de cargas para que use HTTP/2 cuando reenvíe las solicitudes a tu aplicación.

Para habilitar HTTP/2, debes usar la anotación cloud.google.com/app-protocols en el manifiesto del Service de Kubernetes. Esta anotación especifica el protocolo que usa el balanceador de cargas para comunicarse con tu aplicación. Para garantizar que el balanceador de cargas realice una solicitud HTTP/2 correcta a tu backend, este debe estar configurado con SSL.

A continuación, se muestra un ejemplo de un manifiesto de Service configurado para HTTP/2:

apiVersion: v1
kind: Service
metadata:
  name: my-http2-service
  annotations:
    cloud.google.com/app-protocols: '{"my-port":"HTTP2"}'
spec:
  type: NodePort
  selector:
    app: my-app
  ports:
  - name: my-port
    protocol: TCP
    port: 443
    targetPort: 8443

Ten en cuenta lo siguiente:

  • La anotación cloud.google.com/app-protocols se establece en '{"my-port":"HTTP2"}', lo que indica al balanceador de cargas que use HTTP/2 para el tráfico enviado al puerto llamado my-port.
  • El puerto se establece en 443 y dirige el tráfico a los Pods en targetPort 8443.