Accedere ai registry privati con certificati CA privati


Questa pagina mostra come consentire ai carichi di lavoro in esecuzione in Google Kubernetes Engine (GKE) di accedere ai registry di immagini privati utilizzando la chiave pubblica dell'autorità di certificazione (CA) che ha emesso il certificato per il registry.

Questa pagina è rivolta agli esperti di sicurezza che gestiscono l'accesso per i carichi di lavoro della loro organizzazione. Per scoprire di più sui ruoli comuni e sugli esempi di attività a cui facciamo riferimento nei contenuti di Google Cloud, consulta Ruoli e attività comuni degli utenti di GKE Enterprise.

Prima di leggere questa pagina, assicurati di conoscere Secret Manager.

Come funziona

Memorizzi la chiave pubblica della CA utilizzata per emettere certificati per i tuoi registry privati in Secret Manager e configuri i nomi di dominio completamente qualificati (FQDN) del registry che utilizzano questa chiave pubblica per la convalida dei certificati. GKE recupera automaticamente la chiave e aggiorna la configurazione del registry di runtime del contenitore durante l'avvio iniziale del nodo. Quando esegui il deployment di un carico di lavoro che utilizza un'immagine container dal tuo registro privato, vengono eseguiti i seguenti passaggi:

  1. Kubelet sul nodo tenta di estrarre l'immagine dal registry privato.
  2. Il registry presenta un certificato TLS lato server.
  3. Il runtime del contenitore convalida il certificato del registry in modo criptato e garantisce che il FQDN corrisponda a quello specificato.
  4. Se la convalida va a buon fine, GKE estrae l'immagine e pianifica il tuo carico di lavoro.

Vantaggi

Questo metodo di accesso ai registry privati offre i seguenti vantaggi:

  1. Migliora l'affidabilità della configurazione in fase di esecuzione del contenitore: l'utilizzo di metodi come i DaemonSet per impostare la configurazione di containerd aumenta il rischio che si verifichi una condizione di concorrenza, in cui altri DaemonSet potrebbero essere eseguiti prima del DaemonSet di configurazione.
  2. Riduci la vulnerabilità agli attacchi di escalation dei privilegi: rimuove la necessità di eseguire DaemonSet privilegiati che modificano la configurazione di runtime del contenitore.
  3. Riduci il sovraccarico di gestione: Secret Manager consente di archiviare le chiavi pubbliche CA in un'unica posizione, gestire l'accesso alle chiavi utilizzando IAM e implementare il controllo delle versioni e le annotazioni. Per ulteriori informazioni, consulta la panoramica del prodotto Secret Manager.
  4. Migliora la verifica: Cloud Logging raccoglie già i log, ad esempio quando i certificati vengono aggiunti a un cluster e quando i nodi GKE estraggono le immagini.

Prezzi

In questo documento utilizzerai i seguenti componenti fatturabili di Google Cloud:

  • GKE
  • Secret Manager
  • Logging: GKE genera audit log delle attività di amministrazione e, se abilitati, audit log di accesso ai dati per questa funzionalità. Per informazioni sui diversi tipi di log di controllo, consulta Log di controllo di GKE.

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il Calcolatore prezzi.

Prima di iniziare

Prima di iniziare, assicurati di aver eseguito le seguenti operazioni:

  • Attiva l'API Google Kubernetes Engine.
  • Attiva l'API Google Kubernetes Engine
  • Se vuoi utilizzare Google Cloud CLI per questa attività, installa e poi inizializza gcloud CLI. Se hai già installato gcloud CLI, ottieni la versione più recente eseguendo gcloud components update.
  • Enable the Secret Manager API.

    Enable the API

  • Per accedere al registry, devi già disporre di un registry privato e di certificati CA privati. Questa guida non tratta della configurazione di un registry privato o della creazione di certificati.

Requisiti

