Traffico sicuro per GKE Ingress

Questa pagina mostra come proteggere e ottimizzare il traffico per Google Kubernetes Engine (GKE) Ingress. Puoi configurare i certificati SSL tra il client e il bilanciatore del carico e proteggere il traffico tra il bilanciatore del carico e l'applicazione di backend. Prima di continuare, assicurati di conoscere il modo in cui GKE protegge Ingress con HTTPS.

Questa pagina è dedicata agli specialisti di networking che progettano e realizzano l'architettura di rete per la loro organizzazione e installano, configurano e supportano le apparecchiature di rete. Per scoprire di più sui ruoli comuni e sulle attività di esempio a cui facciamo riferimento nei contenuti diGoogle Cloud , consulta Ruoli e attività comuni degli utenti GKE.

Proteggere e ottimizzare il traffico tra il client e il bilanciatore del carico

Per accettare le richieste HTTPS dai tuoi clienti, il bilanciatore del carico deve disporre di un certificato per dimostrare la sua identità ai tuoi clienti. Il bilanciatore del carico deve anche avere una chiave privata per completare l'handshake HTTPS. Per saperne di più su come fornire certificati SSL a un bilanciatore del carico HTTP(S), consulta Configurazione di TLS tra il client e il bilanciatore del carico.

Utilizzare i certificati gestiti da Google

Per configurare uno o più certificati SSL gestiti da Google e associarli a un Ingress, devi:

  • Crea uno o più oggetti ManagedCertificate nello stesso spazio dei nomi di Ingress. Puoi specificare fino a 15 certificati per il bilanciatore del carico
  • Associa gli oggetti ManagedCertificate a un Ingress aggiungendo l'annotazione networking.gke.io/managed-certificates all'Ingress. Questa annotazione è un elenco separato da virgole di oggetti ManagedCertificate.

Limitazioni

Questa sezione descrive le limitazioni dei certificati gestiti da Google. Se richiedi certificati autogestiti o se possiedi già certificati SSL che vuoi configurare sul tuo Ingress, consulta Configurazione di HTTPS (TLS) tra client e bilanciatore del carico.

  • I certificati gestiti da Google sono meno flessibili di quelli che ottieni e gestisci autonomamente. I certificati gestiti da Google supportano fino a 100 domini non con caratteri jolly. A differenza dei certificati autogestiti, i certificati gestiti da Google non supportano i domini con caratteri jolly.

  • Il numero e il tipo di certificati supportati da un ingresso sono definiti dai limiti dei certificati SSL gestiti da Google.

  • Gli aggiornamenti dei certificati gestiti da Google non sono supportati. Per saperne di più, consulta Aggiornamento manuale di un certificato gestito da Google.

  • Se il certificato viene revocato direttamente dall'autorità di certificazione, Google non lo ruota automaticamente. Devi eliminare ManagedCertificate e crearne uno nuovo.

  • GKE Ingress non supporta i certificati gestiti da Gestore certificati. Per utilizzare i certificati gestiti da Certificate Manager, utilizza l'API Gateway.

Prerequisiti

  • Devi essere il proprietario del nome di dominio. Il nome di dominio non deve contenere più di 63 caratteri. Puoi utilizzare qualsiasi registrar di nomi di dominio per ottenere un nome di dominio.

  • Se utilizzi un cluster GKE Standard, deve essere abilitato il componente aggiuntivo HttpLoadBalancing.

  • Il manifest Ingress deve includere l'annotazione kubernetes.io/ingress.class: "gce". Il campo ingressClassName non è supportato.

  • Devi applicare le risorse Ingress e ManagedCertificate nello stesso progetto e nello stesso spazio dei nomi.

  • Crea un indirizzo IP esterno statico riservato. La prenotazione di un indirizzo IP statico garantisce che rimanga tuo, anche se elimini l'ingresso. Se non riservi un indirizzo IP, questo potrebbe cambiare, il che ti costringerà a riconfigurare i record DNS del dominio. Utilizza Google Cloud CLI o la console Google Cloud per creare un indirizzo IP riservato.

    gcloud

    Per creare un indirizzo IP riservato, esegui questo comando:

    gcloud compute addresses create ADDRESS_NAME --global
    

    Sostituisci ADDRESS_NAME con il nome dell'indirizzo IP prenotato che stai creando.

    Per trovare l'indirizzo IP statico che hai creato, esegui questo comando:

    gcloud compute addresses describe ADDRESS_NAME --global
    

    L'output è simile al seguente:

    address: 203.0.113.32
    ...
    

    Console

    Per creare un indirizzo IP riservato:

    1. Vai alla pagina Indirizzi IP esterni nella console Google Cloud .

      Vai a Indirizzi IP esterni

    2. Specifica un nome per l'indirizzo IP (ad esempio, example-ip-address).

    3. Specifica se vuoi un indirizzo IPv4 o IPv6.

    4. Seleziona l'opzione Globale per Tipo.

    5. Fai clic su Prenota. L'indirizzo IP è elencato nella colonna Indirizzo esterno.

    Config Connector

    Nota:questo passaggio richiede Config Connector. Segui le istruzioni di installazione per installare Config Connector sul cluster.

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: example-ip-address
    spec:
      location: global
    Per eseguire il deployment di questo manifest, scaricalo sul tuo computer come compute-address.yaml ed esegui:

    kubectl apply -f compute-address.yaml
    

