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 registri delle immagini privati utilizzando la chiave pubblica dell'autorità di certificazione (CA) che ha emesso il certificato per il registro.

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 sulle attività di esempio a cui facciamo riferimento nei contenuti, consulta Ruoli e attività comuni degli utenti GKE. Trusted Cloud by S3NS

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

Come funziona l'accesso ai registri privati

Memorizzi la chiave pubblica della CA utilizzata per emettere certificati per i tuoi registri privati in Secret Manager e configuri quali nomi di dominio completi (FQDN) del registro utilizzano quella chiave pubblica per la convalida dei certificati. GKE recupera automaticamente la chiave e aggiorna la configurazione del registro del runtime del container durante il bootstrapping del nodo. Quando esegui il deployment di un carico di lavoro che utilizza un'immagine container dal tuo registro privato, si verificano i seguenti passaggi:

  1. Kubelet sul nodo tenta di estrarre l'immagine dal registro privato.
  2. Il registro presenta un certificato TLS lato server.
  3. Il runtime del container convalida il certificato del registro in modo crittografico e per garantire che l'FQDN corrisponda a quello specificato.
  4. Se la convalida viene superata, GKE estrae l'immagine e pianifica il tuo workload.

Vantaggi

Questo metodo di accesso ai registri privati offre vantaggi come i seguenti:

  1. Migliora l'affidabilità della configurazione del runtime del container: l'utilizzo di metodi come DaemonSet per impostare la configurazione di containerd aggiunge il rischio che si verifichi una condizione di competizione, in cui altri DaemonSet potrebbero essere eseguiti prima del DaemonSet di configurazione.
  2. Riduzione della vulnerabilità agli attacchi di escalation dei privilegi: elimina la necessità di eseguire DaemonSet con privilegi che modificano la configurazione del runtime del container.
  3. Riduzione del sovraccarico di gestione: Secret Manager ti consente di archiviare le chiavi pubbliche CA in una posizione centrale, gestire l'accesso alle chiavi utilizzando IAM e implementare il controllo delle versioni e le annotazioni. Per saperne di più, consulta la panoramica del prodotto Secret Manager.
  4. Migliora l'auditabilità: Cloud Logging raccoglie già i log, inclusi quelli relativi all'aggiunta di certificati a un cluster e al pull delle immagini da parte dei nodi GKE.

Prezzi

In questo documento utilizzi i seguenti componenti fatturabili di Trusted Cloud:

  • GKE
  • Secret Manager
  • Logging: GKE genera audit log dell'attività di amministrazione e, se abilitati, audit log di accesso ai dati per questa funzionalità. Per informazioni sui diversi tipi di log di controllo, vedi Log di controllo 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à, installala e poi inizializza gcloud CLI. Se hai già installato gcloud CLI, scarica l'ultima versione eseguendo gcloud components update.
  • Enable the Secret Manager API.

    Enable the API

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

Requisiti

Per utilizzare le chiavi pubbliche dell'autorità di certificazione privata 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 è l'impostazione predefinita per tutti i cluster GKE, oppure immagini del nodo Ubuntu con containerd versione 1.33.0 o successive. Le immagini dei nodi Windows Server non sono supportate.
  • I tuoi node pool devono avere l'ambito di accesso cloud-platform per consentire ai nodi di scaricare i certificati. Per maggiori 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 con una versione precedente alla 1.33.0.
  • Non puoi utilizzare i certificati CA privati nei nodi Windows Server.
  • Ogni cluster supporta fino a cinque certificati CA privati per i registri privati.
  • Ogni certificato può avere fino a 25 nomi di dominio completi (FQDN).
  • Ogni dominio può essere utilizzato in un solo file di certificato. Tuttavia, i bundle di certificati sono supportati.
  • I certificati devono essere codificati in formato PEM.
  • Il server non ruota automaticamente i certificati. Per saperne di più, consulta Ruotare i certificati CA privati in questo documento.
  • I nomi di dominio completi presentano le seguenti limitazioni:
    • La lunghezza massima del nome di dominio completo è di 255 caratteri, inclusi i caratteri speciali.
    • I nomi di dominio completi possono utilizzare solo lettere, numeri e trattini (-).
    • Punycode non è supportato.
    • I caratteri jolly non sono supportati.