Per utilizzare le chiavi pubbliche delle CA private per accedere ai registri privati, devi soddisfare i seguenti requisiti:

  • I cluster devono utilizzare GKE 1.27.3-gke.1700 o versioni successive.
  • Devi utilizzare un'immagine del nodo Container-Optimized OS con Containerd, che è quella predefinita per tutti i cluster GKE. Le immagini del nodo Ubuntu con containerd non sono supportate. Le immagini dei nodi Windows Server non sono supportate.
  • I tuoi pool di nodi devono avere l'ambito di accesso cloud-platform per consentire ai nodi di scaricare i certificati. Per ulteriori informazioni, consulta Ambiti di accesso predefiniti in GKE. Questo documento include istruzioni per impostare l'ambito di accesso quando crei un cluster o pool di nodi.

Limitazioni

Tieni presenti le seguenti limitazioni:

  • Non puoi utilizzare certificati CA privati nelle immagini dei nodi Ubuntu.
  • Non puoi utilizzare certificati CA privati nei nodi Windows Server.
  • Ogni cluster supporta fino a cinque certificati CA privati per i registry privati.
  • Ogni certificato può avere fino a 25 nomi di dominio completi (FQDN).
  • Ogni dominio può essere utilizzato solo in un singolo file del certificato. Tuttavia, i bundle di certificati sono supportati.
  • I certificati devono essere codificati in PEM.
  • Il server non ruota automaticamente i certificati. Per ulteriori informazioni, consulta la sezione Eseguire la rotazione dei certificati CA privati in questo documento.
  • I FQDN presentano le seguenti limitazioni:
    • La lunghezza massima dell'FQDN è 255 caratteri, inclusi i caratteri speciali.
    • Gli FQDN possono contenere solo lettere, numeri e trattini (-).
    • Punycode non è supportato.
    • I caratteri jolly non sono supportati.

Esegui la migrazione dai DaemonSet di configurazione

Nei cluster GKE Standard, puoi eseguire il deployment di DaemonSet con privilegi per modificare la configurazione di runtime del contenitore. Questo metodo modifica direttamente la configurazione di containerd su ogni nodo.

Se utilizzi DaemonSet con privilegi per configurare l'accesso ai registry privati, prima di utilizzare questo documento tieni presente quanto segue:

  • La memorizzazione delle chiavi pubbliche della CA privata in Secret Manager consente di configurare solo l'accesso ai registry privati. Non sono supportate altre configurazioni relative al registry.
  • Se attivi questa funzionalità, il cluster utilizzerà il modello di configurazione del percorso host CRI di containerd, che non è compatibile con il modello di configurazione precedente. Se hai DaemonSet che modificano la configurazione dell'host containerd, ad esempio per registry, mirror o proxy privati non sicuri, aggiorna i DaemonSet in modo che utilizzino il modello hostpath CRI.

    Per i campi disponibili nel modello hostpath di CRI, consulta la sezione Configurazione del registry nel repository GitHub di containerd.

Quando attivi questa funzionalità, GKE applica il modello di configurazione del percorso host CRI ai nuovi nodi del cluster. I nodi esistenti continuano a utilizzare il modello di configurazione precedente finché non vengono ricreati durante eventi come gli upgrade.

Aggiornare i DaemonSet per supportare entrambi i modelli di configurazione

Per ridurre il rischio che i DaemonSet di configurazione non funzionino sui nodi che supportano un modello di configurazione specifico, assicurati che i DaemonSet utilizzino condizionatamente un modello di configurazione specifico in base ai file di configurazione di containerd sul nodo. Per un esempio di DaemonSet che implementa questa logica condizionale, consulta il manifesto insecure-registry-config.yaml nel repository GitHub GoogleCloudPlatform/k8s-node-tools.

Memorizza le chiavi pubbliche della CA in Secret Manager

Memorizza le chiavi pubbliche delle tue CA private che emettono i certificati del tuo registry privato come secret in Secret Manager. Per le istruzioni, consulta Creare un secret nella documentazione di Secret Manager.

