E-NO
Kubernetes 7 min de lecture

Kubernetes Secrets Concepts Avancés : Guide Pratique d'Implémentation

calendar_today Publié : 2026-08-13
update Dernière mise à jour : 2026-08-13
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Kubernetes Secrets Concepts Avancés : Guide Pratique d'Implémentation ».

Les Secrets Kubernetes constituent la base de la gestion des données sensibles dans les environnements conteneurisés, mais de nombreuses équipes peinent à aller au-delà du simple stockage clé-valeur pour adopter des patterns prêts pour la production. Ce guide couvre les concepts avancés de gestion des Secrets, notamment le chiffrement au repos, les opérateurs de secrets externes, les stratégies de rotation et les configurations prêtes pour l'audit. Chaque section inclut des commandes concrètes, les sorties attendues et les étapes de vérification pour appliquer ces patterns en toute sécurité dans vos clusters.

Chiffrement au Repos et Configuration des Fournisseurs

Kubernetes stocke les Secrets non chiffrés dans etcd par défaut. Activer le chiffrement au repos nécessite de configurer le kube-apiserver avec une ressource EncryptionConfiguration qui définit quelles ressources chiffrer et quel fournisseur utiliser. Les fournisseurs supportés incluent aescbc, aesgcm, secretbox et kms — ce dernier étant la seule option qui garde les clés de chiffrement hors du control plane entièrement.

Créez un fichier de configuration de chiffrement à /etc/kubernetes/encryption-config.yaml :

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
      - configmaps
    providers:
      - kms:
          name: myKMSProvider
          endpoint: unix:///var/run/kms-plugin/socket.sock
          cachesize: 1000
          timeout: 3s
      - aescbc:
          keys:
            - name: key1
              secret: c2VjcmV0IGtleSBtYXR0ZXJzIGhlcmU=

Mettez à jour le manifeste du kube-apiserver (/etc/kubernetes/manifests/kube-apiserver.yaml) pour référencer ce fichier :

- --encryption-provider-config=/etc/kubernetes/encryption-config.yaml

Après le redémarrage de l'apiserver, vérifiez que le chiffrement est actif en créant un Secret de test et en examinant les données brutes d'etcd :

kubectl create secret generic test-encryption --from-literal=token=my-secret-value
ETCDCTL_API=3 etcdctl get /registry/secrets/default/test-encryption --print-value-only | xxd | head -20

La sortie doit afficher des données binaires sans le texte en clair my-secret-value visible. Si vous voyez le texte en clair, le chiffrement ne fonctionne pas — consultez les logs du kube-apiserver pour les erreurs liées à encryption.

Rotation des clés : Pour faire pivoter la clé de chiffrement, ajoutez une nouvelle clé à la liste keys avec name: key2 et placez-la en premier. Redémarrez l'apiserver. Puis réchiffrez les Secrets existants :

kubectl get secrets --all-namespaces -o json | kubectl replace -f -

Surveillez la progression du réchiffrement avec kubectl get secrets --all-namespaces -o custom-columns=NAME:.metadata.name,ENCRYPTED:.metadata.annotations.kubernetes\.io/encrypted.

Opérateur External Secrets et Synchronisation des Secrets

Stocker les secrets dans etcd Kubernetes crée un point de défaillance unique et complique la synchronisation multi-cluster. L'External Secrets Operator (ESO) récupère les secrets depuis des fournisseurs externes — AWS Secrets Manager, HashiCorp Vault, Azure Key Vault, GCP Secret Manager — et les matérialise comme Secrets Kubernetes.

Installez ESO via Helm :

helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets -n external-secrets-system --create-namespace

Configurez un ClusterSecretStore pour AWS Secrets Manager avec IRSA (IAM Roles for Service Accounts) :

apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
  name: aws-secrets-manager
spec:
  provider:
    aws:
      service: SecretsManager
      region: us-east-1
      auth:
        jwt:
          serviceAccountRef:
            name: external-secrets-sa
            namespace: external-secrets-system

Créez le compte de service et annotez-le avec l'ARN du rôle IAM :

kubectl annotate sa external-secrets-sa -n external-secrets-system \
  eks.amazonaws.com/role-arn=arn:aws:iam::123456789012:role/ExternalSecretsRole

