Sécuriser ses secrets est essentiel dans tout déploiement Kubernetes. Traditionnellement, la gestion des secrets dans GKE passait par leur injection dans les pods sous forme de variables d'environnement ou de volumes. Fonctionnelle, certes, mais cette approche reste fastidieuse et soulève des questions de sécurité. Heureusement, Google Cloud propose une solution efficace : l'add-on Secret Manager pour GKE.
Dans cet article, je vous explique comment utiliser l'add-on Secret Manager pour GKE pour accéder aux secrets stockés dans Secret Manager sous forme de volumes montés dans des Pods GKE.
:: En mai 2024, cette fonctionnalité est encore en preview, à utiliser donc avec prudence.
Qu'est-ce que Secret Manager ?
Secret Manager est un service managé de Google Cloud Platform (GCP) conçu pour stocker et récupérer des informations sensibles : clés d'API, mots de passe, certificats, etc. Ses atouts :
- Gestion centralisée : les secrets sont regroupés en un seul endroit, ce qui simplifie le contrôle des accès et l'audit.
- Sécurité renforcée : les secrets sont chiffrés au repos et en transit, ce qui limite les risques d'exposition.
- Workload Identity simplifié : les workloads accèdent aux secrets en toute sécurité via workload identity, sans identifiants supplémentaires.
L'add-on Secret Manager en quelques mots
L'add-on Secret Manager pour Google Kubernetes Engine (GKE) simplifie l'accès et la gestion des secrets dans vos pods. Ses avantages :
- Accès direct : inutile d'écrire du code sur mesure, vous accédez directement aux secrets stockés dans Secret Manager depuis vos pods GKE.
- Gestion centralisée : stockez et pilotez tous vos secrets au même endroit (Secret Manager) et accordez l'accès à des secrets précis pour vos pods GKE.
- Sécurité accrue : profitez des fonctionnalités de Secret Manager — chiffrement, contrôle d'accès, rotation, journaux d'audit — combinées aux fonctionnalités Kubernetes comme le montage de volumes pour les secrets.
- Large compatibilité : fonctionne avec les clusters GKE Standard et Autopilot, et prend en charge les déploiements sur architectures AMD comme ARM.
L'add-on s'appuie sur le projet open source Kubernetes Secrets Store CSI Driver et sur le Google Secret Manager provider. Si vous utilisez déjà le Secrets Store CSI Driver open source pour accéder à vos secrets, vous pouvez migrer vers l'add-on Secret Manager. Pour en savoir plus, consultez Migrer depuis le Secrets Store CSI Driver existant.
Tant que l'add-on reste en preview, les fonctionnalités suivantes ne sont pas disponibles :
Ne vaudrait-il pas mieux utiliser External Secrets Operator ?
En résumé : si vous devez respecter des exigences de conformité et éviter d'avoir des secrets natifs Kubernetes dans votre cluster, partez sur le Secrets Store CSI driver et l'add-on Secret Manager pour GKE — vous pourrez monter les secrets de Secret Manager directement comme volumes dans vos pods. Sinon, ESO fera très bien l'affaire.
Un utilisateur GitHub nommé Lucas a publié une comparaison intéressante entre External Secrets Operator et le Secrets Store CSI driver dans ce commentaire, que je reproduis ici :
ESO synchronise les secrets d'un fournisseur cloud vers des secrets k8s ; vous pouvez donc continuer à utiliser les secrets k8s si vous y êtes habitué.
SSCSID monte le secret externe directement comme volume dans un pod, et la présence d'un secret k8s dans le cluster reste optionnelle.
ESO mise sur la configuration via les CRD ; côté secret store du fournisseur, vous ne créez que la valeur du secret.
SSCSID exige que l'intégralité de la configuration ou du secret soit stockée directement dans le fournisseur, puisque l'application devra la consommer telle quelle. Cela peut s'avérer compliqué avec des configurations volumineuses contenant plusieurs secrets imbriqués.
Les secrets ESO s'utilisent nativement avec n'importe quelle ressource k8s — c'est évident, mais 👇
SSCSID a besoin d'un pod webhook pour vraiment bien fonctionner. Pas évident d'utiliser des secrets SSCSID pour les référencer dans un ingress ou un dockerconfig pour le pull d'images, puisque leur seul objectif est le montage dans un pod. Même pour activer la synchronisation avec un secret k8s, il faut d'abord monter le secret dans un pod.
Avec ESO, comme nous synchronisons les secrets avec des secrets natifs k8s, en cas de problème de connectivité vous pouvez toujours accéder au secret présent dans votre cluster ; à la reconnexion, la synchronisation reprend automatiquement.
Avec SSCSID, en cas de perte de connectivité, les montages du csi driver cessent de fonctionner si des redémarrages surviennent, etc. Le sujet est en cours de réflexion, j'ignore où cela en est : doc. À leur demander directement.
ESO se résume à un seul déploiement d'opérateur dans votre cluster.
SSCSID s'appuie sur un daemonset privilégié chargé d'effectuer les montages dans vos pods.
Existe-t-il d'autres options ?
Si vous cherchez une alternative fiable pour récupérer des secrets depuis des services de gestion de secrets directement dans un volume, sans passer par le Kubernetes Secrets Store CSI Driver, cela vaut vraiment le détour.
Par ailleurs, en 2001, Abdellfetah SGHIOUAR, Dev Advocate chez Google, a publié un article intéressant qui passe en revue plusieurs autres options pour stocker des secrets sur GKE. À consulter ici.
**Premiers pas avec** l'add-on Secret Manager pour GKE
Pour commencer, il faut activer l'add-on Secret Manager dans votre cluster. Vous pouvez aussi créer un cluster directement avec ce flag. Pensez à remplacer CLUSTER_NAME et REGION/ZONE.
gcloud beta container clusters update <CLUSTER_NAME> \
--enable-secret-manager \
--location=<ZONE/REGION>
Vérifiez aussi que Workload Identity Federation est bien actif sur votre cluster.
Une fois l'add-on Secret Manager activé, deux nouvelles APIs apparaissent avec la version d'API 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
Pour communiquer avec Secret Manager, il faut accorder les permissions nécessaires au compte de service Kubernetes que nous allons utiliser.
Commençons par créer le namespace k8s et le compte de service utilisés dans notre cluster.
kubectl create ns secret-manager-access
kubectl create sa secret-manager-access-sa
Ensuite, nous utilisons Workload Identity Federation pour accorder les bonnes permissions à notre compte de service K8s. Pensez à remplacer le Project ID et le Project Number dans les variables.
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 : la configuration de Workload Identity Federation a récemment évolué. Pour en savoir plus, consultez cet article dans lequel un collègue de DoiT détaille le sujet.
Ci-dessous, nous créons notre super secret dans Google Secret Manager ainsi que sa première version :
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"
Il nous faut maintenant créer la Custom Resource SecretProviderClass. Elle sera liée au secret GCP créé précédemment. N'oubliez pas de renseigner votre 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
Configurer le volume du 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
Vérifions que le secret est bien là :
kubectl exec -it test-pod -- cat /var/secrets/super-secret.txt
This is my awesome secret, please don't share
Avantages du Secret Manager CSI Driver :
- Sécurité renforcée : les secrets ne sont jamais stockés dans les pods, ce qui réduit la surface d'attaque.
- Gestion simplifiée des workloads : workload identity supprime le besoin de gérer des identifiants à l'intérieur des pods.
- Configuration plus fine : un contrôle granulaire des accès aux secrets permet de définir des permissions précises.
- Journalisation d'audit centralisée : toutes les tentatives d'accès aux secrets sont consignées dans Secret Manager pour faciliter l'audit.
Conclusion
En adoptant l'add-on Secret Manager pour GKE, vous bénéficiez d'un Secret Manager CSI Driver entièrement managé, qui renforce nettement la posture de sécurité de GKE et simplifie la gestion des secrets dans vos applications. Avec un contrôle centralisé, un montage automatisé et un contrôle d'accès robuste, le CSI Driver vous permet de vous concentrer sereinement sur le développement et le déploiement de vos applications.
Références :
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
J'espère que cet article vous aura été utile ! Pour toute question, n'hésitez pas à laisser un commentaire ci-dessous.
Si vous ne connaissez pas encore DoiT International, c'est l'occasion de nous découvrir. Notre équipe est à l'écoute pour mieux comprendre vos besoins en cloud engineering. Composée exclusivement d'Engineers seniors, elle est spécialisée dans le conseil cloud avancé, la conception d'architectures et l'aide au debugging. Contactez-nous, et discutons-en !