emptyDir funciona en cualquier distribución de Kubernetes. Solo la ruta de entrega de certificados de esta guía (AWS Secrets Manager + el Secrets Store CSI Driver + IRSA) es específica de AWS / EKS. Si ejecutas en otro entorno, mantén la distribución del pod y el spool y sustituye el mecanismo de montaje de secretos de tu plataforma para las Fases 2 y 3.
Cuándo usar este patrón. Elige el pod único cuando tu aplicación no deba llamar a través de un límite de red para alcanzar el colector (IPC en pod de baja latencia, acoplamiento estrecho del ciclo de vida, aislamiento de pod por tenant). Para flotas multi-aplicación que comparten un colector por nodo o por clúster, consulta enterprise-docs/kubernetes-deployment.md en su lugar.
Resumen
- Eventos (en el pod): el SDK de tu aplicación escribe archivos
.jsonlen elemptyDircompartido en$AGENTEYE_HOME/events/; el sweeper del colector los lee y los sube. Sin puerto localhost, sin loopback, transferencia pura mediante sistema de archivos compartido. - Certificado mTLS (pod ← nube): el Secrets Store CSI Driver monta el bundle de certificados desde Secrets Manager en un volumen de solo lectura en
/etc/agenteye/tls/, con alcance al contenedor del colector.
| Parte | Responsabilidad |
|---|---|
| Exosphere | Emite el certificado de cliente mTLS y entrega el bundle en el Secrets Manager de tu cuenta de AWS bajo un nombre estable. Vuelve a publicar el bundle renovado en el mismo secreto antes de su expiración. |
| Tú | Instala el Secrets Store CSI Driver, otorga al ServiceAccount del pod acceso de lectura al secreto vía IRSA, y aplica el manifiesto del Pod. Eso es todo. |
Prerequisitos
En tu cuenta de AWS / clúster de EKS
-
Un clúster de EKS con un proveedor OIDC asociado. Verifica con:
Si el comando devuelve una URL
https://oidc.eks.…, OIDC está habilitado. Si no, asocia uno: - El Secrets Store CSI Driver y el proveedor de AWS instalados en el clúster (ver § Fase 2).
-
AWS CLI v2 y
kubectlen tu estación de trabajo.
Coordinación con Exosphere
Antes de desplegar, Exosphere entrega el bundle de cliente mTLS en el Secrets Manager de tu cuenta de AWS y proporciona:- El nombre del secreto (convención:
agenteye/mtls-client/<your-cluster>) - La región de AWS donde vive el secreto
- La URL del backend de AgentEye para configurar el colector
- Tu API key del colector (ver enterprise-docs/api-keys.md)
Fase 1: Lo que entrega Exosphere
No generas el certificado de cliente mTLS tú mismo. Exosphere lo emite y entrega el bundle directamente en el Secrets Manager de tu cuenta de AWS, de modo que el único material de credenciales que llega a tu entorno es el secreto terminado y listo para montar. Lo que llega a tu cuenta:| Propiedad | Valor |
|---|---|
| Nombre del secreto | agenteye/mtls-client/<cluster-name> (estable entre renovaciones) |
| Región | La región de AWS que designaste para tu clúster de EKS |
| Contenido | Un único secreto JSON con tres claves (client.crt, client.key y ca.crt), cada una con el material codificado en PEM |
| Etiqueta | AgentEyeCluster=<cluster-name> |
SecretProviderClass y la política de IAM siguen funcionando sin modificaciones. Para el ciclo de vida del certificado (validez, cadencia de renovación, alertas de expiración), consulta enterprise-docs/kubernetes-deployment.md.
Fase 2: Instalar el Secrets Store CSI Driver + proveedor de AWS
Omite este paso si ya ejecutas otra carga de trabajo que monta secretos de AWS vía CSI.Running para todos los pods.
¿Por qué rotationPollInterval=1h? Cuando Exosphere publica un certificado renovado, Secrets Manager se actualiza en el lugar. El CSI Driver vuelve a leer el secreto en este intervalo y reescribe los archivos montados. El colector lee los archivos de certificado una vez al iniciar, por lo que comienza a presentar el certificado renovado solo tras un reinicio del proceso; consulta § Rotación de certificados para saber cómo activar uno.
Fase 3: Otorgar al pod acceso de lectura al secreto (IRSA)
3.1 Crear la política de IAM
Guarda comoagenteye-mtls-reader-policy.json:
<region>, <account-id> y <cluster-name>. El -* al final coincide con el sufijo aleatorio de seis caracteres que AWS añade a cada ARN de secreto.
Crea la política:
3.2 Crear el rol de IAM y vincularlo al ServiceAccount del pod
ServiceAccount llamado agenteye-pod con la anotación eks.amazonaws.com/role-arn apuntando al nuevo rol.
3.3 Permisos de IAM requeridos: resumen
| Permiso | Alcance | Por qué |
|---|---|---|
secretsmanager:GetSecretValue | arn:aws:secretsmanager:<region>:<acct>:secret:agenteye/mtls-client/<cluster>-* | El CSI Driver lee el bundle de certificados en cada montaje y tick de rotación. |
secretsmanager:DescribeSecret | el mismo | El CSI Driver llama a DescribeSecret para detectar cambios de versión entre sondeos. |
secretsmanager:PutSecretValue, secretsmanager:UpdateSecret ni secretsmanager:DeleteSecret al pod. El pod solo lee el secreto; escribir nuevas versiones en él es responsabilidad de Exosphere cuando se emite o renueva el certificado.
Si el secreto está cifrado con una clave KMS gestionada por el cliente (no la clave predeterminada aws/secretsmanager), también otorga:
Fase 4: Desplegar el Pod
4.1 SecretProviderClass
agenteye-mtls-spc.yaml:
jmesPath indica al proveedor de AWS que divida el secreto JSON en tres archivos separados en disco. Las comillas en '"client.crt"' son necesarias porque JMESPath trata . como operador de subexpresión.
4.2 Manifiesto del Pod / Deployment
Cómo se comunican los dos contenedores. El SDK de AgentEye y el colector no se comunican a través de un socket de red; no hay ningún puerto HTTP local. El SDK escribe lotes de eventos como archivos.jsonl en $AGENTEYE_HOME/events/, y el colector monitoriza continuamente ese directorio y sube cada archivo. Para un pod sidecar esto significa:
- Ambos contenedores montan el mismo volumen
emptyDiren la misma ruta. - Ambos contenedores configuran
AGENTEYE_HOMEcon esa ruta. - La imagen de tu aplicación debe tener el SDK de AgentEye instalado y configurado (ver enterprise-docs/python-sdk.md).
CuandoAGENTEYE_HOMEno está definido, tanto el SDK como el colector usan por defecto~/.agenteye, y los dos contenedores tienen distintos directorios home, por lo que aterrizarían en dos spools separados y la transferencia fallaría silenciosamente. EstableceAGENTEYE_HOMEen la misma ruta explícita en ambos contenedores. La verificación del §4.3 y la fila correspondiente en Solución de problemas lo detectan si se omite.
agenteye-pod.yaml (Deployment con una réplica, escala según sea necesario):
agenteye-collector-api-key contiene la API key del colector (consulta enterprise-docs/api-keys.md para el aprovisionamiento).
Aplicar:
4.3 Verificar
client.crt, client.key, ca.crt todos presentes y de solo lectura, pertenecientes al usuario del contenedor.
Confirmar que el spool de eventos compartido es visible para ambos contenedores:
AGENTEYE_HOME es diferente); consulta § Solución de problemas.
Prueba de humo de extremo a extremo:
Done: N/N uploaded, 0 failed.. Si el spool está vacío imprime No pending files. y sale sin validar nada — así que ejecuta esto solo después de que tu aplicación haya enviado al menos un evento.
Ten en cuenta que flush sale con código distinto de cero solo por fallos de configuración local: configuración faltante (sin URL/key resuelta) o un certificado TLS ilegible o malformado (consulta § Solución de problemas). Una API key incorrecta no cambia el código de salida — la subida recibe un 401, el archivo se mueve a failed/, y el comando sigue imprimiendo [FAILED] … por archivo más Done: 0/N uploaded, N failed. y sale con 0. Para detectar una key incorrecta o una subida rechazada, lee la salida Done:/[FAILED] o comprueba si hay archivos en $AGENTEYE_HOME/failed/, no el código de salida.
Rotación de certificados
El certificado de cliente tiene una validez de 90 días y se renueva automáticamente unos 15 días antes de su expiración; Exosphere publica entonces el bundle renovado en el mismo secreto de Secrets Manager. A partir de ahí, el flujo dentro del pod es:-
El secreto de Secrets Manager obtiene una nueva versión
AWSCURRENT. El ARN y el nombre no cambian. -
Dentro del
rotationPollInterval(1h por defecto; ver § Fase 2), el CSI Driver lee la nueva versión y reescribe los archivos en/etc/agenteye/tls/. -
El colector carga los archivos de certificado una vez al iniciar, por lo que sigue presentando el certificado anterior hasta que el proceso se reinicie. Para cambiar al material renovado, reinicia el colector; un reinicio progresivo es suficiente:
Para automatizar esto, añade un sidecar que monitorice
/etc/agenteye/tls/(por ejemplo coninotifywait) y active el rollout cuando los archivos cambien.
Solución de problemas
| Síntoma | Causa probable | Solución |
|---|---|---|
Pod atascado en ContainerCreating, los eventos muestran MountVolume.SetUp failed for volume "agenteye-mtls" | El proveedor CSI no puede alcanzar Secrets Manager | Verifica que IRSA esté correctamente vinculado: kubectl describe sa agenteye-pod -n <ns> muestra la anotación eks.amazonaws.com/role-arn. Revisa CloudTrail para la llamada AssumeRole. |
Error: AccessDeniedException: not authorized to perform secretsmanager:GetSecretValue | La política de IAM tiene alcance al ARN incorrecto | El sufijo del ARN del secreto es aleatorio; usa agenteye/mtls-client/<cluster>-* con el comodín, no el ARN exacto. |
Error: ParameterNotFound del proveedor de AWS | Discrepancia en el nombre del secreto entre SecretProviderClass.objects[].objectName y el secreto que entregó Exosphere | Confirma el nombre exacto con aws secretsmanager list-secrets --filters Key=tag-key,Values=AgentEyeCluster. |
Error de jmesPath, solo un archivo montado | Sintaxis JMESPath | Los puntos en las claves JSON requieren comillas dobles: '"client.crt"', no client.crt. |
El colector registra tls: bad certificate tras una renovación | El CSI Driver aún no ha sondeado la nueva versión, o el colector sigue ejecutándose con el certificado anterior que cargó al iniciar | Confirma que los archivos montados se han actualizado (ls -l /etc/agenteye/tls/), luego reinicia el colector para cargarlos: kubectl rollout restart deploy/my-app-with-collector -n <ns>. Consulta § Rotación de certificados. |
El contenedor del colector entra en bucle de reinicios con no such file or directory: /etc/agenteye/tls/client.crt | El volumen aún no está poblado en el primer inicio; la sonda de inicio es demasiado agresiva | Añade un pequeño retraso inicial o usa un init container que espere a que el archivo exista: until [ -f /etc/agenteye/tls/client.crt ]; do sleep 1; done. |
El pod CSI Driver muere con OOMKilled | Los límites de memoria predeterminados son demasiado bajos para clústeres con muchos SecretProviderClasses | Aumenta con --set linux.resources.limits.memory=200Mi en la instalación de Helm. |
La aplicación funciona correctamente, agenteye-collector flush reporta No pending files., pero el dashboard de AgentEye no muestra eventos | La aplicación y el colector no comparten el spool de eventos | Verifica que (a) ambos contenedores monten el mismo emptyDir agenteye-spool en la misma ruta, y (b) ambos configuren AGENTEYE_HOME con esa ruta. Ejecuta las dos comprobaciones ls /var/lib/agenteye/ del § 4.3; los listados deben coincidir. |
Referencia: archivos en disco en el pod
El pod tiene dos rutas de datos en disco:Bundle de certificados mTLS: /etc/agenteye/tls/ (CSI, solo lectura, exclusivo del colector)
Montado por el Secrets Store CSI Driver desde AWS Secrets Manager.
| Archivo | Contenido | Usado por el colector como |
|---|---|---|
client.crt | Certificado de cliente codificado en PEM | AGENTEYE_TLS_CERT |
client.key | Clave privada codificada en PEM | AGENTEYE_TLS_KEY |
ca.crt | Certificado CA codificado en PEM | AGENTEYE_TLS_CA (opcional, solo cuando el certificado del servidor AgentEye no es de confianza pública) |
Spool de eventos: $AGENTEYE_HOME/ (emptyDir, lectura-escritura compartida entre ambos contenedores)
Compartido mediante un volumen emptyDir llamado agenteye-spool.
| Ruta | Escrito por | Leído por | Propósito |
|---|---|---|---|
$AGENTEYE_HOME/events/*.jsonl | Aplicación (SDK de AgentEye) | Sweeper del colector | Lotes de eventos que el SDK ha enviado, en espera de subida. |
$AGENTEYE_HOME/failed/ | Colector (en caso de fallo de subida) | Tú (durante depuración) | Archivos JSONL que el colector no pudo subir tras reintentos. |
$AGENTEYE_HOME/config.json | Tú (opcional) | Colector | Archivo de configuración opcional del colector (alternativa a las variables de entorno). |
events/ como failed/ son creados automáticamente por el colector al iniciar; no se necesita ningún initContainer.
Documentación relacionada
- enterprise-docs/collector-installation.md: opciones del binario del colector, referencia de configuración mTLS, modos demonio.
- enterprise-docs/kubernetes-deployment.md: despliegue multi-pod, aspectos internos de la emisión de certificados, ciclo de vida y alertas de expiración.
- enterprise-docs/api-keys.md: aprovisionamiento de la API key del colector consumida por el pod.
- enterprise-docs/troubleshooting.md: índice de solución de problemas a nivel de clúster.

