Gestión de Secretos en Contenedores con Vault

Las credenciales de bases de datos, claves de API y tokens de autenticación son activos críticos. Kubernetes Secrets almacena estos secretos en etcd en texto plano (a menos que se configure EncryptionConfiguration) y, en la práctica, suelen terminar sin cifrar en repositorios Git (GitOps). Para sistemas estadísticos que manejan datos sensibles, confiar solo en Kubernetes Secrets es insuficiente.

HashiCorp Vault resuelve estas limitaciones: centraliza la gestión, cifra los secretos en reposo y en tránsito, y permite inyectarlos en contenedores sin exponerlos en variables de entorno. Este artículo compara los dos métodos principales de integración con Kubernetes; Vault Agent Injector (sidecar) y CSI Driver, proporcionan ejemplos prácticos y una guía de selección adaptada a proyectos de software estadístico y MLOps.

Diagrama de flujo: Inyección de secretos con Vault Agent Injector

Diagrama de flujo: CSI Driver (montaje directo)

1. Los dos métodos de integración: Agent Injector vs. CSI Driver

Vault ofrece dos enfoques para inyectar secretos en pods, manteniéndolos fuera de etcd. Ambos son seguros, pero tienen arquitecturas y casos de uso distintos.

1.1 Vault Agent Injector (Sidecar)

Un webhook mutador intercepta la creación de pods y, según anotaciones, inyecta dos contenedores auxiliares:

  • vault-agent-init: autentica el pod contra Vault y precarga los secretos antes de que arranque la aplicación.
  • vault-agent: sidecar que renueva automáticamente los leases de los secretos.
  • Los secretos se escriben en un volumen de memoria compartida (/vault/secrets). La aplicación solo lee archivos de esa ruta.
FaseDescripción
1. InterceptaciónEl webhook captura el evento de creación del pod.
2. Inyección de Init ContainerSe añade vault-agent-init que autentica y precarga secretos.
3. Inyección de SidecarSe añade vault-agent que renueva leases continuamente.
4. Montaje de Volumen CompartidoTodos los contenedores montan un emptyDir en /vault/secrets.

Mapa conceptual comparativo: Agent Injector vs CSI Driver

Instalación y configuración básica

bash

Verificar el injector:

bash

Configuración del Auth Method de Kubernetes:

bash

Política de Vault (ejemplo para acceso a secretos de base de datos):

hcl

Rol que vincula la ServiceAccount con la política:

bash

Ejemplo práctico: pod con inyección de secretos

yaml

La aplicación lee las credenciales desde /vault/secrets/db-creds tras ejecutar source. No necesita conocer la API de Vault.

1.2 CSI Driver (Container Storage Interface)

El CSI Driver monta secretos como volúmenes efímeros directamente desde Vault hacia el pod, sin contenedores sidecar.

Instalación

bash

Definir un SecretProviderClass

yaml

Montar el volumen en el pod

yaml

Los secretos aparecen como archivos individuales (ej. /mnt/secrets-store/db-username).

1.3 Comparativa y guía de selección

CriterioAgent Injector (Sidecar)CSI Driver
Complejidad operativaMedia (sidecars adicionales)Baja (solo montaje de volumen)
Renovación automática de secretosSí, continuaLimitada (requiere reinicio del pod)
Compatibilidad con aplicaciones existentesAlta (lee archivos)Alta (lee archivos)
Huella de recursosMayor (uno o dos contenedores extra por pod)Menor (driver a nivel de nodo)
Casos de uso recomendadosSecretos dinámicos con rotación frecuente; apps que no pueden reiniciarseSecretos estáticos o rotación poco frecuente; clústeres con muchos pods

Recomendación para software estadístico: El Vault Agent Injector es preferible para modelos en producción, pipelines de entrenamiento y servicios de inferencia real‑time, porque renueva leases automáticamente sin reiniciar los pods. El CSI Driver es más ligero para trabajos batch (ETL, entrenamientos cortos).

En cualquier caso, nunca almacene secretos en texto plano en el código fuente ni en variables de entorno inseguras.

2. Gestión de secretos en entornos de desarrollo local

Para pruebas locales sin un clúster Kubernetes, puede ejecutar Vault en modo dev o usar variables de entorno para secretos de baja criticidad. Ejemplo con docker-compose:

yaml

Luego configure su aplicación para leer secretos desde Vault (usando la API REST o el agente local) solo en desarrollo. En producción, use el injector.

3. Integración con el flujo de trabajo de MLOps

En un pipeline de MLOps, múltiples etapas requieren secretos:

Flujo de integración con MLOps (GitHub Actions + Vault OIDC)

EtapaEjemplo de secreto
Ingesta de datosClaves de API para fuentes externas (financieras, gubernamentales), credenciales de bases de datos.
EntrenamientoTokens de MLflow, credenciales para GPUs en la nube, claves de almacenamiento (S3).
DespliegueClaves de API del modelo, tokens de service mesh.

Cada pod se inyecta solo los secretos que necesita (mínimo privilegio). Ejemplo de anotaciones para múltiples secretos:

yaml

Para pipelines CI/CD (GitHub Actions), puede autenticarse con Vault mediante OIDC sin almacenar tokens largos:

yaml

El secreto se obtiene como variable de entorno temporal dentro del job.

4. Mejores prácticas y checklist de seguridad

PrácticaDescripción
ServiceAccounts dedicadasCada aplicación tiene su propia cuenta de servicio de Kubernetes, con un rol de Vault independiente y una política que concede acceso solo a los secretos que necesita. Previene propagación lateral.
TLS/mTLSConfigurar TLS para todas las comunicaciones entre los pods y Vault. Usar mTLS cuando sea posible.
Auditoría de accesoVault logs todas las operaciones (quién accedió a qué secreto, cuándo y desde qué pod). Integre estos logs con su sistema de monitoreo (SIEM, bucket centralizado).
Rotación automáticaConfigure políticas de rotación (ej. cada 30 días). El Agent Injector renueva leases sin reiniciar las aplicaciones.
No almacenar secretos en imágenesLas imágenes Docker nunca deben contener secretos. Inyecte siempre en tiempo de ejecución.
Alta disponibilidadEn producción, despliegue Vault en modo HA con al menos 3 réplicas y almacenamiento persistente (Raft, Consul).
Monitoreo de saludHealth checks periódicos sobre la API de Vault. Alertas cuando el servidor esté sealed o no responda.

Checklist rápido

  • ¿Los secretos se inyectan mediante Vault, no están hardcodeados ni en variables de entorno?

  • ¿Cada aplicación tiene su propia ServiceAccount y rol Vault con políticas específicas?

  • ¿Se ha habilitado TLS/mTLS entre Vault y los pods?

  • ¿Los logs de acceso a secretos se envían a un sistema centralizado (ELK, SIEM)?

  • ¿Está configurada la rotación automática de credenciales?

  • ¿Vault está en modo HA con almacenamiento persistente?

  • ¿Se han probado health checks y alertas de sellado?

Referencias

Documentos relacionados