> ## Documentation Index
> Fetch the complete documentation index at: https://docs.befailproof.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 단일 Pod 배포: EKS에서 Collector + Application Sidecar

> AgentEye 단일 Pod 배포: EKS에서 Collector + Application Sidecar 문서.

애플리케이션과 AgentEye 컬렉터를 **동일한 Kubernetes Pod 내**에서 실행하면 텔레메트리 수집 시 네트워크 경계를 절대 통과하지 않습니다. 애플리케이션의 SDK와 컬렉터는 단일 Pod 내 이벤트 스풀을 공유하므로, localhost 포트를 노출할 필요도 없고, 서비스 메시를 통과할 필요도 없으며, 컬렉터의 라이프사이클이 관찰 대상 워크로드에 직접 연결된 상태에서 저지연 인프로세스 텔레메트리 핸드오프가 가능합니다. 컬렉터가 제시하는 mTLS 클라이언트 인증서는 AWS Secrets Manager에서 직접 Pod로 전달되므로, 자격 증명 갱신 시 파일을 수동으로 조작할 필요가 없습니다.

여기서 설명하는 sidecar + 공유 스풀 모델은 클라우드에 종속되지 않습니다. `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](/ko/agenteye/kubernetes-deployment)를 참조하세요.

***

## 개요

```
┌──────────────────────────────── Pod ─────────────────────────────────┐
│                                                                      │
│   ┌──────────────────────┐              ┌──────────────────────┐     │
│   │ your-app             │              │ agenteye-collector   │     │
│   │ (SDK writes JSONL)   │              │ (sweeps events/,     │     │
│   │                      │              │  uploads over mTLS)  │     │
│   └──────────┬───────────┘              └──────────┬───────────┘     │
│              │ writes                        reads │                 │
│              ▼                                     ▼                 │
│     ┌────────────────────────────────────────────────────┐           │
│     │  emptyDir: /var/lib/agenteye/{events,failed}/      │           │
│     │  (AGENTEYE_HOME - shared event spool)              │           │
│     └────────────────────────────────────────────────────┘           │
│                                                   ▲                  │
│                                                   │ reads cert       │
│                                          ┌────────┴─────────┐        │
│                                          │ CSI (read-only): │        │
│                                          │ /etc/agenteye/   │        │
│                                          │ tls/client.{crt, │        │
│                                          │   key}, ca.crt   │        │
│                                          └────────┬─────────┘        │
└───────────────────────────────────────────────────┼──────────────────┘
                                                    │ mounted by
                                                    │ Secrets Store CSI
                                                    │ (AWS provider +
                                                    │ IRSA)
                                           ┌────────┴──────────┐
                                           │ AWS Secrets       │
                                           │ Manager           │
                                           │ agenteye/mtls-    │
                                           │ client/<cluster>  │
                                           └────────┬──────────┘
                                                    ▲
                                                    │ push on issue /
                                                    │ renewal
                                           ┌────────┴──────────┐
                                           │ Exosphere         │
                                           │ delivers the cert │
                                           │ bundle into your  │
                                           │ Secrets Manager   │
                                           │ on renewal        │
                                           └───────────────────┘

Outbound: collector → AGENTEYE_URL (mTLS, using the CSI-mounted cert).
```

두 가지 데이터 흐름, 두 가지 볼륨:

* **이벤트 (인 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 클러스터. 다음으로 확인하세요:

  ```bash theme={null}
  aws eks describe-cluster --name <your-cluster> \
    --query "cluster.identity.oidc.issuer" --output text
  ```

  명령이 `https://oidc.eks.…` URL을 반환하면 OIDC가 활성화된 것입니다. 그렇지 않다면 다음과 같이 연결하세요:

  ```bash theme={null}
  eksctl utils associate-iam-oidc-provider \
    --cluster <your-cluster> --approve
  ```