Configurazione di un certificato gestito da Google

  1. Crea un oggetto ManagedCertificate. Questa risorsa specifica i domini per il certificato SSL. I domini con caratteri jolly non sono supportati.

    Il seguente manifest descrive un oggetto ManagedCertificate. Salva il manifest come 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
    

    Sostituisci quanto segue:

    • FIRST_CERT_NAME: il nome del primo oggetto ManagedCertificate.
    • FIRST_DOMAIN: il primo dominio di tua proprietà.
    • SECOND_CERT_NAME: il nome del secondo oggetto ManagedCertificate.
    • SECOND_DOMAIN: il secondo dominio di tua proprietà.

    I nomi degli oggetti ManagedCertificate sono diversi dai nomi dei certificati effettivi che creano. Per utilizzarli in Ingress, devi solo conoscere i nomi degli oggetti ManagedCertificate.

  2. Applica il manifest al cluster:

    kubectl apply -f managed-cert.yaml
    
  3. Segui le istruzioni per creare un deployment e un servizio per esporre la tua applicazione a internet.

  4. Affinché questo oggetto ManagedCertificate diventi Active, collegalo a Ingress utilizzando l'annotazione networking.gke.io/managed-certificates, come nel seguente esempio. ManagedCertificate non deve essere già Active per poterlo collegare 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. Attendi il completamento del provisioning dei certificati gestiti da Google. L'operazione potrebbe richiedere fino a 60 minuti. Puoi controllare lo stato dei certificati utilizzando il seguente comando:

    kubectl describe managedcertificate managed-cert
    

    L'output è simile al seguente:

    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
    (...)
    

    Il valore del campo Status.CertificateStatus indica che il certificato è stato sottoposto a provisioning. Se Status.CertificateStatus non è Active, il certificato non è ancora stato sottoposto a provisioning.

  6. Verifica che SSL funzioni visitando i tuoi domini utilizzando il prefisso https://. Il browser indica che la connessione è sicura e puoi visualizzare i dettagli del certificato.

Migrazione ai certificati gestiti da Google dai certificati autogestiti

Quando esegui la migrazione di un Ingress dall'utilizzo di certificati SSL autogestiti a certificati SSL gestiti da Google, non eliminare i certificati SSL autogestiti prima che i certificati SSL gestiti da Google siano attivi. Una volta eseguito correttamente il provisioning dei certificati SSL gestiti da Google, questi vengono attivati automaticamente. Quando i certificati SSL gestiti da Google sono attivi, puoi eliminare i tuoi certificati SSL autogestiti.

Segui queste istruzioni per eseguire la migrazione dai certificati SSL autogestiti a quelli gestiti da Google.

  1. Aggiungi un nuovo certificato gestito da Google all'ingresso, come descritto nella sezione precedente.
  2. Attendi finché lo stato della risorsa certificato gestito da Google non è Active. Controlla lo stato del certificato con il seguente comando:

    kubectl describe managedcertificate managed-cert
    
  3. Quando lo stato è Active, aggiorna l'ingresso per rimuovere i riferimenti al certificato autogestito.

Rimozione di un certificato gestito da Google

