
Un Secret Kubernetes permet de stocker des données sensibles comme des mots de passe, des clés API, des tokens ou des certificats. Il fournit un conteneur dédié pour ce type d’information, mais sa sécurité dépend surtout du RBAC, du chiffrement au repos et de la manière dont vous l’injectez dans vos Pods.
Ce guide montre comment créer un Secret, choisir son type, l’injecter dans un Pod et appliquer les bonnes pratiques de sécurité.
Prérequis : un cluster Kubernetes avec kubectl configuré.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre ce qu’un Secret protège (et ce qu’il ne protège pas)
- Créer des Secrets de différents types (Opaque, TLS, docker-registry)
- Injecter les Secrets dans vos Pods (env ou volume)
- Appliquer les bonnes pratiques de sécurité essentielles
- Décider quand passer à un gestionnaire de secrets externe
Ce qu’un Secret apporte de plus qu’un ConfigMap
Section intitulée « Ce qu’un Secret apporte de plus qu’un ConfigMap »Un Secret Kubernetes est pensé pour des données sensibles, mais il ne devient réellement sûr que si vous mettez en place les bonnes protections autour :
- Contrôle d’accès strict avec RBAC
- Chiffrement au repos dans etcd
- Limitation des accès API
- Montage en volume plutôt qu’en variables d’environnement lorsque c’est pertinent
Par défaut, un Secret reste lisible par toute identité autorisée à le récupérer via l’API Kubernetes.
Pourquoi base64 n’est pas du chiffrement
Section intitulée « Pourquoi base64 n’est pas du chiffrement »C’est le piège le plus courant. Beaucoup pensent que l’encodage base64 protège leurs données. C’est faux.
# Créer un Secretkubectl create secret generic demo-secret --from-literal=password='S3cr3t!P@ss'
# Voir le Secret "protégé"kubectl get secret demo-secret -o jsonpath='{.data.password}'UzNjcjN0IVBAc3M=# Décoder en une commandeecho 'UzNjcjN0IVBAc3M=' | base64 -dS3cr3t!P@ssLe décodage est instantané. Base64 sert uniquement à transporter des données binaires dans du YAML/JSON, pas à les protéger.
Types de Secrets Kubernetes
Section intitulée « Types de Secrets Kubernetes »Kubernetes propose plusieurs types de Secrets, chacun avec une structure adaptée :
| Type | Usage | Clés créées |
|---|---|---|
Opaque | Usage générique (mots de passe, tokens) | Libres |
kubernetes.io/tls | Certificats TLS | tls.crt, tls.key |
kubernetes.io/dockerconfigjson | Authentification registry | .dockerconfigjson |
kubernetes.io/basic-auth | Authentification HTTP basique | username, password |
kubernetes.io/ssh-auth | Clé SSH | ssh-privatekey |
Créer un Secret
Section intitulée « Créer un Secret »Secret Opaque (usage courant)
Section intitulée « Secret Opaque (usage courant) »La méthode la plus simple pour des identifiants :
kubectl create secret generic db-credentials \ --from-literal=username=admin \ --from-literal=password='S3cr3t!P@ss'Vérifiez la création :
kubectl get secret db-credentialsNAME TYPE DATA AGEdb-credentials Opaque 2 5sSecret TLS
Section intitulée « Secret TLS »Pour stocker un certificat et sa clé privée :
kubectl create secret tls my-tls-secret \ --cert=server.crt \ --key=server.keykubectl get secret my-tls-secretNAME TYPE DATA AGEmy-tls-secret kubernetes.io/tls 2 5sSecret docker-registry
Section intitulée « Secret docker-registry »Pour s’authentifier auprès d’un registre privé :
kubectl create secret docker-registry my-registry \ --docker-server=registry.example.com \ --docker-username=myuser \ --docker-password=mypasswordUtilisez-le dans un Pod avec imagePullSecrets :
spec: imagePullSecrets: - name: my-registry containers: - name: app image: registry.example.com/myapp:latestSecret depuis un fichier YAML
Section intitulée « Secret depuis un fichier YAML »Pour un contrôle total et la gestion en GitOps :
apiVersion: v1kind: Secretmetadata: name: db-credentialstype: Opaquedata: username: YWRtaW4= # echo -n 'admin' | base64 password: UzNjcjN0IVBAc3M= # echo -n 'S3cr3t!P@ss' | base64Vous pouvez aussi utiliser stringData pour éviter l’encodage manuel :
apiVersion: v1kind: Secretmetadata: name: db-credentialstype: OpaquestringData: username: admin password: S3cr3t!P@ssKubernetes convertit automatiquement stringData en data encodé.
Injecter un Secret dans un Pod
Section intitulée « Injecter un Secret dans un Pod »Deux méthodes principales, chacune avec ses cas d’usage :
| Méthode | Cas d’usage | Mise à jour auto |
|---|---|---|
| Variable d’environnement | Identifiants simples | Non |
| Volume | Certificats, fichiers de config | Oui (~60s) |
Méthode 1 : Variables d’environnement
Section intitulée « Méthode 1 : Variables d’environnement »apiVersion: apps/v1kind: Deploymentmetadata: name: myappspec: replicas: 1 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: app image: nginx env: - name: DB_USERNAME valueFrom: secretKeyRef: name: db-credentials key: username - name: DB_PASSWORD valueFrom: secretKeyRef: name: db-credentials key: passwordVérifiez l’injection :
kubectl exec deploy/myapp -- env | grep DB_DB_USERNAME=adminDB_PASSWORD=S3cr3t!P@ssLes valeurs sont décodées automatiquement dans le conteneur.
Méthode 2 : Monter comme volume
Section intitulée « Méthode 2 : Monter comme volume »Recommandé pour les certificats et fichiers de configuration :
apiVersion: apps/v1kind: Deploymentmetadata: name: myappspec: selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: app image: nginx volumeMounts: - name: secret-volume mountPath: /etc/secrets readOnly: true volumes: - name: secret-volume secret: secretName: db-credentials defaultMode: 0400Vérifiez les fichiers montés :
kubectl exec deploy/myapp -- ls -la /etc/secretslrwxrwxrwx 1 root root 15 password -> ..data/passwordlrwxrwxrwx 1 root root 15 username -> ..data/usernameLes liens symboliques permettent la mise à jour automatique (~60s de délai).
Monter une seule clé avec un nom personnalisé
Section intitulée « Monter une seule clé avec un nom personnalisé »volumes:- name: secret-volume secret: secretName: db-credentials items: - key: password path: db-passwordLe fichier /etc/secrets/db-password contient uniquement le mot de passe.
Sécurité : les pratiques essentielles
Section intitulée « Sécurité : les pratiques essentielles »1. Restreindre l’accès avec RBAC
Section intitulée « 1. Restreindre l’accès avec RBAC »Par défaut, tout utilisateur avec get sur les Secrets peut les lire. Créez des Roles restrictifs :
apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: name: secret-reader namespace: productionrules:- apiGroups: [""] resources: ["secrets"] resourceNames: ["db-credentials"] # Limiter aux Secrets nécessaires verbs: ["get"]2. Activer le chiffrement dans etcd
Section intitulée « 2. Activer le chiffrement dans etcd »Par défaut, Kubernetes stocke les Secrets en clair dans etcd. Activez le chiffrement au repos :
apiVersion: apiserver.config.k8s.io/v1kind: EncryptionConfigurationresources:- resources: - secrets providers: - aescbc: keys: - name: key1 secret: <base64-encoded-32-byte-key> - identity: {}3. Préférer le montage volume aux variables d’environnement
Section intitulée « 3. Préférer le montage volume aux variables d’environnement »| Aspect | Variable env | Volume |
|---|---|---|
Visible dans docker inspect | Oui | Non |
Visible dans /proc/<pid>/environ | Oui | Non |
| Mise à jour automatique | Non | Oui |
Le montage en volume est souvent préférable pour limiter certaines expositions accidentelles et bénéficier de mises à jour automatiques, mais il ne remplace ni un bon cloisonnement des accès ni un durcissement du runtime. Si le conteneur est compromis, les fichiers montés restent accessibles au processus.
4. Faire la rotation des Secrets
Section intitulée « 4. Faire la rotation des Secrets »# Mettre à jour le Secretkubectl create secret generic db-credentials \ --from-literal=username=admin \ --from-literal=password='N0uv3@uP@ss!' \ --dry-run=client -o yaml | kubectl apply -f -
# Redémarrer les Pods pour appliquerkubectl rollout restart deployment myappQuand passer à un gestionnaire externe
Section intitulée « Quand passer à un gestionnaire externe »Les Secrets Kubernetes natifs ont des limites :
| Limite | Impact |
|---|---|
| Pas de rotation automatique | Vous devez mettre à jour manuellement |
| Pas d’audit détaillé | Qui a accédé à quel Secret ? |
| Chiffrement etcd à configurer | Pas activé par défaut |
| Secrets visibles en YAML | Risque de commit accidentel |
Utilisez un gestionnaire externe si vous avez besoin de :
- Rotation automatique des secrets
- Audit détaillé des accès
- Intégration avec des secrets existants (AWS, Azure, GCP)
- Secrets dynamiques (credentials de BDD à durée limitée)
Solutions recommandées :
- HashiCorp Vault avec External Secrets ou Vault Sidecar
- AWS Secrets Manager / Azure Key Vault / GCP Secret Manager
- Sealed Secrets pour chiffrer les Secrets dans Git
Debug : problèmes courants
Section intitulée « Debug : problèmes courants »-
Le Secret existe-t-il ?
Fenêtre de terminal kubectl get secret db-credentialsSi “NotFound”, créez-le d’abord.
-
La clé existe-t-elle dans le Secret ?
Fenêtre de terminal kubectl get secret db-credentials -o jsonpath='{.data}'Vérifiez l’orthographe exacte de la clé.
-
Le Pod référence-t-il le bon Secret ?
Fenêtre de terminal kubectl describe pod myapp-xxx | grep -A5 "Environment\|Mounts" -
Erreur CreateContainerConfigError ?
Secret ou clé introuvable. Vérifiez que le Secret existe dans le même namespace que le Pod.
Erreurs fréquentes
Section intitulée « Erreurs fréquentes »| Erreur | Cause | Solution |
|---|---|---|
CreateContainerConfigError | Secret ou clé introuvable | Vérifier nom et namespace |
| Variable vide | Clé mal orthographiée | kubectl get secret -o yaml |
unauthorized | RBAC insuffisant | Vérifier les permissions |
À retenir
Section intitulée « À retenir »- Un Secret stocke les données sensibles, mais base64 n’est pas du chiffrement
- Les types de Secrets (Opaque, TLS, docker-registry) structurent vos données
- Variables d’environnement : simples mais jamais rafraîchies automatiquement
- Volumes : préférables pour la sécurité et la mise à jour automatique
- RBAC est votre première ligne de défense — restreignez l’accès aux Secrets
- Chiffrement etcd : activez-le pour protéger les Secrets au repos
- Pour la rotation automatique ou l’audit, passez à un gestionnaire externe