* 클러스터에 [Secrets Store CSI Driver](https://secrets-store-csi-driver.sigs.k8s.io/)와 [AWS 공급자](https://github.com/aws/secrets-store-csi-driver-provider-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](/ko/agenteye/api-keys) 참조)

***

## 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>`                                                |

갱신 시 동일한 시크릿이 새 버전으로 업데이트되므로 ARN과 이름은 절대 변경되지 않습니다. `SecretProviderClass`와 IAM 정책은 변경 없이 계속 작동합니다. 인증서 라이프사이클(유효 기간, 갱신 주기, 만료 알림)에 대해서는 [enterprise-docs/kubernetes-deployment.md](/ko/agenteye/kubernetes-deployment)를 참조하세요.

***

## Phase 2: Secrets Store CSI Driver + AWS 공급자 설치

이미 CSI를 통해 AWS 시크릿을 마운트하는 다른 워크로드를 실행 중이라면 이 단계를 건너뛰세요.

```bash theme={null}
# CSI Driver
helm repo add secrets-store-csi-driver \
  https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts
helm install -n kube-system csi-secrets-store \
  secrets-store-csi-driver/secrets-store-csi-driver \
  --set syncSecret.enabled=true \
  --set enableSecretRotation=true \
  --set rotationPollInterval=1h

# AWS provider
kubectl apply -f \
  https://raw.githubusercontent.com/aws/secrets-store-csi-driver-provider-aws/main/deployment/aws-provider-installer.yaml
```

**확인:**

```bash theme={null}
kubectl get pods -n kube-system | grep -E 'csi-secrets-store|aws-provider'
```

예상 결과: 모든 Pod에서 `Running` 상태.

> **`rotationPollInterval=1h`를 사용하는 이유?** Exosphere가 갱신된 인증서를 게시하면 Secrets Manager가 현재 위치에서 업데이트됩니다. CSI Driver는 이 간격으로 시크릿을 다시 읽고 마운트된 파일을 다시 씁니다. 컬렉터는 시작 시 인증서 파일을 한 번만 읽으므로, 프로세스가 재시작된 후에야 갱신된 인증서를 제시하기 시작합니다. 재시작 방법은 § 인증서 갱신을 참조하세요.

***

## Phase 3: Pod에 시크릿 읽기 권한 부여 (IRSA)

### 3.1 IAM 정책 생성

`agenteye-mtls-reader-policy.json`으로 저장:

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadAgentEyeMtlsBundle",
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue",
        "secretsmanager:DescribeSecret"
      ],
      "Resource": "arn:aws:secretsmanager:<region>:<account-id>:secret:agenteye/mtls-client/<cluster-name>-*"
    }
  ]
}
```

`<region>`, `<account-id>`, `<cluster-name>`을 실제 값으로 대체하세요. 끝의 `-*`는 AWS가 모든 시크릿 ARN에 추가하는 6자리 임의 접미사와 일치합니다.

정책 생성:

```bash theme={null}
aws iam create-policy \
  --policy-name AgentEyeMtlsReader-<cluster-name> \
  --policy-document file://agenteye-mtls-reader-policy.json
```

### 3.2 IAM 역할 생성 및 Pod의 ServiceAccount에 바인딩

```bash theme={null}
eksctl create iamserviceaccount \
  --name agenteye-pod \
  --namespace <your-namespace> \
  --cluster <your-cluster> \
  --role-name AgentEyePodRole-<cluster-name> \
  --attach-policy-arn arn:aws:iam::<account-id>:policy/AgentEyeMtlsReader-<cluster-name> \
  --approve
```

이 명령은 새 역할을 가리키는 `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`을 호출합니다. |

Pod에 `secretsmanager:PutSecretValue`, `secretsmanager:UpdateSecret`, `secretsmanager:DeleteSecret`을 **절대 부여하지 마세요**. Pod는 시크릿을 읽기만 하며, 새 버전 작성은 인증서 발급 또는 갱신 시 Exosphere가 처리합니다.

시크릿이 기본 `aws/secretsmanager` 키가 아닌 고객 관리형 KMS 키로 암호화된 경우, 다음도 추가로 부여하세요:

```json theme={null}
{
  "Effect": "Allow",
  "Action": ["kms:Decrypt"],
  "Resource": "arn:aws:kms:<region>:<acct>:key/<key-id>",
  "Condition": {
    "StringEquals": {
      "kms:ViaService": "secretsmanager.<region>.amazonaws.com"
    }
  }
}
```

***

## Phase 4: Pod 배포

### 4.1 SecretProviderClass

`agenteye-mtls-spc.yaml`:

```yaml theme={null}
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: agenteye-mtls
  namespace: <your-namespace>
spec:
  provider: aws
  parameters:
    objects: |
      - objectName: "agenteye/mtls-client/<cluster-name>"
        objectType: "secretsmanager"
        jmesPath:
          - path: '"client.crt"'
            objectAlias: "client.crt"
          - path: '"client.key"'
            objectAlias: "client.key"
          - path: '"ca.crt"'
            objectAlias: "ca.crt"
