Accedi ai secret archiviati all'esterno dei cluster GKE utilizzando le librerie client


Questo tutorial mostra come archiviare i dati sensibili utilizzati dal tuo Cluster Google Kubernetes Engine (GKE) in Secret Manager e altro ancora accedere in modo sicuro ai dati dai pod utilizzando la federazione delle identità per i carichi di lavoro per GKE librerie client di Google Cloud. Questo il tutorial è destinato agli amministratori della sicurezza che vogliono spostare dati sensibili dallo spazio di archiviazione nel cluster.

L'archiviazione dei dati sensibili all'esterno dello spazio di archiviazione del cluster riduce il rischio di accesso non autorizzato ai dati in caso di attacco. Utilizzo della federazione delle identità per i carichi di lavoro per GKE di accedere ai dati consente di evitare i rischi associati alla gestione le chiavi degli account di servizio e consente di controllare l'accesso ai secret Identity and Access Management (IAM) anziché regole RBAC nel cluster. Puoi utilizzare qualsiasi provider di archivi segreti esterni, come Secret Manager o Volta di HashiCorp.

Questo tutorial utilizza un cluster GKE Autopilot. Per eseguire i passaggi utilizzando GKE Standard, devi abilita manualmente la federazione delle identità per i carichi di lavoro per GKE.

Puoi utilizzare la federazione delle identità per i carichi di lavoro per GKE per accedere a qualsiasi API Google Cloud da per i carichi di lavoro GKE senza dover usare approcci meno sicuri e i file statici di chiavi degli account di servizio. Questo tutorial utilizza Secret Manager come esempio, ma puoi usare gli stessi passaggi per accedere ad altri Google Cloud su quelle di livello inferiore. Per saperne di più, vedi Federazione delle identità dei carichi di lavoro per GKE.

Obiettivi

  • Crea un secret in Secret Manager di Google Cloud.
  • Crea un cluster GKE Autopilot, Kubernetes e account di servizio Kubernetes.
  • Crea criteri di autorizzazione IAM per concedere l'accesso a Kubernetes gli account di servizio sul secret.
  • Utilizzare le applicazioni di test per verificare l'accesso agli account di servizio.
  • Esegui un'app di esempio che accede al secret utilizzando l'API Secret Manager.

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi basata sull'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud potrebbero essere idonei per una prova gratuita.

Una volta completate le attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la pagina Pulizia.

Prima di iniziare

  1. Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. Installa Google Cloud CLI.
  3. Per initialize gcloud CLI, esegui questo comando:

    gcloud init
  4. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  5. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  6. Abilita le API Kubernetes Engine and Secret Manager.

    gcloud services enable container.googleapis.com secretmanager.googleapis.com
  7. Installa Google Cloud CLI.
  8. Per initialize gcloud CLI, esegui questo comando:

    gcloud init
  9. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  10. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  11. Abilita le API Kubernetes Engine and Secret Manager.

    gcloud services enable container.googleapis.com secretmanager.googleapis.com
  12. Concedi i ruoli al tuo Account Google. Esegui questo comando una volta per ciascuno dei seguenti ruoli IAM: roles/secretmanager.admin, roles/container.clusterAdmin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:EMAIL_ADDRESS" --role=ROLE
    • Sostituisci PROJECT_ID con l'ID progetto.
    • Sostituisci EMAIL_ADDRESS con il tuo indirizzo email.
    • Sostituisci ROLE con ogni singolo ruolo.

prepara l'ambiente

Clona il repository GitHub che contiene i file di esempio per questo tutorial:

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd ~/kubernetes-engine-samples/security/wi-secrets

Crea un secret in Secret Manager

  1. L'esempio seguente mostra i dati che utilizzerai per creare un secret:

    key=my-api-key
  2. Crea un secret per archiviare i dati di esempio:

    gcloud secrets create bq-readonly-key \
        --data-file=manifests/bq-readonly-key \
        --ttl=3600s
    

    Questo comando esegue le seguenti operazioni:

    • Crea un nuovo secret di Secret Manager con la chiave di esempio nella regione Google Cloud us-central1.
    • Imposta il secret in modo che scada un'ora dopo l'esecuzione del comando.

