## Introduction

Les Secrets Kubernetes stockent des informations sensibles telles que des mots de passe, des jetons et des clés TLS. Si un Secret est mal configuré, divulgué ou indisponible, les applications échouent ou les informations d'identification peuvent être compromises. Surveiller les Secrets ne consiste pas à exposer leur contenu. Il s'agit de détecter quand ils sont créés, mis à jour, supprimés ou ne parviennent pas à être montés correctement, et quand les modèles d'accès semblent suspects.

Ce guide couvre la surveillance pratique des Secrets pour les développeurs, les ingénieurs DevOps, les SRE et les équipes plateforme. Il relie les alertes, les métriques, les tableaux de bord et la réponse aux incidents à des commandes réelles, des sorties attendues et des décisions de récupération. L'accent est mis sur la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, éviter de journaliser les valeurs des secrets, vérifier les résultats et documenter les chemins de récupération.

Vous trouverez des exemples concrets pour les journaux d'audit Kubernetes, le Metrics Server, Prometheus, Alertmanager, Grafana et un playbook de réponse aux incidents étape par étape. Chaque exemple suppose un cluster fonctionnel avec `kubectl` configuré et, le cas échéant, Prometheus ou Grafana installé.

## Inventaire de la version et de l'environnement

Avant de surveiller les Secrets, connaissez votre environnement. Commencez par des observations en lecture seule pour établir l'état actuel. Cela évite des erreurs comme appliquer un correctif au mauvais cluster ou supposer qu'une fonctionnalité est disponible alors qu'elle ne l'est pas.

### Vérifier la version de Kubernetes

```bash
kubectl version --short
```

Exemple de sortie attendue :

```text
Client Version: v1.28.2
Server Version: v1.28.4
```

Certaines fonctionnalités de surveillance des Secrets, telles que les politiques de journal d'audit ou les Secrets `Immutable`, dépendent de la version du serveur API. Par exemple, les Secrets `Immutable` sont devenus stables dans Kubernetes 1.21. Si votre cluster est plus ancien, ne vous fiez pas à ce champ.

### Lister les Secrets existants

```bash
kubectl get secrets --all-namespaces
```

Exemple de sortie :

```text
NAMESPACE     NAME                  TYPE                                  DATA   AGE
default       my-app-secret         Opaque                                2      3d
kube-system   default-token-abcde   kubernetes.io/service-account-token   3      180d
```

Notez l'espace de noms, le nom, le type, le nombre de clés de données et l'âge. Un Secret récemment créé dans un espace de noms sensible peut mériter une inspection plus approfondie.

### Inspecter sans révéler les valeurs

N'exécutez jamais `kubectl get secret -o yaml` à la légère, car cela imprime des valeurs encodées en base64 qui peuvent être décodées. À la place, listez uniquement les clés :

```bash
kubectl get secret my-app-secret -n default -o jsonpath='{.data}' | jq 'keys'
```

Exemple de sortie :

```text
[
  "password",
  "username"
]
```

Cela confirme que le Secret existe et possède les clés attendues sans exposer les données.

### Vérifier l'état du montage

Si une application utilise un Secret, vérifiez qu'il est monté correctement. Trouvez le pod :

```bash
kubectl get pods -n default -l app=my-app
```

Puis inspectez les montages de volume :

```bash
kubectl describe pod <pod-name> -n default | grep -A 5 Mounts
```

Exemple de sortie :

```text
Mounts:
  /etc/app-secrets from secret-volume (ro)
  /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-xxxxx (ro)
```

Si le point de montage est absent, le Secret peut ne pas être référencé dans la spécification du pod.

## Chemin de configuration sûr

Les changements de configuration de la surveillance des Secrets doivent être incrémentaux. Commencez par des métriques en lecture seule et des journaux d'audit avant d'activer des alertes bloquantes.

### Activer la journalisation d'audit