Configurare l'accesso a Secret Manager da GKE

Per assicurarti che l'account di servizio IAM del cluster disponga delle autorizzazioni necessarie per estrarre i secret da Secret Manager, chiedi all'amministratore di concedere all'account di servizio IAM del cluster i seguenti ruoli IAM sul secret:

Per saperne di più sulla concessione dei ruoli, consulta Gestire l'accesso a progetti, cartelle e organizzazioni.

Questi ruoli predefiniti contengono le autorizzazioni necessarie per estrarre i secret da Secret Manager. Per visualizzare le autorizzazioni esatte richieste, espandi la sezione Autorizzazioni richieste:

Autorizzazioni obbligatorie

Per estrarre i secret da Secret Manager sono necessarie le seguenti autorizzazioni:

  • resourcemanager.projects.get
  • resourcemanager.projects.list
  • secretmanager.secrets.get
  • secretmanager.secrets.list
  • secretmanager.versions.get
  • secretmanager.versions.list
  • secretmanager.versions.access

L'amministratore potrebbe anche essere in grado di concedere queste autorizzazioni all'account di servizio IAM del cluster con ruoli personalizzati o altri ruoli predefiniti.

Se non hai associato un account di servizio IAM personalizzato al tuo cluster o al tuo pool di nodi, che è il nostro approccio consigliato, il cluster utilizza l'account di servizio predefinito di Compute Engine. Se possibile, ti consigliamo di configurare i cluster e i pool di nodi con un account di servizio IAM con privilegi minimi. Per le istruzioni, consulta Utilizzare gli account di servizio con privilegi minimi.

Creare un file di configurazione di runtime

Per attivare la possibilità di utilizzare certificati CA privati per i registry privati in GKE, crea un file YAML per modificare la configurazione di containerd.

  1. Ottieni il numero del tuo progetto Google Cloud:

    gcloud projects describe PROJECT_ID \
        --format="value(projectNumber)"
    

    L'output è il numero di progetto numerico.

  2. Salva la seguente configurazione come containerd-configuration.yaml:

    privateRegistryAccessConfig:
      certificateAuthorityDomainConfig:
      - gcpSecretManagerCertificateConfig:
          secretURI: "projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION"
        fqdns:
          - "FQDN1"
          - "FQDN2"
      enabled: true
    

    Sostituisci quanto segue:

    • PROJECT_NUMBER: il numero del progetto visualizzato nel passaggio precedente.
    • SECRET_VERSION: il numero di versione del segreto in Secret Manager. Se vuoi, puoi utilizzare un alias di versione, ma consigliamo di utilizzare il numero di versione per evitare complessità di gestione.
    • FQDN1, FQDN2: i nomi di dominio completamente qualificati per i tuoi registry privati. Puoi anche utilizzare un indirizzo IPv4 se è stato emesso un certificato per quell'indirizzo, ma non lo consigliamo.

Per una descrizione di questi campi, consulta privateRegistryAccessConfig nella tabella delle opzioni di configurazione di containerd disponibili.

Applica la configurazione di containerd ai nuovi cluster

Questa sezione mostra come applicare un file di configurazione containerd quando crei un nuovo cluster GKE.

Esegui questo comando:

gcloud container clusters create-auto CLUSTER_NAME \
    --location=LOCATION \
    --scopes="cloud-platform" \
    --containerd-config-from-file="PATH_TO_CONFIG_FILE"

Sostituisci quanto segue:

  • CLUSTER_NAME: il nome del nuovo cluster.
  • LOCATION: la località Compute Engine del nuovo cluster.
  • PATH_TO_CONFIG_FILE: il percorso del file di configurazione che hai creato, ad esempio ~/containerd-configuration.yaml.