crea il cluster e le risorse Kubernetes

Crea un cluster GKE, gli spazi dei nomi Kubernetes e Kubernetes account di servizio. Puoi creare due spazi dei nomi, uno per l'accesso di sola lettura e uno per l'accesso in lettura/scrittura al secret. Creerai anche un account di servizio Kubernetes ciascuno spazio dei nomi da utilizzare con la federazione delle identità per i carichi di lavoro per GKE.

  1. Crea un cluster GKE Autopilot:

    gcloud container clusters create-auto secret-cluster \
        --region=us-central1
    

    Il deployment del cluster potrebbe richiedere circa cinque minuti. Autopilot nei cluster è sempre abilitata la federazione delle identità per i carichi di lavoro per GKE. Se vuoi utilizzare un al cluster GKE Standard, devi manualmente abilita la federazione delle identità per i carichi di lavoro per GKE prima di continuare.

  2. Crea uno spazio dei nomi readonly-ns e uno admin-ns:

    kubectl create namespace readonly-ns
    kubectl create namespace admin-ns
    
  3. Crea un account di servizio Kubernetes readonly-sa e un admin-sa Account di servizio Kubernetes:

    kubectl create serviceaccount readonly-sa --namespace=readonly-ns
    kubectl create serviceaccount admin-sa --namespace=admin-ns
    

Creazione criteri di autorizzazione IAM

  1. Concedi all'account di servizio readonly-sa l'accesso di sola lettura al secret:

    gcloud secrets add-iam-policy-binding bq-readonly-key \
        --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/readonly-ns/sa/readonly-sa \
        --role='roles/secretmanager.secretAccessor' \
        --condition=None
    

    Sostituisci quanto segue:

    • PROJECT_NUMBER: il valore numerico di Google Cloud del progetto.
    • PROJECT_ID: l'ID del tuo progetto Google Cloud.
  2. Concedi all'account di servizio admin-sa l'accesso in lettura e scrittura al secret:

    gcloud secrets add-iam-policy-binding bq-readonly-key \
        --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/admin-ns/sa/admin-sa \
        --role='roles/secretmanager.secretAccessor' \
        --condition=None
    gcloud secrets add-iam-policy-binding bq-readonly-key \
        --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/admin-ns/sa/admin-sa \
        --role='roles/secretmanager.secretVersionAdder' \
        --condition=None
    

Verifica l'accesso al secret

Esegui il deployment dei pod di test in ogni spazio dei nomi per verificare la sola lettura e la lettura/scrittura access.

  1. Esamina il manifest del pod di sola lettura:

    # Copyright 2022 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    apiVersion: v1
    kind: Pod
    metadata:
      name: readonly-test
      namespace: readonly-ns
    spec:
      containers:
      - image: google/cloud-sdk:slim
        name: workload-identity-test
        command: ["sleep","infinity"]
        resources:
          requests:
            cpu: "150m"
            memory: "150Mi"
      serviceAccountName: readonly-sa

    Questo pod utilizza l'account di servizio readonly-sa in readonly-ns nello spazio dei nomi.

  2. Esamina il manifest del pod di lettura/scrittura:

    # Copyright 2022 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    apiVersion: v1
    kind: Pod
    metadata:
      name: admin-test
      namespace: admin-ns
    spec:
      containers:
      - image: google/cloud-sdk:slim
        name: workload-identity-test
        command: ["sleep","infinity"]
        resources:
          requests:
            cpu: "150m"
            memory: "150Mi"
      serviceAccountName: admin-sa

    Questo pod utilizza l'account di servizio admin-sa in admin-ns nello spazio dei nomi.

  3. Esegui il deployment dei pod di test:

    kubectl apply -f manifests/admin-pod.yaml
    kubectl apply -f manifests/readonly-pod.yaml
    

    L'esecuzione dei pod potrebbe richiedere alcuni minuti. Per monitorare l'avanzamento, esegui il seguente comando:

    watch kubectl get pods -n readonly-ns
    

    Quando lo stato del pod diventa RUNNING, premi Ctrl+C per tornare alla dalla riga di comando.