Les journaux d'audit Kubernetes enregistrent toutes les requêtes API, y compris celles concernant les Secrets. Configurez le serveur API avec un fichier de politique d'audit qui journalise l'accès aux Secrets au niveau `Metadata` ou supérieur. Un fichier de politique minimal :

```yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
  resources:
  - group: ""
    resources: ["secrets"]
```

Appliquez la politique au serveur API (cela nécessite les drapeaux kube-apiserver `--audit-policy-file` et `--audit-log-path`). Testez ensuite en listant les Secrets :

```bash
kubectl get secrets
```

Vérifiez le journal d'audit pour les entrées :

```text
{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"...","stage":"ResponseComplete","requestURI":"/api/v1/secrets","verb":"list","user":{"username":"admin"},"sourceIPs":["10.0.0.1"],"responseStatus":{"code":200}}
```

Cela vous donne une piste sans journaliser les données des secrets.

### Utiliser un compte de service dédié

Créez un compte de service dédié pour les outils de surveillance avec le moindre privilège. Par exemple :

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: secret-monitor
  namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: secret-monitor-role
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: secret-monitor-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: secret-monitor-role
subjects:
- kind: ServiceAccount
  name: secret-monitor
  namespace: monitoring
```

Appliquez-le :

```bash
kubectl apply -f secret-monitor-rbac.yaml
```

Testez l'accès depuis le compte de service :

```bash
kubectl auth can-i list secrets --as=system:serviceaccount:monitoring:secret-monitor
```

Attendu : `yes`

### Tester dans un espace de noms hors production

Avant de modifier la production, créez un Secret de test dans un espace de noms de bac à sable et vérifiez que votre pile de surveillance le détecte.

## Vérification et diagnostic

Avec l'observation de base en place, collectez des métriques et mettez en place des diagnostics qui révèlent la santé de l'utilisation des Secrets.

### Métriques du serveur API

Le serveur API Kubernetes expose des métriques sur les requêtes, y compris les opérations sur les Secrets. Si vous avez Prometheus qui collecte le serveur API, les métriques utiles incluent :

- `apiserver_request_total{resource="secrets"}`
- `apiserver_request_duration_seconds_bucket{resource="secrets"}`

Par exemple, une requête PromQL pour voir le taux de requêtes de liste de Secrets sur 5 minutes :

```promql
rate(apiserver_request_total{resource="secrets", verb="list"}[5m])
```

Cela peut indiquer une activité inhabituelle si le taux augmente.

### Vérifier les pods avec des Secrets montés

Utilisez `kubectl` pour trouver les pods qui montent un Secret particulier. Cela aide à diagnostiquer pourquoi une mise à jour de Secret n'est pas répercutée (les pods ont souvent besoin d'un redémarrage pour prendre en compte les modifications des Secrets montés) :

```bash
kubectl get pods --all-namespaces -o json | jq -r '.items[] | select(.spec.volumes[]?.secret.secretName == "my-app-secret") | .metadata.namespace + "/" + .metadata.name'
```

Exemple de sortie :

```text
default/my-app-7d4f8b9c6-abcde
default/my-app-7d4f8b9c6-fghij
```

### Inspecter les événements

Les événements capturent souvent les problèmes liés aux Secrets, tels que les échecs de montage :

```bash
kubectl get events --all-namespaces --field-selector reason=FailedMount
```

Exemple de sortie :

```text
NAMESPACE   LAST SEEN   TYPE     REASON        OBJECT             MESSAGE
default     2m          Warning  FailedMount   pod/my-app-...     MountVolume.SetUp failed for volume "secret-volume" : secret "my-app-secret" not found
```

Cela vous indique immédiatement que le Secret est manquant.

### Utiliser des règles d'alerte Prometheus

Définissez des règles d'alerte pour les opérations sur les Secrets. Par exemple, alertez si un Secret est supprimé de manière inattendue :

```yaml
groups:
- name: kubernetes-secrets
  rules:
  - alert: SecretDeleted
    expr: increase(apiserver_request_total{resource="secrets", verb="delete"}[10m]) > 0
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "Secret supprimé au cours des 10 dernières minutes"
      description: "Une requête de suppression de Secret a été observée. Enquêtez immédiatement."