Définissez maintenant un ExternalSecret qui synchronise un secret spécifique depuis AWS :

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-credentials
  namespace: production
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: ClusterSecretStore
  target:
    name: db-creds
    creationPolicy: Owner
  data:
    - secretKey: username
      remoteRef:
        key: prod/database
        property: username
    - secretKey: password
      remoteRef:
        key: prod/database
        property: password

Vérifiez la synchronisation :

kubectl get externalsecret database-credentials -n production -o yaml
kubectl get secret db-creds -n production -o jsonpath='{.data.username}' | base64 -d

Le refreshInterval contrôle la fréquence à laquelle ESO interroge le fournisseur. Pour une propagation immédiate après un changement de secret dans AWS, déclenchez un rafraîchissement manuel :

kubectl annotate externalsecret database-credentials -n production force-refresh=$(date +%s) --overwrite

Mode de défaillance : Si le fournisseur externe est inaccessible, ESO conserve le dernier Secret synchronisé avec succès. Vérifiez kubectl describe externalsecret pour le statut Condition: Ready et LastRefreshTime. Configurez des alertes Prometheus sur l'ancienneté de external_secrets_last_refresh_timestamp_seconds.

Rotation Automatisée des Secrets avec Reloader et Pilotes CSI

Faire pivoter les secrets sans redémarrage de pods nécessite soit un sidecar qui surveille les changements, soit le pilote Secrets Store CSI Driver avec la rotation activée. Le pilote CSI monte les secrets comme fichiers et peut les rafraîchir sur un intervalle configurable.

Installez le Secrets Store CSI Driver et le fournisseur pour votre backend (exemple : AWS) :

helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts
helm install csi secrets-store-csi-driver/secrets-store-csi-driver -n kube-system --set syncSecret.enabled=true --set enableSecretRotation=true

Créez un SecretProviderClass référençant le fournisseur AWS :

apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: aws-secrets
  namespace: production
spec:
  provider: aws
  parameters:
    objects: |
      - objectName: "prod/api-key"
        objectType: "secretsmanager"
        jmesPath:
          - path: api_key
            objectAlias: api-key
  secretObjects:
    - secretName: api-credentials
      type: Opaque
      data:
        - objectName: api-key
          key: api-key

Montez le volume CSI dans votre Deployment :

volumes:
  - name: secrets-store
    csi:
      driver: secrets-store.csi.k8s.io
      readOnly: true
      volumeAttributes:
        secretProviderClass: aws-secrets
volumeMounts:
  - name: secrets-store
    mountPath: "/mnt/secrets"
    readOnly: true

Avec enableSecretRotation=true, le pilote interroge le fournisseur toutes les 2 minutes (configurable via rotationPollInterval) et met à jour les fichiers montés et le Secret Kubernetes synchronisé. Les applications lisant depuis /mnt/secrets/api-key voient la nouvelle valeur sans redémarrage.

Vérification : Mettez à jour le secret dans AWS Secrets Manager, puis observez le pod :

kubectl exec -it <nom-du-pod> -n production -- cat /mnt/secrets/api-key
kubectl get secret api-credentials -n production -o jsonpath='{.data.api-key}' | base64 -d

Les deux doivent refléter la nouvelle valeur dans l'intervalle d'interrogation. Sinon, vérifiez les pods du pilote CSI : kubectl logs -n kube-system -l app=secrets-store-csi-driver.

Alternative pour environnements non-CSI : Utilisez l'annotation de deployment stakater/reloader pour déclencher des redémarrages progressifs quand un Secret change :

annotations:
  reloader.stakater.com/auto: "true"

Cela redémarre les pods quand tout Secret ou ConfigMap référencé change — plus simple mais cause une brève indisponibilité pendant le déploiement.

RBAC, Journalisation d'Audit et Scoping par Namespace

Les Secrets sont des cibles de haute valeur. Restreignez l'accès avec du RBAC au moindre privilège et activez la journalisation d'audit pour détecter les patterns d'accès anormaux.

Créez un Role autorisant la lecture de Secrets spécifiques uniquement dans un namespace :

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: secret-reader-limited
  namespace: production
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    resourceNames: ["db-creds", "api-credentials", "tls-cert"]
    verbs: ["get", "list", "watch"]