Testa l'accesso di sola lettura

  1. Apri una shell nel pod readonly-test:

    kubectl exec -it readonly-test --namespace=readonly-ns -- /bin/bash
    
  2. Prova a leggere il secret:

    gcloud secrets versions access 1 --secret=bq-readonly-key
    

    L'output è key=my-api-key.

  3. Prova a scrivere nuovi dati nel secret:

    printf "my-second-api-key" | gcloud secrets versions add bq-readonly-key --data-file=-
    

    L'output è simile al seguente:

    ERROR: (gcloud.secrets.versions.add) PERMISSION_DENIED: Permission 'secretmanager.versions.add' denied for resource 'projects/PROJECT_ID/secrets/bq-readonly-key' (or it may not exist).
    

    Il pod che utilizza l'account di servizio di sola lettura può solo leggere il secret, e non può scrivere nuovi dati.

  4. Esci dal pod:

    exit
    

Testa l'accesso in lettura/scrittura

  1. Apri una shell nel pod admin-test:

    kubectl exec -it admin-test --namespace=admin-ns -- /bin/bash
    
  2. Prova a leggere il secret:

    gcloud secrets versions access 1 --secret=bq-readonly-key
    

    L'output è key=my-api-key.

  3. Prova a scrivere nuovi dati nel secret:

    printf "my-second-api-key" | gcloud secrets versions add bq-readonly-key --data-file=-
    

    L'output è simile al seguente:

    Created version [2] of the secret [bq-readonly-key].
    
  4. Leggi la nuova versione del secret:

    gcloud secrets versions access 2 --secret=bq-readonly-key
    

    L'output è my-second-api-key.

  5. Esci dal pod:

    exit
    

I pod ricevono solo il livello di accesso che hai concesso a Kubernetes l'account di servizio usato nel manifest del pod. Tutti i pod che utilizzano l'admin-sa L'account Kubernetes nello spazio dei nomi admin-ns può scrivere nuove versioni ma tutti i pod nello spazio dei nomi readonly-ns che utilizzano readonly-sa L'account di servizio Kubernetes può solo leggere il secret.

Accedi ai secret dal tuo codice

In questa sezione:

  1. Esegui il deployment di un'applicazione di esempio che legge il tuo secret in tramite Secret Manager utilizzando le librerie client.

  2. Verifica che l'applicazione possa accedere al tuo secret.