Puoi attivare la configurazione del registry privato sui nuovi cluster standard eseguendo il comando gcloud container clusters create con le stesse opzioni.

Applica la configurazione di containerd ai cluster esistenti

Questa sezione illustra come applicare una configurazione di containerd a cluster e nodi esistenti.

Controllare gli ambiti di accesso

I cluster esistenti devono avere l'ambito di accesso cloud-platform per utilizzare questa funzionalità. Questa sezione mostra come controllare gli ambiti di accesso e aggiornare un cluster esistente con un file di configurazione del registry privato nuovo o modificato.

Per informazioni dettagliate sugli ambiti di accesso predefiniti nei nuovi cluster, consulta Ambiti di accesso in GKE.

Controllare gli ambiti di accesso di Autopilot

Esegui questo comando:

gcloud container clusters describe CLUSTER_NAME \
    --location=LOCATION \
    --flatten=nodeConfig \
    --format='csv[delimiter="\\n",no-heading](oauthScopes)'

Se il tuo cluster non ha l'ambito di accesso https://www.googleapis.com/auth/cloud-platform, crea un nuovo cluster con questo ambito di accesso.

Controlla gli ambiti di accesso standard

Per controllare gli ambiti di accesso al cluster standard, controlla un pool di nodi:

gcloud container node-pools describe NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=LOCATION \
    --flatten=nodeConfig \
    --format='csv[delimiter="\\n",no-heading](oauthScopes)'

Sostituisci NODE_POOL_NAME con il nome del pool di nodi.

Se il tuo cluster non ha l'ambito di accesso https://www.googleapis.com/auth/cloud-platform, crea un nuovo pool di nodi con l'ambito di accesso cloud-platform ed elimina il pool di nodi esistente.

Aggiorna il cluster in modo che utilizzi il file di configurazione

Esegui questo comando:

gcloud container clusters update CLUSTER_NAME \
    --location=LOCATION \
    --containerd-config-from-file="PATH_TO_CONFIG_FILE"

Ricrea i nodi nei cluster standard

Se il tuo cluster standard non utilizza gli upgrade automatici, devi ricreare manualmente i pool di nodi per applicare la nuova configurazione. Per attivare una ricreazione manuale dei nodi, esegui l'upgrade del cluster alla stessa versione GKE già in uso.

gcloud container clusters upgrade CLUSTER_NAME \
    --location=LOCATION \
    --cluster-version=VERSION

Sostituisci VERSION con la stessa versione della patch GKE già in uso nel cluster.

Verifica che il cluster possa accedere al registry privato

Esegui questo comando:

gcloud container clusters describe CLUSTER_NAME \
    --location=LOCATION \
    --flatten="nodePoolDefaults.nodeConfigDefaults.containerdConfig"

L'output è simile al seguente:

    containerdConfig:
      privateRegistryAccessConfig:
        certificateAuthorityDomainConfig:
        - fqdns:
          - 203.0.113.105
          gcpSecretManagerCertificateConfig:
            secretUri: projects/123456789012/secrets/example-secret-name/versions/1
        enabled: true

Esegui il deployment di un carico di lavoro che accede a un'immagine privata

In questa sezione esegui il deployment di un pod statico che fa riferimento a un'immagine del tuo registro privato.

  1. Salva il seguente manifest come private-registry-pod.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: private-registry-pod
    spec:
      containers:
      - name: private-image
        image: IMAGE_NAME
    

    Sostituisci IMAGE_NAME con il nome dell'immagine privata.

  2. Esegui il deployment del pod:

    kubectl create -f private-registry-pod.yaml
    

Ruotare i certificati CA privati

