Mettere al sicuro i secret è fondamentale in qualsiasi deployment Kubernetes. Tradizionalmente, in GKE la gestione dei secret avveniva iniettandoli nei pod come variabili d'ambiente o volumi. È un approccio funzionale, ma macchinoso e con qualche criticità sul fronte della sicurezza. Per fortuna, Google Cloud offre una soluzione efficace: l'add-on Secret Manager per GKE.
In questo post vedremo come usare l'add-on Secret Manager per GKE per accedere ai secret salvati in Secret Manager montandoli come volumi nei Pod GKE.
:: A maggio 2024 questa funzionalità è ancora in preview , quindi va usata con cautela.
Cos'è Secret Manager?
Secret Manager è un servizio gestito di Google Cloud Platform (GCP) pensato per archiviare e recuperare informazioni sensibili come chiavi API, password e certificati. I vantaggi sono diversi:
- Gestione centralizzata: i secret risiedono in un'unica posizione, semplificando il controllo degli accessi e l'auditing.
- Sicurezza superiore: i secret sono cifrati a riposo e in transito, riducendo al minimo il rischio di esposizione.
- Workload Identity semplificata: i workloads possono accedere ai secret in modo sicuro tramite workload identity, senza credenziali aggiuntive.
L'add-on Secret Manager
L'add-on Secret Manager per Google Kubernetes Engine (GKE) semplifica l'accesso e la gestione dei secret nei pod. Ecco i suoi vantaggi:
- Accesso immediato: non serve scrivere codice ad hoc; puoi accedere direttamente ai secret salvati in Secret Manager dai pod GKE.
- Gestione centralizzata: archivia e gestisci tutti i secret in un unico punto (Secret Manager) e concedi l'accesso a secret specifici per i tuoi pod GKE.
- Sicurezza rafforzata: sfrutta le funzionalità di Secret Manager — cifratura, controllo degli accessi, rotazione e audit log — insieme a quelle di Kubernetes, come i volume mount per i secret.
- Ampia compatibilità: funziona sia con i cluster GKE Standard sia con Autopilot, e supporta deployment su architetture AMD e ARM.
L'add-on deriva dal progetto open source Kubernetes Secrets Store CSI Driver e dal Google Secret Manager provider. Se stai già usando il Secrets Store CSI Driver open source per accedere ai secret, puoi migrare all'add-on Secret Manager. Per i dettagli, consulta Migrate from the existing Secrets Store CSI Driver.
Trattandosi ancora di una preview, l'add-on al momento non offre queste funzionalità:
Non è meglio usare External Secrets Operator?
In sintesi: se devi rispettare requisiti di compliance ed evitare di avere secret nativi di Kubernetes nel cluster, la strada giusta è Secrets Store CSI driver con il GKE Secrets Add-On, che ti permette di montare i secret di Secrets Manager direttamente come volumi nei pod. Se non hai questo vincolo, ESO può essere una buona alternativa.
Esiste un confronto interessante tra External Secrets Operator e Secrets Store CSI driver, pubblicato da un utente GitHub di nome Lucas in questo commento, che riportiamo qui di seguito
ESO sincronizza i secret da un cloud provider verso secret in k8s, così puoi continuare a usare i secret k8s se ci sei abituato.
SSCSID monta il secret esterno direttamente come volume in un pod, e avere un secret k8s nel cluster è opzionale
ESO si concentra sulla configurazione tramite CRD: ciò che crei nel secret store del provider è solo il valore del secret stesso
SSCSID richiede che l'intera configurazione/secret sia archiviata direttamente nel provider, perché sarà l'applicazione a doverla consumare. Questo può essere complicato con configurazioni più ampie che incorporano alcuni secret.
I secret di ESO si possono usare nativamente con qualsiasi risorsa in k8s — ovviamente — ma 👇
SSCSID, per funzionare davvero bene, ha bisogno di un pod webhook. Non è semplice usare i secret SSCSID per referenziarli in un ingress o in un dockerconfig per il pull delle immagini, perché il loro scopo è solo il mount su un pod. Anche per abilitare il sync dei secret k8s devi prima montare il secret su un pod.
In ESO, dato che sincronizziamo i secret con i secret nativi di k8s, in caso di problemi di connettività puoi comunque accedere al secret presente nel cluster; quando torni online, la sincronizzazione riprende
con SSCSID, se perdi connettività, i mount del csi driver smettono di funzionare se ci sono restart o simili. Ci stanno lavorando, ma non so a che punto siano: doc. Conviene chiedere a loro.
ESO sarà un singolo deployment dell'operator nel cluster
SSCSID prevede un daemonset privilegiato del provider che si occupa di effettuare i mount nei pod
Esistono altre opzioni?
Se cerchi un'alternativa sicura per recuperare i secret dai servizi di secret management direttamente in un volume e senza usare il Kubernetes Secrets Store CSI Driver, vale la pena dare un'occhiata.
Inoltre, nel 2001 Abdellfetah SGHIOUAR, Dev Advocate di Google, ha scritto un articolo interessante in cui passa in rassegna altre opzioni per archiviare i secret su GKE. Lo trovi qui.
**Primi passi con** l'add-on Secret Manager per GKE
Per iniziare dobbiamo abilitare l'add-on Secret Manager nel cluster. Lo stesso flag è disponibile anche in fase di creazione di un nuovo cluster. Ricorda di sostituire i valori CLUSTER_NAME e REGION/ZONE.
gcloud beta container clusters update <CLUSTER_NAME> \
--enable-secret-manager \
--location=<ZONE/REGION>
Verifica anche di avere la Workload Identity Federation attiva nel cluster.
Una volta abilitato l'add-on Secret Manager, dovresti vedere due nuove API disponibili con la api version secrets-store.csi.x-k8s.io/v1
$ kubectl api-resources | grep secrets-store
secretproviderclasses secrets-store.csi.x-k8s.io/v1 true SecretProviderClass
secretproviderclasspodstatuses secrets-store.csi.x-k8s.io/v1 true SecretProviderClassPodStatus
Per comunicare con Secret Manager dobbiamo concedere i permessi necessari al service account Kubernetes che useremo.
Creiamo prima il namespace k8s e il service account da usare nel cluster.
kubectl create ns secret-manager-access
kubectl create sa secret-manager-access-sa
A questo punto useremo Workload Identity Federation per assegnare i permessi corretti al nostro service account K8s. Ricorda di sostituire Project ID e Project Number nelle variabili
PROJECT_NUMBER=<ADD_YOUR_PROJECT_NUMBER>
PROJECT_ID=<ADD_YOUR_PROJECT_ID>
NAMESPACE=secret-manager-access
gcloud projects add-iam-policy-binding projects/star-sorceress \
--role=roles/secretmanager.secretAccessor \
--member=principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${NAMESPACE}/sa/secret-manager-access-sa \
--condition=None
PS: di recente è cambiato il modo in cui si configura Workload Identity Federation. Per saperne di più, dai un'occhiata a questo blog post, in cui un collega di DoiT spiega tutto nel dettaglio.
Qui sotto creiamo il nostro super secret su Google Secret Manager insieme alla prima versione:
echo "This is my awesome secret, please don't share!" > super-secret.txt
gcloud secrets create super-secret --replication-policy="automatic" --data-file="super-secret.txt"
Ora dobbiamo creare la Custom Resource SecretProviderClass, che sarà collegata al secret GCP creato in precedenza. Non dimenticare di inserire il tuo Project ID.
kubectl apply -f - <<EOF
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: super-secret
spec:
provider: gke
parameters:
secrets: |
- resourceName: "projects/<PROJECT_ID>/secrets/super-secret/versions/1"
path: "super-secret.txt"
EOF
Configurazione del volume del Pod
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: secret-manager-access
spec:
serviceAccountName: secret-manager-access-sa
containers:
- name: test-pod
image: google/cloud-sdk:slim
command: ["sleep","infinity"]
volumeMounts:
- mountPath: "/var/secrets"
name: super-secret
volumes:
- name: super-secret
csi:
driver: secrets-store-gke.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: super-secret
EOF
Verifichiamo ora che il secret sia presente:
kubectl exec -it test-pod -- cat /var/secrets/super-secret.txt
This is my awesome secret, please don't share
Vantaggi del Secret Manager CSI Driver:
- Sicurezza rafforzata: i secret non vengono mai memorizzati nei pod, riducendo la superficie di attacco.
- Gestione dei workloads semplificata: con la workload identity non c'è più bisogno di gestire credenziali nei pod.
- Maggiore configurabilità: il controllo granulare sull'accesso ai secret consente permessi a grana fine.
- Audit logging centralizzato: tutti i tentativi di accesso ai secret vengono registrati in Secret Manager, semplificando l'auditing.
Conclusione
Adottare l'add-on Secret Manager per GKE significa poter contare su un Secret Manager CSI Driver completamente gestito, che migliora in modo sensibile la postura di sicurezza di GKE e semplifica la gestione dei secret all'interno delle applicazioni. Grazie a controllo centralizzato, mount automatico e regole di accesso solide, il CSI Driver ti permette di concentrarti sullo sviluppo e sul deployment delle tue applicazioni con la massima serenità.
Riferimenti:
https://github.com/kubernetes-sigs/secrets-store-csi-driver
https://github.com/GoogleCloudPlatform/secrets-store-csi-driver-provider-gcp
https://cloud.google.com/secret-manager/docs/secret-manager-managed-csi-component#migrate
https://github.com/external-secrets/external-secrets/issues/478#issuecomment-964413129
https://medium.com/google-cloud/consuming-google-secret-manager-secrets-in-gke-911523207a79
https://cloud.google.com/kubernetes-engine/docs/concepts/workload-identity
https://github.com/doitintl/kube-secrets-init
Spero che questo post Le sia stato utile! Per qualsiasi domanda, può lasciare un commento qui sotto.
Se ancora non conosce DoiT International, La invitiamo a scoprirci. Il nostro team è pronto ad approfondire le Sue esigenze di cloud engineering. Composti esclusivamente da Engineers senior, siamo specializzati in consulenza cloud avanzata, progettazione architetturale e supporto al debugging. Ci contatti, parliamone insieme!