```

`jmesPath` 블록은 AWS 공급자에게 JSON 시크릿을 디스크의 세 개의 개별 파일로 분할하도록 지시합니다. `'"client.crt"'`의 따옴표 처리는 JMESPath가 `.`을 하위 표현식 연산자로 처리하기 때문에 필요합니다.

```bash theme={null}
kubectl apply -f agenteye-mtls-spc.yaml
```

### 4.2 Pod / Deployment 매니페스트

**두 컨테이너의 통신 방식.** AgentEye SDK와 컬렉터는 네트워크 소켓으로 통신하지 않으며, 로컬 HTTP 포트도 없습니다. SDK는 이벤트 배치를 `$AGENTEYE_HOME/events/`에 `.jsonl` 파일로 작성하고, 컬렉터는 해당 디렉토리를 지속적으로 감시하여 각 파일을 업로드합니다. sidecar Pod의 경우:

* 두 컨테이너 모두 **동일한** `emptyDir` 볼륨을 **동일한** 경로에 마운트합니다.
* 두 컨테이너 모두 `AGENTEYE_HOME`을 해당 경로로 설정합니다.
* 애플리케이션 이미지에 AgentEye SDK가 설치 및 구성되어 있어야 합니다 ([enterprise-docs/python-sdk.md](/ko/agenteye/python-sdk) 참조).

> `AGENTEYE_HOME`이 설정되지 않으면 SDK와 컬렉터 모두 기본값인 `~/.agenteye`를 사용하는데, 두 컨테이너의 홈 디렉토리가 다르기 때문에 서로 다른 스풀을 사용하게 되어 핸드오프가 자동으로 실패합니다. **두** 컨테이너 모두에 `AGENTEYE_HOME`을 동일한 명시적 경로로 설정하세요. §4.3 검증 단계와 해당 문제 해결 항목에서 이를 놓쳤을 경우 잡아낼 수 있습니다.

`agenteye-pod.yaml` (복제본 1개의 Deployment, 필요에 따라 확장):

```yaml theme={null}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-with-collector
  namespace: <your-namespace>
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app-with-collector
  template:
    metadata:
      labels:
        app: my-app-with-collector
    spec:
      serviceAccountName: agenteye-pod
      containers:
        - name: app
          image: <your-app-image>
          env:
            # SDK writes event JSONL files into $AGENTEYE_HOME/events/
            - name: AGENTEYE_HOME
              value: /var/lib/agenteye
          volumeMounts:
            - name: agenteye-spool
              mountPath: /var/lib/agenteye

        - name: agenteye-collector
          # Pin to a versioned :v<version> tag for production; :beta-latest
          # tracks the current beta build (:latest exists only for stable releases).
          image: ghcr.io/agenteye-enterprise/collector:beta-latest
          args: ["start"]
          env:
            # Must match the app container's AGENTEYE_HOME so the collector
            # sweeps the same directory the SDK writes to.
            - name: AGENTEYE_HOME
              value: /var/lib/agenteye
            - name: AGENTEYE_URL
              value: "https://ingest.example.agenteye.com/events"
            - name: AGENTEYE_KEY
              valueFrom:
                secretKeyRef:
                  name: agenteye-collector-api-key
                  key: key
            - name: AGENTEYE_TLS_CERT
              value: /etc/agenteye/tls/client.crt
            - name: AGENTEYE_TLS_KEY
              value: /etc/agenteye/tls/client.key
            # Only when the AgentEye server presents a cert not signed by a
            # publicly-trusted CA (e.g. self-signed by an in-cluster issuer
            # because you have no real DNS domain). The CSI mount already
            # exposes ca.crt alongside the client cert/key.
            - name: AGENTEYE_TLS_CA
              value: /etc/agenteye/tls/ca.crt
          volumeMounts:
            - name: agenteye-spool
              mountPath: /var/lib/agenteye
            - name: agenteye-mtls
              mountPath: /etc/agenteye/tls
              readOnly: true
          livenessProbe:
            exec:
              command: ["agenteye-collector", "health"]
            initialDelaySeconds: 10
            periodSeconds: 30

      volumes:
        # Shared event spool between app and collector. emptyDir is fine:
        # events are transient and the collector drains them before pod
        # termination on graceful shutdown.
        - name: agenteye-spool
          emptyDir: {}
        # mTLS cert bundle, mounted read-only into the collector only.
        - name: agenteye-mtls
          csi:
            driver: secrets-store.csi.k8s.io
            readOnly: true
            volumeAttributes:
              secretProviderClass: agenteye-mtls
```

`agenteye-collector-api-key` 시크릿에는 컬렉터의 API 키가 담겨 있습니다 (프로비저닝 방법은 [enterprise-docs/api-keys.md](/ko/agenteye/api-keys) 참조).

**적용:**

```bash theme={null}
kubectl apply -f agenteye-pod.yaml
```

### 4.3 확인

```bash theme={null}
# Pod가 2/2 컨테이너 준비 완료 상태로 Running이어야 함
kubectl get pods -n <your-namespace> -l app=my-app-with-collector