Secret Manager e GKE non possono ruotare automaticamente i certificati CA privati in Secret Manager. Per eseguire una rotazione dei certificati, svolgi i seguenti passaggi. Questi passaggi richiedono di rielaborare i nodi esistenti due volte. Ti consigliamo di eseguire le rotazioni dei certificati durante il tempo di riposo pianificato per ridurre al minimo l'impatto delle interruzioni del carico di lavoro.

  1. Crea un bundle di certificati con codifica PEM contenente sia i certificati vecchi che quelli nuovi.
  2. Aggiungi il bundle come nuova versione del secret in Secret Manager.
  3. Aggiorna il campo secretURI del file di configurazione di runtime con il nuovo numero di versione del segreto.
  4. Aggiorna il cluster in modo che utilizzi la nuova versione del segreto.
  5. Recupera il timestamp dell'operazione di aggiornamento:

    gcloud container operations list \
        --filter="operationType ~ UPDATE_CLUSTER AND targetLink ~ CLUSTER_NAME" \
        --sort-by=startTime \
        --limit=1 \
        --format='value(endTime)'
    

    L'output è simile al seguente:

    2024-01-31T09:27:30.864308964Z
    
  6. Cerca i nodi creati prima del termine dell'operazione di aggiornamento:

    kubectl get nodes -o json | jq ".items[] |
    select(.metadata.creationTimestamp | fromdateiso8601 < $(date -d
    CLUSTER_UPDATE_TIMESTAMP +%s)) | .metadata.name"
    

    Sostituisci CLUSTER_UPDATE_TIMESTAMP con il timestamp del passaggio precedente.

    L'output è un elenco di nomi di nodi che non sono stati ricreati con la configurazione aggiornata. Quando l'output è vuoto, vai al passaggio successivo.

  7. Crea una nuova versione del secret in Secret Manager con solo il nuovo certificato.

  8. Ripeti i passaggi precedenti per aggiornare il cluster, ottenere il timestamp dell'operazione e verificare che i nodi utilizzino la nuova versione del segreto.

  9. Elimina la vecchia versione del secret da Secret Manager.

Visualizzare gli audit log in Logistica

Questa sezione mostra come utilizzare Logging per verificare se GKE ha installato la versione del segreto sui tuoi nodi.

  1. Vai alla pagina Esplora log nella console Google Cloud:

    Vai a Esplora log

  2. Specifica la seguente query:

    resource.type="gce_instance"
    textPayload:"Installed certificate \\\"projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION\\\""
    

    Se l'installazione del certificato è andata a buon fine, l'output è simile al seguente:

    "Installed certificate "projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION""
    

    Se l'installazione del certificato non è riuscita, l'output è simile al seguente:

    "Failed to install certificate "projects/PROJECT_NUMBER/secrets/SECRET_NAME/versions/SECRET_VERSION""
    

Best practice

Ti consigliamo di seguire le best practice riportate di seguito quando utilizzi questa funzionalità:

  • Non utilizzare gli alias per le versioni dei secret di Secret Manager. Utilizza il numero di versione generato automaticamente per ogni versione del secret. Un alias potrebbe indicare una versione del certificato diversa nel tempo, il che potrebbe comportare complessità nel monitoraggio delle versioni specifiche utilizzate dai tuoi carichi di lavoro.
  • Utilizza periodi di manutenzione ed esclusioni per controllare quando GKE può ricreare i tuoi nodi per applicare le configurazioni aggiornate di containerd.
  • Fornisci l'accesso ai secret a livello di secret, non a livello di progetto.

Disattivare le opzioni di configurazione di containerd

Per rimuovere la configurazione personalizzata:

  1. Aggiorna il file di configurazione in modo da specificare enabled: false nell'elemento di configurazione che vuoi disattivare ed elimina gli altri campi dell'elemento, come nell'esempio seguente:

    privateRegistryAccessConfig:
      enabled: false
  2. Applica il file di configurazione aggiornato al tuo cluster. Per le istruzioni, consulta Applicare la configurazione di containerd ai cluster esistenti.

Risoluzione dei problemi

Per la procedura di risoluzione dei problemi, consulta Risoluzione dei problemi relativi al runtime del contenitore.