emptyDir 이벤트 스풀을 공유하는 두 컨테이너는 모든 Kubernetes 배포판에서 동작합니다. 이 가이드에서 인증서 전달 경로(AWS Secrets Manager + Secrets Store CSI Driver + IRSA)만 AWS / EKS에 특화되어 있습니다. 다른 플랫폼을 사용한다면 Pod 및 스풀 레이아웃은 그대로 유지하고, Phase 2와 3의 시크릿 마운트 방식만 해당 플랫폼의 메커니즘으로 대체하면 됩니다.
이 패턴을 사용할 시기. 애플리케이션이 컬렉터에 도달하기 위해 네트워크 경계를 통과해서는 안 되는 경우(저지연 인 Pod IPC, 긴밀한 라이프사이클 결합, 테넌트별 Pod 격리)에 단일 Pod를 선택하세요. 노드 또는 클러스터당 하나의 컬렉터를 공유하는 다중 앱 플리트의 경우, enterprise-docs/kubernetes-deployment.md를 참조하세요.
개요
- 이벤트 (인 Pod): 앱의 SDK가
$AGENTEYE_HOME/events/의 공유emptyDir에.jsonl파일을 작성하면, 컬렉터 스위퍼가 이를 읽어 업로드합니다. localhost 포트도 없고, 루프백도 없으며, 순수한 공유 파일시스템 핸드오프입니다. - mTLS 인증서 (pod ← cloud): Secrets Store CSI Driver가 Secrets Manager의 인증서 번들을
/etc/agenteye/tls/의 읽기 전용 볼륨에 마운트하며, 컬렉터 컨테이너에만 적용됩니다.
| 주체 | 책임 |
|---|---|
| Exosphere | mTLS 클라이언트 인증서를 발급하고 번들을 귀하의 AWS 계정 Secrets Manager에 안정적인 이름으로 전달합니다. 만료 전에 갱신된 번들을 동일한 시크릿에 재발행합니다. |
| 귀하 | Secrets Store CSI Driver를 설치하고, IRSA를 통해 Pod의 ServiceAccount에 시크릿 읽기 권한을 부여하고, Pod 매니페스트를 적용합니다. 이것이 전부입니다. |
사전 요구사항
AWS 계정 / EKS 클러스터
-
OIDC 공급자가 연결된 EKS 클러스터. 다음으로 확인하세요:
명령이
https://oidc.eks.…URL을 반환하면 OIDC가 활성화된 것입니다. 그렇지 않다면 다음과 같이 연결하세요: - 클러스터에 Secrets Store CSI Driver와 AWS 공급자가 설치되어 있어야 합니다 (§ Phase 2 참조).
-
워크스테이션에 AWS CLI v2와
kubectl이 설치되어 있어야 합니다.
Exosphere와의 협의
배포 전에 Exosphere가 mTLS 클라이언트 번들을 귀하의 AWS 계정 Secrets Manager에 전달하고 다음을 제공합니다:- 시크릿 이름 (규칙:
agenteye/mtls-client/<your-cluster>) - 시크릿이 위치한 AWS 리전
- 컬렉터에 구성할 AgentEye 백엔드 URL
- 컬렉터 API 키 (enterprise-docs/api-keys.md 참조)
Phase 1: Exosphere가 전달하는 것
mTLS 클라이언트 인증서를 직접 생성하지 않아도 됩니다. Exosphere가 이를 발급하고 번들을 귀하의 AWS 계정 Secrets Manager에 직접 전달하므로, 귀하의 환경에 전달되는 자격 증명 자료는 완성되어 마운트 준비가 된 시크릿뿐입니다. 귀하의 계정에 도착하는 내용:| 속성 | 값 |
|---|---|
| 시크릿 이름 | agenteye/mtls-client/<cluster-name> (갱신 시에도 안정적으로 유지) |
| 리전 | EKS 클러스터에 지정한 AWS 리전 |
| 페이로드 | PEM 인코딩 자료를 각각 담은 세 가지 키(client.crt, client.key, ca.crt)를 포함한 단일 JSON 시크릿 |
| 태그 | AgentEyeCluster=<cluster-name> |
SecretProviderClass와 IAM 정책은 변경 없이 계속 작동합니다. 인증서 라이프사이클(유효 기간, 갱신 주기, 만료 알림)에 대해서는 enterprise-docs/kubernetes-deployment.md를 참조하세요.
Phase 2: Secrets Store CSI Driver + AWS 공급자 설치
이미 CSI를 통해 AWS 시크릿을 마운트하는 다른 워크로드를 실행 중이라면 이 단계를 건너뛰세요.Running 상태.
rotationPollInterval=1h를 사용하는 이유? Exosphere가 갱신된 인증서를 게시하면 Secrets Manager가 현재 위치에서 업데이트됩니다. CSI Driver는 이 간격으로 시크릿을 다시 읽고 마운트된 파일을 다시 씁니다. 컬렉터는 시작 시 인증서 파일을 한 번만 읽으므로, 프로세스가 재시작된 후에야 갱신된 인증서를 제시하기 시작합니다. 재시작 방법은 § 인증서 갱신을 참조하세요.
Phase 3: Pod에 시크릿 읽기 권한 부여 (IRSA)
3.1 IAM 정책 생성
agenteye-mtls-reader-policy.json으로 저장:
<region>, <account-id>, <cluster-name>을 실제 값으로 대체하세요. 끝의 -*는 AWS가 모든 시크릿 ARN에 추가하는 6자리 임의 접미사와 일치합니다.
정책 생성:
3.2 IAM 역할 생성 및 Pod의 ServiceAccount에 바인딩
eks.amazonaws.com/role-arn 어노테이션이 있는 agenteye-pod라는 이름의 ServiceAccount를 생성합니다.
3.3 필수 IAM 권한: 요약
| 권한 | 범위 | 이유 |
|---|---|---|
secretsmanager:GetSecretValue | arn:aws:secretsmanager:<region>:<acct>:secret:agenteye/mtls-client/<cluster>-* | CSI Driver가 모든 마운트 및 갱신 틱 시 인증서 번들을 읽습니다. |
secretsmanager:DescribeSecret | 동일 | CSI Driver가 폴링 간격 사이에 버전 변경을 감지하기 위해 DescribeSecret을 호출합니다. |
secretsmanager:PutSecretValue, secretsmanager:UpdateSecret, secretsmanager:DeleteSecret을 절대 부여하지 마세요. Pod는 시크릿을 읽기만 하며, 새 버전 작성은 인증서 발급 또는 갱신 시 Exosphere가 처리합니다.
시크릿이 기본 aws/secretsmanager 키가 아닌 고객 관리형 KMS 키로 암호화된 경우, 다음도 추가로 부여하세요:
Phase 4: Pod 배포
4.1 SecretProviderClass
agenteye-mtls-spc.yaml:
jmesPath 블록은 AWS 공급자에게 JSON 시크릿을 디스크의 세 개의 개별 파일로 분할하도록 지시합니다. '"client.crt"'의 따옴표 처리는 JMESPath가 .을 하위 표현식 연산자로 처리하기 때문에 필요합니다.
4.2 Pod / Deployment 매니페스트
두 컨테이너의 통신 방식. AgentEye SDK와 컬렉터는 네트워크 소켓으로 통신하지 않으며, 로컬 HTTP 포트도 없습니다. SDK는 이벤트 배치를$AGENTEYE_HOME/events/에 .jsonl 파일로 작성하고, 컬렉터는 해당 디렉토리를 지속적으로 감시하여 각 파일을 업로드합니다. sidecar Pod의 경우:
- 두 컨테이너 모두 동일한
emptyDir볼륨을 동일한 경로에 마운트합니다. - 두 컨테이너 모두
AGENTEYE_HOME을 해당 경로로 설정합니다. - 애플리케이션 이미지에 AgentEye SDK가 설치 및 구성되어 있어야 합니다 (enterprise-docs/python-sdk.md 참조).
AGENTEYE_HOME이 설정되지 않으면 SDK와 컬렉터 모두 기본값인~/.agenteye를 사용하는데, 두 컨테이너의 홈 디렉토리가 다르기 때문에 서로 다른 스풀을 사용하게 되어 핸드오프가 자동으로 실패합니다. 두 컨테이너 모두에AGENTEYE_HOME을 동일한 명시적 경로로 설정하세요. §4.3 검증 단계와 해당 문제 해결 항목에서 이를 놓쳤을 경우 잡아낼 수 있습니다.
agenteye-pod.yaml (복제본 1개의 Deployment, 필요에 따라 확장):
agenteye-collector-api-key 시크릿에는 컬렉터의 API 키가 담겨 있습니다 (프로비저닝 방법은 enterprise-docs/api-keys.md 참조).
적용:
4.3 확인
client.crt, client.key, ca.crt 모두 존재하며, 읽기 전용으로 컨테이너 사용자 소유.
공유 이벤트 스풀이 두 컨테이너에서 보이는지 확인:
AGENTEYE_HOME이 다른 경우) 문제가 있는 것입니다. § 문제 해결을 참조하세요.
엔드투엔드 스모크 테스트:
Done: N/N uploaded, 0 failed. 요약을 출력합니다. 스풀이 비어 있으면 No pending files.를 출력하고 아무것도 검증하지 않고 종료됩니다. 따라서 앱이 최소 하나의 이벤트를 플러시한 후에만 실행하세요.
flush는 로컬 설정 오류에 대해서만 0이 아닌 값으로 종료됩니다: 구성 누락(URL/키 미설정) 또는 읽을 수 없거나 파싱 불가능한 TLS 인증서 (§ 문제 해결 참조). 잘못된 API 키는 종료 코드를 변경하지 않습니다 — 업로드가 401을 받으면 파일이 failed/로 이동되고, 명령은 여전히 파일별로 [FAILED] …를 출력하고 Done: 0/N uploaded, N failed.를 출력한 후 0으로 종료됩니다. 잘못된 키나 거부된 업로드를 감지하려면 종료 코드가 아닌 Done:/[FAILED] 출력을 읽거나 $AGENTEYE_HOME/failed/에 파일이 생기는지 확인하세요.
인증서 갱신
클라이언트 인증서는 90일 동안 유효하며, 만료 약 15일 전에 자동으로 갱신됩니다. 그러면 Exosphere가 갱신된 번들을 동일한 Secrets Manager 시크릿에 게시합니다. Pod 내 흐름은 다음과 같습니다:-
Secrets Manager의 시크릿이 새
AWSCURRENT버전을 얻습니다. ARN과 이름은 변경되지 않습니다. -
rotationPollInterval(기본값 1h; § Phase 2 참조) 이내에 CSI Driver가 새 버전을 읽고/etc/agenteye/tls/아래의 파일을 다시 씁니다. -
컬렉터는 시작 시 한 번 인증서 파일을 로드하므로, 프로세스가 재시작될 때까지 이전 인증서를 계속 제시합니다. 갱신된 자료로 전환하려면 컬렉터를 재시작하세요. 롤링 재시작으로 충분합니다:
이를 자동화하려면
/etc/agenteye/tls/를 감시하는 사이드카를 추가하고 (예:inotifywait사용), 파일이 변경될 때 롤아웃을 트리거하도록 하세요.
문제 해결
| 증상 | 가능한 원인 | 해결 방법 |
|---|---|---|
Pod가 ContainerCreating에서 멈추고, 이벤트에 MountVolume.SetUp failed for volume "agenteye-mtls" 표시 | CSI 공급자가 Secrets Manager에 접근할 수 없음 | IRSA가 올바르게 바인딩되었는지 확인: kubectl describe sa agenteye-pod -n <ns>에서 eks.amazonaws.com/role-arn 어노테이션이 표시되어야 합니다. AssumeRole 호출에 대해 CloudTrail을 확인하세요. |
오류: AccessDeniedException: not authorized to perform secretsmanager:GetSecretValue | IAM 정책이 잘못된 ARN 범위로 지정됨 | 시크릿 ARN 접미사는 임의적이므로, 정확한 ARN이 아닌 와일드카드 agenteye/mtls-client/<cluster>-*를 사용하세요. |
AWS 공급자에서 ParameterNotFound 오류 | SecretProviderClass.objects[].objectName과 Exosphere가 전달한 시크릿 이름 불일치 | aws secretsmanager list-secrets --filters Key=tag-key,Values=AgentEyeCluster로 정확한 이름을 확인하세요. |
jmesPath 오류, 파일이 하나만 마운트됨 | JMESPath 구문 오류 | JSON 키의 점은 이중 따옴표가 필요합니다: client.crt가 아닌 '"client.crt"'. |
갱신 후 컬렉터 로그에 tls: bad certificate | CSI Driver가 아직 새 버전을 폴링하지 않았거나, 컬렉터가 시작 시 로드한 이전 인증서로 여전히 실행 중 | 마운트된 파일이 업데이트되었는지 확인 (ls -l /etc/agenteye/tls/)한 후 컬렉터를 재시작하여 로드: kubectl rollout restart deploy/my-app-with-collector -n <ns>. § 인증서 갱신 참조. |
컬렉터 컨테이너가 no such file or directory: /etc/agenteye/tls/client.crt로 크래시루프 | 첫 시작 시 볼륨이 아직 채워지지 않음; 스타트업 프로브가 너무 공격적 | 작은 초기 지연을 추가하거나, 파일이 존재할 때까지 기다리는 init 컨테이너를 사용하세요: until [ -f /etc/agenteye/tls/client.crt ]; do sleep 1; done. |
CSI Driver Pod가 OOMKilled | SecretProviderClass가 많은 클러스터에서 기본 메모리 한도가 너무 낮음 | Helm 설치에서 --set linux.resources.limits.memory=200Mi로 늘리세요. |
앱은 정상 실행되고, agenteye-collector flush는 No pending files.를 보고하지만, AgentEye 대시보드에 이벤트가 표시되지 않음 | 앱과 컬렉터가 이벤트 스풀을 공유하지 않음 | (a) 두 컨테이너 모두 동일한 경로에 동일한 agenteye-spool emptyDir을 마운트하고, (b) 두 컨테이너 모두 AGENTEYE_HOME을 해당 경로로 설정했는지 확인하세요. § 4.3의 두 ls /var/lib/agenteye/ 확인을 실행하세요. 목록이 일치해야 합니다. |
참조: Pod 내 디스크 파일
Pod에는 두 가지 데이터 경로가 있습니다:mTLS 인증서 번들: /etc/agenteye/tls/ (CSI, 읽기 전용, 컬렉터 전용)
AWS Secrets Manager에서 Secrets Store CSI Driver로 마운트됩니다.
| 파일 | 내용 | 컬렉터 사용 환경 변수 |
|---|---|---|
client.crt | PEM 인코딩 클라이언트 인증서 | AGENTEYE_TLS_CERT |
client.key | PEM 인코딩 개인 키 | AGENTEYE_TLS_KEY |
ca.crt | PEM 인코딩 CA 인증서 | AGENTEYE_TLS_CA (선택 사항, AgentEye 서버 인증서가 공개적으로 신뢰되지 않는 경우에만) |
이벤트 스풀: $AGENTEYE_HOME/ (emptyDir, 두 컨테이너 간 읽기-쓰기 공유)
agenteye-spool이라는 이름의 emptyDir 볼륨을 통해 공유됩니다.
| 경로 | 작성자 | 읽기 주체 | 목적 |
|---|---|---|---|
$AGENTEYE_HOME/events/*.jsonl | 앱 (AgentEye SDK) | 컬렉터 스위퍼 | SDK가 플러시한 이벤트 배치, 업로드 대기 중. |
$AGENTEYE_HOME/failed/ | 컬렉터 (업로드 실패 시) | 귀하 (디버깅 시) | 재시도 후에도 컬렉터가 업로드하지 못한 JSONL 파일. |
$AGENTEYE_HOME/config.json | 귀하 (선택 사항) | 컬렉터 | 선택적 컬렉터 구성 파일 (환경 변수 대안). |
events/와 failed/ 하위 디렉토리는 모두 컬렉터 시작 시 자동으로 생성됩니다. initContainer는 필요하지 않습니다.
관련 문서
- enterprise-docs/collector-installation.md: 컬렉터 바이너리 옵션, mTLS 구성 참조, 데몬 모드.
- enterprise-docs/kubernetes-deployment.md: 멀티 Pod 배포, 인증서 발급 내부 구조, 라이프사이클 및 만료 알림.
- enterprise-docs/api-keys.md: Pod에서 사용하는 컬렉터 API 키 프로비저닝.
- enterprise-docs/troubleshooting.md: 클러스터 전체 문제 해결 인덱스.

