Composants
Audience: Opérateur de plateforme
vault-db-injector s'exécute sous la forme de quatre composants coopérants. Ils
partagent le même binaire Go et sélectionnent leur rôle au démarrage via la
clé de configuration mode.
Injector (webhook)
Fichier : pkg/injector/injector.go
L'injector s'exécute en tant que Deployment et expose un Mutating Admission
Webhook Kubernetes en TLS. Lorsqu'un pod portant le label
vault-db-injector: "true" est admis, le webhook lit les annotations
db-creds-injector.numberly.io/* et détermine ce qu'il faut injecter dans
les variables d'environnement du pod.
En mode legacy, le webhook appelle CanIGetRoles contre Vault pour vérifier
que le ServiceAccount du pod est associé au rôle DB demandé, émet un token
orphelin Vault portant la politique du rôle, récupère les identifiants
dynamiques, et les écrit en clair dans les variables d'environnement du spec
du conteneur.
En mode NRI (auth projected), le webhook ne récupère pas les identifiants.
Il écrit des placeholders opaques __VDBI_PH_<64hex>___ dans les variables
d'environnement — une paire par dbConfig — et inscrit un UUID par dbConfig dans
l'annotation db-creds-injector.numberly.io/uuid pour corrélation ultérieure.
CanIGetRoles est ignoré car Vault atteste l'identité du pod nativement au
moment du pod-token.
Plugin NRI (DaemonSet)
Fichiers : pkg/nri/...
Le plugin NRI s'exécute en tant que DaemonSet sur chaque nœud, montant
/var/run/nri/nri.sock depuis l'hôte. Il s'enregistre comme plugin NRI auprès
de containerd ou CRI-O. À chaque événement CreateContainer, il filtre par
label de pod, analyse les variables d'environnement à la recherche de
placeholders, et en cas de correspondance récupère l'identité du pod depuis
le kube-apiserver, se connecte à Vault en tant que ce pod (mode projected) ou
en son propre nom (mode legacy), émet les identifiants, et envoie un
ContainerAdjustment pour que runc démarre le conteneur avec les vraies
variables d'environnement.
Un cache tmpfs par nœud à /run/<release-fullname>/nri/cache.json conserve
les identifiants déchiffrés entre les redémarrages du plugin, de sorte qu'un
CrashLoop ne nécessite pas de réémettre les identifiants à chaque tentative.
Le cache est effacé au redémarrage du nœud.
Renewer (Deployment)
Fichier : pkg/renewer/renewer.go
Le renewer s'exécute en tant que Deployment avec élection de leader. Toutes les
5 minutes (configurable via SyncTTLSecond), le leader parcourt le mont de
bookkeeping KV, appelle auth/token/renew sur chaque token stocké et
sys/leases/renew sur chaque bail stocké. En mode projected-SA, le renewer
détient une politique Vault minimale : renew uniquement, sans revoke ni
suppression KV. La révocation est gérée exclusivement par le revoker.
Revoker (Deployment)
Fichier : pkg/revoker/revoker.go
Le revoker s'exécute en tant que Deployment avec élection de leader. Le leader
surveille l'API Kubernetes pour les événements DELETE de pods filtrés par le
label vault-db-injector: "true". À la suppression, il révoque le token et le
bail du pod, puis efface l'entrée KV. Un balayage périodique de filet de
sécurité toutes les 5 minutes (safetyNetSync) rattrape les pods décédés
pendant que le watch était déconnecté ou que le revoker était arrêté.
En mode projected-SA, le revoker est l'unique responsable de la révocation :
le renewer ne touche plus auth/token/revoke-orphan ni la delete KV.
Élection de leader
Le renewer et le revoker s'exécutent en mode multi-réplica pour la haute
disponibilité. Seul le leader élu effectue le travail ; les autres attendent.
Le webhook (injector) est sans état — toutes les réplicas traitent les appels
d'admission en parallèle sans coordination. Voir operations
pour les mécanismes et la métrique vdbi_is_leader.