```

Testez l'alerte en supprimant un Secret de test et en vérifiant Alertmanager.

## Modes de défaillance et récupération

Les Secrets échouent de manière prévisible. Connaître les modes de défaillance vous aide à détecter et à récupérer rapidement.

### Mode de défaillance 1 : Secret introuvable

**Symptôme** : Les pods ne démarrent pas avec des événements `FailedMount` référençant un Secret manquant.

**Diagnostic** : Vérifiez l'espace de noms et le nom du Secret :

```bash
kubectl get secrets -n <namespace> | grep <secret-name>
```

S'il n'est pas trouvé, le Secret peut avoir été supprimé ou créé dans un autre espace de noms.

**Récupération** : Recréez le Secret à partir d'une source fiable. Si vous utilisez un contrôle de version ou un gestionnaire de secrets, appliquez le manifeste :

```bash
kubectl apply -f secret.yaml
```

Puis redémarrez les pods affectés :

```bash
kubectl rollout restart deployment <deployment-name>
```

### Mode de défaillance 2 : Données de Secret incorrectes

**Symptôme** : L'application se connecte à une base de données mais obtient des erreurs d'authentification. Le Secret existe mais contient des valeurs incorrectes.

**Diagnostic** : Comparez les clés de données et, sans imprimer les valeurs, vérifiez l'encodage base64 ou le hachage. Si possible, vérifiez les journaux d'application pour des indices sans exposer les secrets.

**Récupération** : Mettez à jour le Secret avec des valeurs correctes en utilisant une méthode sécurisée. Par exemple, créez à partir de littéraux :

```bash
kubectl create secret generic my-app-secret --from-literal=username=correct-user --from-literal=password='correct-password' --dry-run=client -o yaml | kubectl apply -f -
```

Puis redémarrez les pods.

### Mode de défaillance 3 : Rotation de Secret non répercutée

**Symptôme** : Après avoir fait tourner un secret dans un système externe, l'application utilise toujours les anciennes informations d'identification. Cela arrive souvent parce que les pods mettent en cache les Secrets.

**Diagnostic** : Vérifiez l'heure de démarrage du pod et l'âge du Secret :

```bash
kubectl get pod <pod-name> -o jsonpath='{.metadata.creationTimestamp}'
kubectl get secret <secret-name> -o jsonpath='{.metadata.creationTimestamp}'
```

Si le pod est plus ancien que la mise à jour du Secret, il utilise l'ancien volume monté.

**Récupération** : Redémarrez les pods pour remonter le Secret mis à jour :

```bash
kubectl rollout restart deployment <deployment-name>
```

Si vous utilisez un Secret avec `immutable: true`, vous devez supprimer et recréer le pod ou utiliser un nouveau nom de Secret.

### Mode de défaillance 4 : Accès non autorisé ou fuite

**Symptôme** : Les journaux d'audit montrent des requêtes `get` ou `list` inattendues pour les Secrets provenant d'un utilisateur ou d'une IP inconnue.

**Diagnostic** : Examinez les journaux d'audit :

```text
{"verb":"get","resource":"secrets","user":{"username":"system:serviceaccount:default:compromised-sa"},"sourceIPs":["203.0.113.50"]}
```

**Récupération** : Révoquez immédiatement le compte de service ou les informations d'identification de l'utilisateur, faites tourner les Secrets affectés et enquêtez sur l'IP source. Appliquez une politique réseau pour restreindre l'accès au serveur API si nécessaire.

## Tableau de bord et surveillance continue

Un tableau de bord donne une vue d'ensemble de la santé et de l'activité des Secrets. Utilisez Grafana avec la source de données Prometheus.

### Exemples de panneaux Grafana

**Panneau 1 : Secrets créés/supprimés (dernières 24 heures)**

```promql
sum(increase(apiserver_request_total{resource="secrets", verb="create"}[24h])) by (namespace)
```

**Panneau 2 : Taux de lecture des Secrets par utilisateur**

```promql
sum by (user) (rate(apiserver_request_total{resource="secrets", verb="get"}[5m]))
```

**Panneau 3 : Pods avec échecs de montage de Secrets**

Cela nécessite un exportateur personnalisé ou l'utilisation de kube-state-metrics. Kube-state-metrics expose `kube_pod_container_status_waiting_reason` pour `CrashLoopBackOff`, mais pour les échecs de montage de Secrets, vous devrez peut-être analyser les événements ou utiliser une métrique personnalisée. Sinon, utilisez le tableau de bord basé sur les journaux Elasticsearch ou Loki suivant si vous collectez des événements.

### Exemple d'alerte : Échec de montage de Secret

Si vous collectez les événements Kubernetes dans Prometheus via un exportateur comme `eventrouter`, vous pouvez créer une alerte :

```yaml
- alert: SecretMountFailed
  expr: increase(kube_event_count{reason="FailedMount", involved_object_kind="Pod"}[10m]) > 0
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "Des pods échouent à monter un Secret"
```

### Utiliser kube-state-metrics

Kube-state-metrics fournit une métrique `kube_secret_created` et `kube_secret_info`. Vous pouvez alerter sur des Secrets nouveaux inattendus :

```promql
increase(kube_secret_created[1h]) > 3
```

Cela pourrait être un signe de mauvaise configuration ou d'attaque.

## Liste de contrôle des opérations

Utilisez cette liste de contrôle dans le cadre de votre revue hebdomadaire des opérations. Attribuez chaque élément à un propriétaire et définissez une fréquence de révision. Par exemple, « Priya Shah, responsable de l'ingénierie » est propriétaire de la revue de surveillance des Secrets, et la revue a lieu tous les lundis matin.

### Vérifications quotidiennes (automatisées)

- [ ] Alertmanager n'a aucune alerte critique active pour les opérations sur les Secrets.
- [ ] Le tableau de bord Grafana ne montre aucun pic inattendu dans les lectures de Secrets.
- [ ] L'échantillon du journal d'audit ne montre aucune tentative d'accès non autorisé aux Secrets.
- [ ] Tous les pods avec des Secrets montés sont en état Running et ne redémarrent pas en boucle.

### Vérifications hebdomadaires (revue manuelle)

- [ ] Examiner la liste des Secrets créés ou supprimés au cours de la semaine écoulée. Propriétaire : Priya Shah, responsable de l'ingénierie. À revoir chaque semaine.
- [ ] Confirmer que les Secrets ayant fait l'objet d'une rotation ont été mis à jour et que les pods ont redémarré. Propriétaire : Marcus Chen, ingénieur DevOps.
- [ ] Vérifier les Secrets obsolètes non utilisés par aucun pod. Utilisez :
  ```bash
  kubectl get secrets --all-namespaces -o json | jq -r '.items[] | select(.metadata.ownerReferences == null) | .metadata.namespace + "/" + .metadata.name'
  ```
  Vérifiez ensuite s'ils sont nécessaires.
- [ ] Examiner les permissions RBAC pour l'accès aux Secrets et supprimer les comptes de service inutilisés. Propriétaire : Aisha Patel, ingénieure sécurité.

### Audit mensuel (équipe de sécurité)

- [ ] Auditer toutes les règles du journal d'audit pour leur exhaustivité et les ajuster si nécessaire.
- [ ] Effectuer un exercice simulé de fuite de Secret pour tester la réponse aux incidents.
- [ ] Faire tourner tous les Secrets statiques de plus de 90 jours.
- [ ] Évaluer l'intégration d'une gestion externe des secrets (par exemple, Vault, AWS Secrets Manager) si elle n'est pas déjà utilisée.

## Pièges courants et comment les éviter

### Piège 1 : Journaliser les valeurs des Secrets

**Pourquoi cela arrive** : Les développeurs utilisent `kubectl get secret -o yaml` pour le débogage et la sortie est capturée dans les journaux ou la sortie CI.

**Comment l'éviter** : N'utilisez jamais `-o yaml` sur les Secrets. Utilisez `kubectl get secret <name> -o jsonpath='{.data}'` pour lister uniquement les clés. Masquez les secrets dans les journaux et configurez les systèmes CI pour masquer les valeurs sensibles.

### Piège 2 : Supposer que les mises à jour des Secrets se propagent instantanément

**Pourquoi cela arrive** : Les équipes font tourner un Secret et s'attendent à ce que tous les pods utilisent la nouvelle valeur immédiatement. Cependant, les Secrets montés ne sont mis à jour que périodiquement par le kubelet (si vous utilisez des variables d'environnement, ils ne sont jamais mis à jour).

**Comment l'éviter** : Considérez les mises à jour de Secrets comme nécessitant un redémarrage du pod. Utilisez un déploiement ou un outil comme Reloader pour automatiser les redémarrages.

### Piège 3 : Ne pas surveiller les accès non autorisés

**Pourquoi cela arrive** : La surveillance se concentre sur la santé des pods mais pas sur les journaux d'audit du serveur API, donc quelqu'un peut exfiltrer des Secrets sans être remarqué.

**Comment l'éviter** : Activez la journalisation d'audit avec le niveau `Metadata` pour les Secrets, et configurez des alertes pour les modèles d'accès inhabituels (par exemple, un utilisateur accédant à de nombreux Secrets en peu de temps).

### Piège 4 : RBAC trop large

**Pourquoi cela arrive** : Pour simplifier, les équipes accordent `get` et `list` sur tous les Secrets à de nombreux comptes de service.

**Comment l'éviter** : Utilisez le moindre privilège. N'accordez l'accès en lecture aux Secrets qu'aux composants qui en ont absolument besoin. Utilisez des comptes de service distincts par application et évitez les permissions de lecture à l'échelle du cluster.

### Piège 5 : Fatigue des alertes

**Pourquoi cela arrive** : Les alertes sont trop bruyantes, comme alerter à chaque création de Secret, ce qui pousse les équipes à les ignorer.

**Comment l'éviter** : Ajustez les seuils d'alerte en fonction du comportement normal. Utilisez des clauses `for` pour exiger que la condition persiste, et distinguez entre gravité d'avertissement et critique.

## Conclusion

La surveillance des Secrets Kubernetes est essentielle pour la sécurité et la fiabilité. Elle nécessite une combinaison de journalisation d'audit, de métriques, d'alertes et de tableaux de bord, le tout enveloppé dans un processus opérationnel sûr. Commencez par des observations en lecture seule, mettez en œuvre des alertes progressivement et protégez toujours les valeurs des secrets contre toute exposition.

En suivant les étapes pratiques de ce guide, vous pouvez détecter les défaillances, les accès non autorisés et la dérive de configuration avant qu'ils ne causent des incidents. Attribuez clairement la propriété des tâches de surveillance et révisez-les régulièrement pour maintenir l'efficacité du système. Utilisez la liste de contrôle des opérations pour vous assurer que rien n'est manqué, et affinez continuellement vos alertes au fur et à mesure que votre cluster grandit.

## Derniers mots

La surveillance des Secrets Kubernetes n'a pas besoin d'être complexe. Commencez par les bases : connaissez votre environnement, activez les journaux d'audit, configurez Prometheus et Grafana, et créez quelques alertes significatives. À mesure que votre confiance grandit, étendez-vous à la rotation automatisée et à la gestion externe des secrets. La clé est de faire de la surveillance une habitude, pas une réflexion après coup.