Per rimuovere un certificato gestito da Google dal cluster, devi eliminare l'oggetto ManagedCertificate e rimuovere l'annotazione Ingress che lo fa riferimento.

  1. Elimina l'oggetto ManagedCertificate:

    kubectl delete -f managed-cert.yaml
    

    L'output è simile al seguente:

    managedcertificate.networking.gke.io "managed-cert" deleted
    
  2. Rimuovi l'annotazione da Ingress:

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

    Nota il segno meno, -, alla fine del comando.

  3. Rilascia l'indirizzo IP statico che hai prenotato per il bilanciatore del carico.

    Puoi utilizzare Google Cloud CLI, la console Google Cloud o Config Connector per rilasciare un indirizzo IP riservato.

    gcloud

    Utilizza il seguente comando per rilasciare l'indirizzo IP prenotato:

    gcloud compute addresses delete ADDRESS_NAME --global
    

    Sostituisci ADDRESS_NAME con il nome dell'indirizzo IP.

    Console

    Per rilasciare l'indirizzo IP prenotato, segui questi passaggi:

    1. Vai alla pagina Indirizzi IP esterni nella console Google Cloud .

      Vai a Indirizzi IP esterni

    2. Seleziona la casella di controllo accanto all'indirizzo IP che vuoi rilasciare.

    3. Fai clic su Rilascia indirizzo IP.

    Config Connector

    Nota:questo passaggio richiede Config Connector. Segui le istruzioni di installazione per installare Config Connector sul cluster.

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

    Per eseguire il deployment di questo manifest, scaricalo sul tuo computer come compute-address.yaml ed esegui:

    kubectl delete -f compute-address.yaml
    

Crea certificati e chiavi

Per utilizzare certificati precondivisi o secret Kubernetes, devi prima disporre di uno o più certificati con le relative chiavi private. Ogni certificato deve avere un nome comune (CN) uguale a un nome di dominio di tua proprietà. Se hai già due file di certificato con i valori appropriati per il nome comune, puoi passare alla sezione successiva.

  1. Crea la tua prima chiave:

    openssl genrsa -out test-ingress-1.key 2048
    
  2. Crea la tua prima richiesta di firma del certificato:

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

    Sostituisci FIRST_DOMAIN con un nome di dominio di tua proprietà, ad esempio example.com.

  3. Crea il tuo primo certificato:

    openssl x509 -req -days 365 -in test-ingress-1.csr -signkey test-ingress-1.key \
        -out test-ingress-1.crt
    
  4. Crea la seconda chiave:

    openssl genrsa -out test-ingress-2.key 2048
    
  5. Crea la seconda richiesta di firma del certificato:

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

    Sostituisci SECOND_DOMAIN con un altro nome di dominio di tua proprietà, ad esempio examplepetstore.com.

  6. Crea il secondo certificato:

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

Per saperne di più su certificati e chiavi, consulta la panoramica dei certificati SSL.

Ora hai due file di certificato e due file di chiave.

Le attività rimanenti utilizzano i seguenti segnaposto per fare riferimento ai tuoi domini, certificati e chiavi:

  • FIRST_CERT_FILE: il percorso del primo file del certificato.
  • FIRST_KEY_FILE: il percorso del file della chiave associato al primo certificato.
  • FIRST_DOMAIN: un nome di dominio di tua proprietà.
  • FIRST_SECRET_NAME: il nome del secret contenente il primo certificato e la prima chiave.
  • SECOND_CERT_FILE: il percorso del secondo file del certificato.
  • SECOND_KEY_FILE: il percorso del file della chiave associato al secondo certificato.
  • SECOND_DOMAIN: un secondo nome di dominio di tua proprietà.
  • SECOND_SECRET_NAME: il nome del secret contenente il secondo certificato e la seconda chiave.

Utilizzare certificati precondivisi

Puoi utilizzare certificati SSL autogestiti che carichi nel tuo progetto Google Cloud . Questi sono chiamati certificati precondivisi. Puoi specificare uno o più certificati precondivisi per un Ingress.

Per utilizzare più certificati precondivisi:

  1. Per ogni coppia di certificato e chiave, crea una risorsa del certificato SSL visibile pubblicamente in 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, SECOND_CERT_NAME: i nomi del primo e del secondo certificato.
    • FIRST_CERT_FILE, SECOND_CERT_FILE: il primo e il secondo file di certificato.
    • FIRST_KEY_FILE:, SECOND_KEY_FILE i tuoi file della prima e della seconda chiave.
  2. Nel manifest di Ingress, aggiungi l'annotazione ingress.gcp.kubernetes.io/pre-shared-cert. Il valore dell'annotazione è un elenco separato da virgole dei nomi dei certificati. Inoltre, nella sezione spec.rules, includi i campi host per specificare i domini per i tuoi servizi.

     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.
    

Utilizzare i secret Kubernetes