Eseguire la migrazione da DaemonSet di configurazione

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

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

  • L'archiviazione delle chiavi pubbliche della CA privata in Secret Manager configura solo l'accesso ai registri privati. Non è supportata un'altra configurazione correlata al registro.
  • L'attivazione di questa funzionalità fa sì che il cluster utilizzi il modello di configurazione hostpath CRI di containerd, che è incompatibile con il modello di configurazione precedente. Se hai DaemonSet che modificano la configurazione dell'host containerd, ad esempio per registri privati, mirror o proxy non sicuri, aggiorna i DaemonSet in modo che utilizzino il modello hostpath CRI.

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

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

Aggiorna 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 in modo condizionale un modello di configurazione specifico a seconda dei file di configurazione di containerd sul nodo. Per un esempio di DaemonSet che implementa questa logica condizionale, nel repository GoogleCloudPlatform/k8s-node-tools GitHub, consulta il manifesto insecure-registry-config.yaml.

Archivia le chiavi pubbliche della CA in Secret Manager

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

Configura l'accesso a Secret Manager da GKE

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

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

Questi ruoli predefiniti contengono le autorizzazioni necessarie per estrarre i secret da Secret Manager. Per vedere quali sono esattamente le autorizzazioni richieste, espandi la sezione Autorizzazioni obbligatorie:

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 assegnare queste autorizzazioni al 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 pool di nodi, che è l'approccio consigliato, il cluster utilizza il service account Compute Engine predefinito.

Se possibile, ti consigliamo di configurare i cluster e i pool di nodi con un account di servizio IAM con privilegi minimi. Per istruzioni, vedi Utilizzare service account con privilegi minimi.

Crea un file di configurazione di runtime

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

  1. Recupera il numero del tuo progetto Trusted 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 di progetto ottenuto nel passaggio precedente.
    • SECRET_VERSION: il numero di versione del segreto in Secret Manager. Puoi utilizzare facoltativamente un alias di versione, ma ti consigliamo di utilizzare il numero di versione per evitare complessità di gestione.
    • FQDN1, FQDN2: i nomi di dominio completi per i tuoi registri 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, vedi privateRegistryAccessConfig nella tabella 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 posizione di 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 registro 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 mostra come applicare una configurazione di containerd a cluster e nodi esistenti.

Controllare gli ambiti di accesso

Per utilizzare questa funzionalità, i cluster esistenti devono disporre dell'ambito di accesso cloud-platform. Questa sezione mostra come controllare gli ambiti di accesso e aggiornare un cluster esistente con un file di configurazione del registro 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.

Controllare gli ambiti di accesso standard

Per controllare gli ambiti di accesso del 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 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 di GKE che utilizza già.

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

Sostituisci VERSION con la stessa versione patch di GKE già utilizzata dal cluster.

Verifica che il cluster possa accedere al registro 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 della tua 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, segui questi passaggi. Questi passaggi richiedono di ricreare due volte i nodi esistenti. Ti consigliamo di eseguire le rotazioni dei certificati durante i tempi di inattività pianificati per ridurre al minimo l'impatto delle interruzioni del carico di lavoro.

  1. Crea un bundle di certificati con codifica PEM che contenga sia i certificati vecchi che quelli nuovi.
  2. Aggiungi il bundle come nuova versione del secret in Secret Manager.
  3. Aggiorna il campo del file di configurazione del runtime secretURI con il nuovo numero di versione del secret.
  4. Aggiorna il cluster per utilizzare la nuova versione del secret.
  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, procedi con il 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 secret.

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

Visualizzare gli audit log in Logging

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

  1. Vai alla pagina Esplora log nella console Trusted 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 è riuscita, 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 utilizzare le seguenti best practice quando utilizzi questa funzionalità:

  • Non utilizzare alias per le versioni dei secret di Secret Manager. Utilizza il numero di versione generato automaticamente per ogni versione del secret. Nel tempo, un alias potrebbe puntare a una versione diversa del certificato, il che potrebbe causare 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 nodi per applicare le configurazioni di containerd aggiornate.
  • Fornisci l'accesso ai secret a livello di secret, non a livello di progetto.

Disattiva le opzioni di configurazione di containerd

Per rimuovere la configurazione personalizzata:

  1. Aggiorna il file di configurazione per specificare enabled: false nell'elemento di configurazione che vuoi disattivare ed elimina tutti gli altri campi nell'elemento, come nel seguente esempio:

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

Risoluzione dei problemi

Per la procedura di risoluzione dei problemi, consulta Risoluzione dei problemi del runtime del container.