# 인증서 번들이 마운트되었는지 확인
kubectl exec -n <your-namespace> deploy/my-app-with-collector \
  -c agenteye-collector -- ls -l /etc/agenteye/tls/
```

예상 결과: `client.crt`, `client.key`, `ca.crt` 모두 존재하며, 읽기 전용으로 컨테이너 사용자 소유.

**공유 이벤트 스풀이 두 컨테이너에서 보이는지 확인:**

```bash theme={null}
# 컬렉터에서, 시작 시 컬렉터가 자동 생성하는 events/ 및 failed/ 하위 디렉토리가 보여야 함:
kubectl exec -n <your-namespace> deploy/my-app-with-collector \
  -c agenteye-collector -- ls /var/lib/agenteye/

# 앱에서, 동일한 디렉토리 내용이 보여야 함:
kubectl exec -n <your-namespace> deploy/my-app-with-collector \
  -c app -- ls /var/lib/agenteye/
```

두 목록이 다르다면, 볼륨이 두 컨테이너에 모두 마운트되지 않았거나 (`AGENTEYE_HOME`이 다른 경우) 문제가 있는 것입니다. § 문제 해결을 참조하세요.

**엔드투엔드 스모크 테스트:**

```bash theme={null}
kubectl exec -n <your-namespace> deploy/my-app-with-collector \
  -c agenteye-collector -- agenteye-collector flush
```

예상 결과: 컬렉터가 대기 중인 이벤트를 업로드하고 `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 내 흐름은 다음과 같습니다:

1. Secrets Manager의 시크릿이 새 `AWSCURRENT` 버전을 얻습니다. ARN과 이름은 변경되지 않습니다.
2. `rotationPollInterval` (기본값 1h; § Phase 2 참조) 이내에 CSI Driver가 새 버전을 읽고 `/etc/agenteye/tls/` 아래의 파일을 다시 씁니다.
3. 컬렉터는 시작 시 **한 번** 인증서 파일을 로드하므로, 프로세스가 재시작될 때까지 이전 인증서를 계속 제시합니다. 갱신된 자료로 전환하려면 컬렉터를 재시작하세요. 롤링 재시작으로 충분합니다:

   ```bash theme={null}
   kubectl rollout restart deploy/my-app-with-collector -n <your-namespace>
   ```

   이를 자동화하려면 `/etc/agenteye/tls/`를 감시하는 사이드카를 추가하고 (예: `inotifywait` 사용), 파일이 변경될 때 롤아웃을 트리거하도록 하세요.

이전 인증서는 갱신 후 약 15일 동안 유효하므로, 중단 없이 재시작을 수행할 수 있는 넉넉한 시간이 있습니다. Exosphere가 갱신된 번들을 게시하며, 귀하 측의 유일한 정기 작업은 해당 기간 내에 컬렉터가 재시작되도록 보장하는 것입니다.

***

## 문제 해결

| 증상                                                                                              | 가능한 원인                                                                | 해결 방법                                                                                                                                                                    |
| ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 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/` 확인을 실행하세요. 목록이 일치해야 합니다. |

**먼저 수집할 로그:**

```bash theme={null}
kubectl logs -n kube-system -l app=secrets-store-csi-driver --tail=100
kubectl logs -n kube-system -l app=csi-secrets-store-provider-aws --tail=100
kubectl describe pod -n <your-namespace> -l app=my-app-with-collector
```

***

## 참조: 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 서버 인증서가 공개적으로 신뢰되지 않는 경우에만) |

세 파일 모두 읽기 전용으로 마운트되며 컨테이너 사용자 소유입니다. 시크릿이 갱신될 때 CSI Driver에 의해 다시 씁니다.

### 이벤트 스풀: `$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](/ko/agenteye/collector-installation): 컬렉터 바이너리 옵션, mTLS 구성 참조, 데몬 모드.
* [enterprise-docs/kubernetes-deployment.md](/ko/agenteye/kubernetes-deployment): 멀티 Pod 배포, 인증서 발급 내부 구조, 라이프사이클 및 만료 알림.
* [enterprise-docs/api-keys.md](/ko/agenteye/api-keys): Pod에서 사용하는 컬렉터 API 키 프로비저닝.
* [enterprise-docs/troubleshooting.md](/ko/agenteye/troubleshooting): 클러스터 전체 문제 해결 인덱스.