Per fornire a un bilanciatore del carico HTTP(S) certificati e chiavi che hai creato personalmente, crea uno o più oggetti Kubernetes Secret. Ogni secret contiene un certificato e una chiave. Aggiungi i secret al campo tls del manifest Ingress. Il bilanciatore del carico utilizza l'indicazione del nome del server (SNI) per determinare quale certificato presentare al client, in base al nome di dominio nell'handshake TLS.

Per utilizzare più certificati:

  1. Crea un Secret per ogni coppia di certificato e chiave:

     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. Nel manifest Ingress, nella sezione spec.tls, elenca i secret che hai creato. Inoltre, nella sezione spec.rules, includi i campi host per specificare i domini per i tuoi servizi.

    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
    

    Sostituisci FIRST_DOMAIN e SECOND_DOMAIN con i nomi di dominio di tua proprietà, ad esempio example.com e examplepetstore.com.

Le modifiche ai secret vengono rilevate periodicamente, quindi se modifichi i dati all'interno del secret, l'applicazione delle modifiche al bilanciatore del carico richiederà un massimo di 10 minuti.

Per proteggere Ingress criptato HTTPS per i cluster GKE, consulta l'esempio Ingress sicuro.

Disattivazione di HTTP

Se vuoi che tutto il traffico tra il client e il bilanciatore del carico utilizzi HTTPS, puoi disattivare HTTP includendo l'annotazione kubernetes.io/ingress.allow-http nel manifest Ingress. Imposta il valore dell'annotazione su "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
  ...

Questo manifest include SECRET_NAME, ovvero il nome del secret che hai creato.

HTTP/2 tra il client e il bilanciatore del carico

I client possono utilizzare HTTP/2 per inviare richieste al bilanciatore del carico. Non è richiesta alcuna configurazione.

Proteggere e ottimizzare il traffico tra il bilanciatore del carico e l'applicazione

Puoi configurare il protocollo utilizzato per la comunicazione tra il bilanciatore del carico e i pod della tua applicazione per garantire la sicurezza end-to-end o per ottimizzare il rendimento del traffico interno. Anche se il bilanciatore del carico utilizza per impostazione predefinita HTTP/1.1 non criptato per le connessioni di backend, puoi attivare HTTPS o HTTP/2 per soddisfare i requisiti specifici della tua applicazione.

HTTPS tra il bilanciatore del carico e l'applicazione

Se la tua applicazione, in esecuzione in un pod GKE, è in grado di ricevere richieste HTTPS, puoi configurare il bilanciatore del carico in modo che utilizzi HTTPS quando inoltra le richieste alla tua applicazione. Per saperne di più, consulta HTTPS (TLS) tra il bilanciatore del carico e la tua applicazione.

Per configurare il protocollo utilizzato tra il bilanciatore del carico e l'applicazione, utilizza l'annotazione cloud.google.com/app-protocols nel manifest del servizio. Questo manifest del servizio deve includere type: NodePort, a meno che tu non stia utilizzando il bilanciamento del carico nativo del container. Se utilizzi il bilanciamento del carico nativo del container, utilizza type: ClusterIP.

Il seguente manifest del servizio specifica due porte. L'annotazione indica che quando un bilanciatore del carico HTTP(S) ha come target la porta 80 del servizio, deve utilizzare HTTP. Quando il bilanciatore del carico ha come target la porta 443 del servizio, deve utilizzare HTTPS.

Il file manifest del servizio deve includere un valore name nell'annotazione della porta. Puoi modificare la porta del servizio solo facendo riferimento al relativo name assegnato, non al valore 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

Utilizzare HTTP/2 tra il bilanciatore del carico e l'applicazione

Se la tua applicazione, in esecuzione in un pod GKE, è in grado di ricevere richieste HTTP/2, puoi configurare il bilanciatore del carico in modo che utilizzi HTTP/2 quando inoltra le richieste alla tua applicazione.

Per abilitare HTTP/2, devi utilizzare l'annotazione cloud.google.com/app-protocols nel manifest del servizio Kubernetes. Questa annotazione specifica il protocollo utilizzato dal bilanciatore del carico per comunicare con la tua applicazione. Per assicurarti che il bilanciatore del carico effettui una richiesta HTTP/2 corretta al backend, quest'ultimo deve essere configurato con SSL.

Di seguito è riportato un esempio di manifest di servizio configurato per 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

Tieni presente quanto segue:

  • L'annotazione cloud.google.com/app-protocols è impostata su '{"my-port":"HTTP2"}', che indica al bilanciatore del carico di utilizzare HTTP/2 per il traffico inviato alla porta denominata my-port.
  • La porta è impostata su 443 e indirizza il traffico ai pod su targetPort 8443.