Accedi ai secret di Secret Manager dalla tua applicazione ove possibile, utilizzando l'API Secret Manager.

  1. Esamina il codice sorgente dell'applicazione di esempio:

    // Copyright 2022 Google LLC
    //
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    //     http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    
    package main
    
    import (
    	"context"
    	"fmt"
    	"log"
    	"os"
    
    	secretmanager "cloud.google.com/go/secretmanager/apiv1"
    	secretmanagerpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1"
    )
    
    func main() {
    
            // Get environment variables from Pod spec.
            projectID := os.Getenv("PROJECT_ID")
            secretId := os.Getenv("SECRET_ID")
            secretVersion := os.Getenv("SECRET_VERSION")
    
            // Create the Secret Manager client.
            ctx := context.Background()
            client, err := secretmanager.NewClient(ctx)
            if err != nil {
                    log.Fatalf("failed to setup client: %v", err)
            }
            defer client.Close()
    
            // Create the request to access the secret.
            accessSecretReq := &secretmanagerpb.AccessSecretVersionRequest{
                    Name: fmt.Sprintf("projects/%s/secrets/%s/versions/%s", projectID, secretId, secretVersion),
            }
    
            secret, err := client.AccessSecretVersion(ctx, accessSecretReq)
            if err != nil {
                    log.Fatalf("failed to access secret: %v", err)
            }
    
            // Print the secret payload.
            //
            // WARNING: Do not print the secret in a production environment - this
            // snippet is showing how to access the secret material.
            log.Printf("Welcome to the key store, here's your key:\nKey: %s", secret.Payload.Data)
    }
    

    Questa applicazione chiama l'API Secret Manager per provare a leggere il secret.

  2. Esamina il manifest del pod dell'applicazione di esempio:

    # Copyright 2022 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    apiVersion: v1
    kind: Pod
    metadata:
      name: readonly-secret-test
      namespace: readonly-ns
    spec:
      containers:
      - image: us-docker.pkg.dev/google-samples/containers/gke/wi-secret-store:latest
        name: secret-app
        env:
          - name: PROJECT_ID
            value: "YOUR_PROJECT_ID"
          - name: SECRET_ID
            value: "bq-readonly-key"
          - name: SECRET_VERSION
            value: "latest"
        resources:
          requests:
            cpu: "125m"
            memory: "64Mi"
      serviceAccountName: readonly-sa

    Questo file manifest esegue le seguenti operazioni:

    • Crea un pod nello spazio dei nomi readonly-ns che utilizza readonly-sa l'account di servizio.
    • Esegue il pull di un'applicazione di esempio da un registro di immagini Google. Questo chiama l'API Secret Manager utilizzando librerie client di Google Cloud. Puoi visualizzare il codice dell'applicazione in /main.go nel repository.
    • Imposta le variabili di ambiente per l'applicazione di esempio da utilizzare.
  3. Sostituisci le variabili di ambiente nell'applicazione di esempio:

    sed -i "s/YOUR_PROJECT_ID/PROJECT_ID/g" "manifests/secret-app.yaml"
    
  4. Distribuisci l'applicazione di esempio:

    kubectl apply -f manifests/secret-app.yaml
    

    Il pod potrebbe richiedere alcuni minuti per iniziare a funzionare. Se il pod ha bisogno di un nuovo nodo nel tuo cluster, potresti notare eventi di tipo CrashLoopBackOff mentre GKE esegue il provisioning del nodo. Gli arresti anomali si interrompono quando il nodo con esito positivo.

  5. Verifica l'accesso al secret:

    kubectl logs readonly-secret-test -n readonly-ns
    

    L'output è my-second-api-key. Se l'output è vuoto, il pod potrebbe non in esecuzione. Attendi qualche minuto e riprova.

Approcci alternativi

Se devi montare i dati sensibili ai pod, utilizza Secret Manager per GKE (anteprima). Questo componente aggiuntivo esegue il deployment e gestisce Secret Manager di Google Cloud per il driver CSI di Kubernetes Secret Store in GKE cluster. Per istruzioni, vedi Utilizza il componente aggiuntivo Secret Manager con GKE.

La fornitura di secret come volumi montati comporta i seguenti rischi:

  1. I volumi montati sono suscettibili di attacchi Directory Traversal.
  2. Le variabili di ambiente possono essere compromesse a causa di configurazioni errate come l'apertura di un endpoint di debug.

Quando possibile, ti consigliamo di accedere in modo programmatico ai secret tramite l'API Secret Manager. Per le istruzioni, utilizza l'applicazione di esempio questo tutorial o consulta le Librerie client di Secret Manager.

Esegui la pulizia

Per evitare che al tuo Account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

Elimina singole risorse

  1. Elimina il cluster:

    gcloud container clusters delete secret-cluster \
        --region=us-central1
    
  2. (Facoltativo) Elimina il secret in Secret Manager:

    gcloud secrets delete bq-readonly-key
    

    Se non esegui questa operazione, il secret scade automaticamente perché hai impostato il flag --ttl durante la creazione.

Elimina il progetto

    Elimina un progetto Google Cloud:

    gcloud projects delete PROJECT_ID

Passaggi successivi