Lieze-le à un ServiceAccount utilisé par votre application :

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: secret-reader-binding
  namespace: production
subjects:
  - kind: ServiceAccount
    name: app-sa
    namespace: production
roleRef:
  kind: Role
  name: secret-reader-limited
  apiGroup: rbac.authorization.k8s.io

Politique d'audit : Configurez la politique d'audit du kube-apiserver pour journaliser l'accès aux Secrets au niveau Metadata ou Request. Créez /etc/kubernetes/audit-policy.yaml :

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: Request
    resources:
      - group: ""
        resources: ["secrets"]
    namespaces: ["production", "staging"]
  - level: Metadata
    resources:
      - group: ""
        resources: ["secrets"]

Montez et activez dans le kube-apiserver :

- --audit-policy-file=/etc/kubernetes/audit-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit.log
- --audit-log-maxage=30
- --audit-log-maxbackup=10
- --audit-log-maxsize=100

Interrogez les logs d'audit pour l'activité suspecte :

grep '"resource":"secrets"' /var/log/kubernetes/audit.log | jq -r '.user.username + " " + .verb + " " + .objectRef.name' | sort | uniq -c | sort -rn

Cela fait ressortir les utilisateurs ou comptes de service accédant à un nombre inhabituel de Secrets. Alertez sur verb: "get" OR "list" depuis des comptes de service qui ne devraient que watch.

Isolation par namespace : Utilisez ResourceQuota pour limiter le nombre de Secrets par namespace et prévenir la prolifération :

apiVersion: v1
kind: ResourceQuota
metadata:
  name: secret-quota
  namespace: production
spec:
  hard:
    secrets: "50"

Secrets Immuables et Patterns de Déploiement Versionnés

Kubernetes 1.19+ supporte les Secrets immuables. Une fois marqués immuables, un Secret ne peut être modifié ou supprimé — seulement remplacé en créant un nouveau Secret avec un nom différent. Cela empêche les écrasements accidentels et permet des patterns de rollback sûrs.

Créez un Secret immuable :

kubectl create secret generic app-config-v1 --from-literal=api-endpoint=https://api.v1.example.com --immutable

Mettez à jour le Deployment pour référencer le nom du Secret versionné :

envFrom:
  - secretRef:
      name: app-config-v1

Lors de la rotation de configuration, créez app-config-v2, mettez à jour le manifeste du Deployment, et déployez :

kubectl create secret generic app-config-v2 --from-literal=api-endpoint=https://api.v2.example.com --immutable
kubectl set env deployment/my-app -n production ENV_VERSION=v2
kubectl rollout status deployment/my-app -n production

Si le déploiement échoue, le rollback est instantané :

kubectl rollout undo deployment/my-app -n production

Les anciens pods référencent encore app-config-v1 qui reste intact. Nettoyez les anciennes versions après avoir vérifié la stabilité :

kubectl delete secret app-config-v1 -n production  # Seulement après confirmation qu'aucun pod ne le référence

Vérification : Vérifiez qu'aucun pod ne référence l'ancien Secret :

kubectl get pods -n production -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].envFrom[*].secretRef.name}{"\n"}{end}' | grep app-config-v1

Une sortie vide confirme la suppression sûre.

Conclusion

La gestion avancée des Secrets Kubernetes combine le chiffrement au repos, la synchronisation de secrets externes, la rotation automatisée, le RBAC strict, la visibilité d'audit et le versionnage immuable pour créer une posture de défense en profondeur. Commencez par activer le chiffrement au repos sur votre control plane — cela protège les données même si les sauvegardes etcd sont compromises. Ajoutez l'External Secrets Operator ou le pilote CSI pour retirer les secrets de Git et des pipelines CI entièrement. Appliquez un RBAC au moindre privilège avec des Roles limités par resourceName, et activez la journalisation d'audit au niveau Request pour les namespaces de production. Enfin, adoptez des Secrets immuables et versionnés pour les changements de configuration afin que les rollbacks soient instantanés et auditable. Chaque couche réduit le rayon d'impact et augmente la confiance opérationnelle. Validez chaque contrôle dans un cluster de staging avant de promouvoir en production, et documentez les commandes exactes et sorties attendues pour vos runbooks.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO