- ClickHouse 24.8 — 이벤트 및 평가 분석의 기준 저장소 (100Gi 퍼시스턴트 볼륨을 가진 StatefulSet). 필수 항목: 없으면 서버가 시작되지 않습니다.
- PostgreSQL 16 — 조직, API 키, 사용자, 대시보드, 저장된 쿼리, 인증을 위한 관계형/메타데이터 저장소 (50Gi 퍼시스턴트 볼륨을 가진 StatefulSet)
- Redis 7.2 — 선택적 공유 캐시 및 속도 제한 백엔드; 사용 불가 시 서버와 대시보드는 기능이 저하된 상태로 계속 동작합니다
- AgentEye Server — 이벤트 수집, 분석, 키 관리를 위한 Rust API (2개 레플리카)
- AgentEye Dashboard — Next.js 웹 UI (2개 레플리카)
- AI 어시스턴트 (에이전트 서비스) — 포트 9100에서 제공되는 선택적 읽기 전용 대시보드 내 어시스턴트; LLM 엔드포인트가 구성되기 전까지 비활성 상태
- Traefik (공용) — 수집기 트래픽용 인그레스 컨트롤러, mTLS 보호
- Traefik (대시보드) — 대시보드용 인그레스 컨트롤러, VPN/IP 허용 목록 전용
- cert-manager — TLS 인증서 및 mTLS CA
- 백업 CronJob — 매일 UTC 03:00에 PostgreSQL + ClickHouse 통합 덤프 실행
- 인증서 갱신 모니터 — 클라이언트 인증서 만료 임박 시 알림 발송
사전 요구 사항
시작하기 전에 각 확인 명령을 실행하세요. 모든 항목을 통과해야 합니다.| 요구 사항 | 최솟값 | 확인 명령 | 예상 결과 |
|---|---|---|---|
| Kubernetes 클러스터 | 1.27+ | kubectl version | Server Version >= v1.27 |
| Kustomize (kubectl에 포함) | Kustomize v1.14+ (kubectl 1.27+에 포함) | kubectl kustomize --help | 사용법 텍스트 출력 |
| Helm | v3 | helm version | Version:"v3.x.x" |
| cluster-admin RBAC | — | kubectl auth can-i create namespaces | yes |
| 기본 StorageClass | — | kubectl get storageclass | (default) 표시가 있는 항목 최소 1개 |
| LoadBalancer 지원 | — | 클라우드 환경에 따라 다름 (EKS, GKE, AKS 모두 기본 지원) | — |
| GitHub PAT | — | echo $AGENTEYE_TOKEN | 값이 존재해야 함 (enterprise-docs/github-token.md 참조) |
| openssl | — | openssl version | OpenSSL 1.x 또는 3.x |
| 클라우드 스토리지 버킷 | — | PostgreSQL + ClickHouse 백업용 (S3, GCS, 또는 Azure Blob) | — |
모든 항목 한 번에 확인
배포 구조
수집 엔드포인트는 사용자가 제어하는 호스트명(예:ingest.your-company.example)으로 제공됩니다. cert-manager는 HTTP-01 방식으로 Let’s Encrypt에 공개 신뢰 TLS 인증서를 요청하므로, 수집기는 고객별 CA 고정 없이 시스템 신뢰 저장소에서 서버 인증서를 검증합니다.
대시보드 엔드포인트도 동일한 방식으로 동작합니다. 사용자가 제어하는 두 번째 호스트명(예: agenteye.your-company.example)으로 제공되며, 대시보드 Traefik LoadBalancer를 가리킵니다. cert-manager는 해당 LoadBalancer를 통해 Let’s Encrypt 인증서를 발급합니다. 브라우저는 경고 없이 신뢰된 인증서를 받습니다.
인증서 발급 및 갱신은 HTTP-01로 검증됩니다. 따라서 두 LoadBalancer 모두 인터넷에서 포트 80으로 접근 가능해야 합니다. 대시보드 LoadBalancer에 IP 제한이 필요한 경우, 먼저 지원팀과 DNS-01 솔버를 조율하세요 — 그렇지 않으면 갱신이 자동으로 실패하여 인증서가 만료됩니다.
매니페스트 가져오기
AGENTEYE_TOKEN을 확인하세요.
디렉터리 구조:
상태 모니터링 (선택 사항): 서버의 readiness probe는 이미 Postgres + ClickHouse 상태를 반영하며, third-party/robusta/는 선택적으로 Kubernetes 네이티브 파드 오류 알림을 Slack에 전송하는 기능을 추가합니다. enterprise-docs/health-monitoring.md를 참조하세요.
Phase 1 — 서드파티 인프라 (~30분)
1.1 cert-manager 설치
cert-manager는 HTTPS용 TLS 인증서와 mTLS 클라이언트 인증서에 사용되는 프라이빗 CA를 관리합니다.Running 상태 — cert-manager, cert-manager-cainjector, cert-manager-webhook.
certificates.cert-manager.io, clusterissuers.cert-manager.io, issuers.cert-manager.io가 표시되어야 합니다.
실패 시: 파드가 CrashLoopBackOff 상태이면 일반적으로 CRD가 설치되지 않은 것입니다. --set crds.install=true를 추가하여 다시 실행하세요. webhook 파드가 readiness에 실패하면 30초 기다렸다가 다시 확인하세요 — 시작하는 데 잠시 시간이 걸릴 수 있습니다.
1.2 Traefik 설치 — 공용 수집 컨트롤러
이 Traefik 인스턴스는 외부 LoadBalancer에서 수집기 트래픽을 처리합니다. TLS를 종료하고 수집 엔드포인트에서 mTLS(클라이언트 인증서 검증)를 강제합니다.Running 상태.
kubectl describe pod -n traefik-public <pod-name>으로 이미지 풀 오류나 리소스 제약을 확인하세요.
1.3 Traefik 설치 — 대시보드 컨트롤러
이 Traefik 인스턴스는 전용 LoadBalancer에서 대시보드를 제공하며, IP 허용 목록으로 접근을 제한합니다.이 인스턴스에는 두 가지 허용 목록 메커니즘이 제공됩니다. 이 가이드는 이식성 있는설치 전에service.loadBalancerSourceRanges필드로 접근을 제한하는values-dashboard.yaml을 사용합니다.service.beta.kubernetes.io/aws-load-balancer-source-ranges어노테이션을 선호하는 AWS 환경을 위해values-internal.yaml도 함께 제공됩니다. 하나를 선택하여 일관되게 사용하세요. 아래 단계는values-dashboard.yaml을 기준으로 설명합니다.
third-party/traefik/values-dashboard.yaml을 편집하여 허용된 소스 IP를 설정하세요. loadBalancerSourceRanges 필드는 대시보드에 접근할 수 있는 IP를 제어합니다. 기본값은 0.0.0.0/0(모든 IP)으로 설정되어 있으므로, VPN, 사무실 또는 알려진 이그레스 IP로 제한하세요.
단일 IP 허용
여러 IP 허용
IP 또는 CIDR 블록마다 하나씩 항목을 추가하세요./32 접미사는 단일 IPv4 주소를 의미하며, CIDR 블록(예: /24)은 범위를 의미합니다. 개별 IP와 범위를 자유롭게 혼합할 수 있습니다:
- 줄당 하나의 항목을 유지하고 각 IP의 소유자나 목적을
#주석으로 추가하세요. 이 정보는 나중에 운영자가 해당 항목이 아직 필요한지 판단하는 데 사용됩니다. - 항상 CIDR 표기법을 사용하세요.
203.0.113.10처럼 슬래시 없는 IP는 클라우드 제공업체에서 거부합니다.203.0.113.10/32를 사용하세요. - IPv6 범위의 경우
/128(단일 주소) 또는 더 큰 CIDR(예:2001:db8::1/128)을 사용하세요. 모든 클라우드 제공업체가 IPv6 소스 범위를 지원하지는 않으므로 해당 제공업체의 LoadBalancer 문서를 확인하세요. - 목록은 OR 조건입니다. 소스가 어느 항목과도 일치하면 트래픽이 허용됩니다.
helm install을 진행하세요. 컨트롤러가 이미 설치되어 있다면 같은 플래그로 helm upgrade를 실행하거나 런타임에 Service를 직접 패치하세요 (다음 섹션 참조).
런타임에 허용 목록 업데이트
Helm 업그레이드 없이 Service를 직접 패치하여 허용 IP를 변경할 수 있습니다. 패치는 전체 목록을 교체합니다. 새 IP만 포함하지 말고 유지하고 싶은 모든 IP를 반드시 포함하세요. 새 IP 집합으로 목록을 교체하려면:
런타임 패치는 values-dashboard.yaml에 저장되지 않습니다. 향후 Helm 업그레이드 이후에도 변경 사항을 유지하려면 값 파일도 업데이트하고 커밋하세요.
그런 다음 설치:
Running 상태.
1.4 LoadBalancer 대기
두 Traefik 인스턴스 모두 진행하기 전에 외부 IP가 필요합니다.EXTERNAL-IP가 표시되어야 합니다 (<pending> 상태가 아닌 것).
여전히 pending 상태라면 할당을 대기하세요:
Ctrl+C를 누르세요. IP 할당은 일반적으로 2~5분이 소요됩니다.
실패 시: 10분 후에도 <pending> 상태이면 일반적으로 클라우드 제공업체가 LoadBalancer를 프로비저닝할 수 없는 것입니다. 서브넷 태그(EKS는 kubernetes.io/role/elb 필요), VPC 구성, 서비스 할당량, 내부 LB 어노테이션이 올바르게 설정되어 있는지 확인하세요.
Phase 2 — 시크릿 생성 (~10분)
모든 시크릿은 애플리케이션을 배포하기 전에 수동으로 생성합니다. 이렇게 하면 민감한 값이 매니페스트 파일에 노출되지 않습니다.2.1 네임스페이스 생성
Active.
2.2 이미지 풀 시크릿
이 시크릿은 AgentEye 컨테이너 이미지를 가져오기 위해ghcr.io에 인증합니다. PAT 생성 방법은 enterprise-docs/github-token.md를 참조하세요.
kubernetes.io/dockerconfigjson.
심층 확인 — 토큰이 실제로 이미지를 풀할 수 있는지 확인:
overlay의 kustomization.yaml에 고정된 server 이미지 태그를 사용하세요 (현재 번들된 acme overlay와 base 배포 모두 v0.0.1-beta.48). 릴리스 간 이 확인이 어긋나지 않도록 아래 태그를 배포할 태그로 교체하세요:
ok가 출력되어야 합니다.
실패 시: ErrImagePull 또는 401 Unauthorized는 PAT가 유효하지 않거나 read:packages 스코프가 없는 것입니다. enterprise-docs/github-token.md를 다시 확인하세요.
2.3 PostgreSQL 자격 증명
중요: 비밀번호 생성 시-base64가 아닌-hex를 사용합니다. Base64 출력에는+,/,=가 포함될 수 있으며, 이는DATABASE_URL연결 문자열을 깨뜨립니다. 자세한 내용은 enterprise-docs/troubleshooting.md를 참조하세요.
POSTGRES_PASSWORD를 즉시 시크릿 매니저에 저장하세요. 백업에서 복원하거나 데이터베이스에 직접 연결할 때 필요합니다.
확인:
48 (24 hex 바이트 = 48자).
2.4 관리자 API 키
ADMIN_KEY를 즉시 시크릿 매니저에 저장하세요.
확인:
2.5 인증 구성 (대시보드 로그인)
대시보드는 사용자 로그인에 이메일 + OTP를 사용합니다. 이 시크릿이 없어도 서버는 시작되고ADMIN_KEY API 경로는 계속 동작하지만, 사용자가 UI를 통해 로그인할 수 없습니다.
모든 키는 base 매니페스트에서 optional: true로 참조되므로, 일부 시크릿만 있거나 시크릿이 전혀 없어도 됩니다. 서버는 문서화된 기본값으로 폴백합니다. 모든 것을 하나의 agenteye-auth 시크릿으로 묶으면 인증 관련 값을 한 곳에서 교체할 수 있습니다.
| 키 | 목적 |
|---|---|
ADMIN_EMAIL | 부트스트랩 관리자 사용자. 시작 시마다 모든 권한으로 upsert되며, 대시보드를 통한 삭제/권한 수정이 차단됩니다. 설정하지 않으면 관리자가 시드되지 않아 첫 번째 로그인이 불가능합니다. |
ALLOWED_EMAILS | 쉼표로 구분된 허용 목록. 정확한 주소(user@example.com)와 도메인 와일드카드(*@example.com)를 지원합니다. 설정하지 않으면 사용자 로그인 또는 생성이 불가능합니다. |
SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, SMTP_FROM | OTP 코드 발송을 위한 SMTP 릴레이. SMTP_HOST가 설정되지 않으면 OTP 코드는 이메일 대신 서버 stdout에 기록됩니다 (최초 부팅 스모크 테스트에 유용). 실제 이메일 발송을 위해서는 모든 SMTP 키를 함께 제공하세요. |
SMTP_TLS | starttls(기본값), tls, 또는 none 중 하나. |
DEFAULT_ORG_NAME, DEFAULT_ORG_SLUG | 선택 사항. 내장된 default 조직에 친숙한 표시 이름과 URL 슬러그를 지정하여 /default 대신 /acme와 같은 경로에서 사용할 수 있게 합니다. 최초 부팅 시에만 적용되며, agenteye-orgctl org rename으로 조직 이름을 변경하면 이후에는 무시됩니다 (§7.6 참조). 슬러그는 1~40자의 소문자 영숫자로, 중간에 단일 하이픈을 사용할 수 있습니다. 기본 default를 유지하려면 두 값 모두 설정하지 마세요. |
SMTP 자격 증명을 시크릿 매니저에 저장하세요.확인:
2.6 멀티 테넌트 조직 격리 키 (선택 사항)
단일 테넌트 배포에서는 건너뛰세요. 서버는 내장된 개발용 기본값으로 실행되며, 단일default 조직을 정상적으로 제공합니다. 두 번째 조직을 생성하기 전에 강력하고 안정적인 ORG_CH_SECRET을 설정하세요. 각 조직의 ClickHouse 비밀번호는 HMAC(ORG_CH_SECRET, org_id)로 파생되므로, 공개적으로 알려진 개발용 기본값을 사용하면 조직별 자격 증명이 공개적으로 유추 가능해집니다. agenteye-orgctl org create 명령(§7.6 참조)은 서버가 내장된 개발용 기본값을 사용하는 동안에는 실행을 거부합니다.
secretKeyRef로 읽으므로, 이 시크릿을 생성하지 않은 단일 테넌트 클러스터도 정상적으로 부팅됩니다. 값을 안정적으로 유지하고 모든 레플리카에서 동일하게 유지하세요. 교체 시 부팅 시 재조정이 사용자를 다시 프로비저닝할 때까지 모든 조직의 파생된 ClickHouse 비밀번호가 무효화됩니다 (값이 모든 곳에서 일치하는 롤링 재시작으로 복구됩니다). deploy/base/server/secret.example.yaml을 참조하세요.
ORG_CH_SECRET을 시크릿 매니저에 저장하고 불필요하게 교체하지 마세요.
2.7 모든 시크릿 확인
agenteye-admin-key, agenteye-auth, agenteye-image-pull, agenteye-postgres)은 계속하기 전에 반드시 존재해야 합니다. agenteye-org-ch-secret은 멀티 테넌트 배포에서만 필요합니다 (§2.6 참조).
Phase 3 — 애플리케이션 배포 (~5분)
3.1 공용 호스트명 구성
cert-manager가 Let’s Encrypt 인증서를 요청하려면 수집 및 대시보드 호스트명이 필요합니다. 템플릿을 복사하고 두 값을 설정하세요:domain.env는 gitignore에 포함되어 있으므로 각 배포에 로컬로 유지됩니다. 둘 중 하나라도 누락되면 kustomize 빌드가 오류를 발생시킵니다.
DNS가 먼저 해석되어야 합니다. 아직 DNS를 LB에 연결하지 않아도 됩니다 (Phase 1.2가 완료될 때까지 LB가 존재하지 않음). 하지만 단계 3.2의 ACME 발급은 각 호스트명이 해당 LoadBalancer로 해석될 때까지 재시도합니다. Phase 1.4에서 캡처한 LB 호스트명을 사용하여 지금 DNS를 설정하거나, Phase 4에서 레코드를 추가할 수 있습니다.
3.2 매니페스트 적용
신규 설치 시 base를 직접 적용하거나, 해당 환경용 overlay가 있다면 overlay를 적용하세요 (overlay는 이미지 태그, 환경 변수, 리소스 제한만 고정하며 base의 인증서와 라우팅을 상속합니다):3.3 파드 대기
agent(AI 어시스턴트)와 redis 파드는 함께 시작됩니다. 어시스턴트는 LLM 엔드포인트를 제공할 때까지 비활성 상태이고 (enterprise-docs/assistant.md 참조), Redis는 최선 노력 캐시이므로, 플랫폼이 트래픽을 처리하기 위해 둘 다 Ready 상태일 필요는 없습니다.
확인:
agent 및 redis 파드도 함께 표시되어 Running 상태가 됨):
| 파드 상태 | 가능한 원인 | 디버그 명령 |
|---|---|---|
ImagePullBackOff | 이미지 풀 시크릿 또는 PAT 오류 | kubectl describe pod <name> -n agenteye |
CrashLoopBackOff | 잘못된 환경 변수 (예: DATABASE_URL) | kubectl logs <name> -n agenteye |
Pending | CPU/메모리 부족 또는 노드 없음 | kubectl describe pod <name> -n agenteye (Events 확인) |
3.4 스토리지 확인
Bound 상태:
| PVC | 용량 | 대상 |
|---|---|---|
postgres-data-postgres-0 | 50Gi | PostgreSQL 관계형/메타데이터 저장소 |
clickhouse-data-clickhouse-0 | 100Gi | ClickHouse 이벤트 + 평가 분석 저장소 |
redis-data-redis-0 PVC(1Gi)도 함께 표시됩니다.
실패 시: Pending은 StorageClass가 볼륨을 프로비저닝할 수 없다는 의미입니다. kubectl get storageclass를 확인하고 기본값이 있는지 확인하세요. 프로덕션에서는 overlay로 ClickHouse 볼륨을 빠른 SSD StorageClass(예: AWS의 gp3, GCP의 pd-ssd)에 마운트하세요. 느린 디스크에서는 컴팩션 처리량이 저하됩니다.
3.5 인증서 확인
Ready: True:
| 이름 | 발급자 | 목적 |
|---|---|---|
mtls-ca | selfsigned | mTLS 클라이언트 인증서 발급을 위한 프라이빗 CA (10년 유효) |
ingest-tls | letsencrypt-prod | 수집 엔드포인트용 공용 TLS 인증서 (90일, 자동 갱신) |
dashboard-tls | letsencrypt-prod | 대시보드용 공용 TLS 인증서 (90일, 자동 갱신) |
ingest-tls 또는 dashboard-tls가 Ready 상태가 아닌 경우:
kubectl describe certificate <name> -n agenteye를 실행하고 Events를 확인하세요. 일반적인 원인:
- DNS가 아직 LB를 가리키지 않음. Let’s Encrypt는 호스트명을 해석하고 포트 80에 연결하여 검증합니다 —
INGEST_DOMAIN은 공용 LB로,DASHBOARD_DOMAIN은 대시보드 LB로 해석되어야 합니다. CNAME/Alias가 전파될 때까지 주문은pending상태로 유지됩니다. DNS가 올바르게 설정되면 cert-manager가 자동으로 재시도합니다 (Certificate를 삭제할 필요 없음). - 호스트명이 치환되지 않음.
dnsNames가 여전히INGEST_DOMAIN_PLACEHOLDER/DASHBOARD_DOMAIN_PLACEHOLDER로 표시되면 3.1 단계를 건너뛴 것입니다 —base/certificates/domain.env를 생성하고 다시 적용하세요. - 대시보드 Traefik이 챌린지를 처리할 수 없음 (
dashboard-tls만 해당). 대시보드 Traefik 인스턴스는 번들된 값 파일(Phase 1.2)과 함께 설치되어야 합니다. 이 파일은 cert-manager의 HTTP-01 솔버를 처리하는 스코프가 지정된 Ingress 제공자를 활성화합니다. 이 파일 없이 설치된 인스턴스는 챌린지를 라우팅할 수 없어 주문이 영원히pending상태로 남습니다.
mtls-ca가 Ready 상태가 아닌 경우: cert-manager 자체가 비정상 상태입니다. 1.1 단계의 cert-manager 파드를 다시 확인하세요.
3.6 CronJob 확인
| 이름 | 스케줄 | 목적 |
|---|---|---|
agenteye-backup | 0 3 * * * | UTC 03:00에 매일 Postgres + ClickHouse 백업 |
cert-renewal-check | 0 3,15 * * * | UTC 03:00 및 15:00에 인증서 만료 알림 |
3.7 서버 정상 시작 확인
POSTGRES_PASSWORD가 DATABASE_URL을 깨뜨리는 경우입니다. enterprise-docs/troubleshooting.md를 참조하세요.
3.8 대시보드가 서버에 연결되었는지 확인
Ready를 찾고 ECONNREFUSED 또는 유사한 오류가 없는지 확인하세요.
실패 시: server Service가 존재하는지 확인하고 (kubectl get svc server -n agenteye), 대시보드 배포에서 AGENTEYE_SERVER_URL이 http://server:8080으로 설정되어 있는지 확인하세요.
Phase 4 — 네트워크 접근 (~5분)
4.1 LoadBalancer 주소 확인
AWS EKS에서는 LoadBalancer가 IP 대신 호스트명을 반환합니다. 위 명령에서확인:.ip를.hostname으로 교체하세요.
4.2 LoadBalancer에 DNS 연결
base/certificates/domain.env의 호스트명이 각 LoadBalancer로 해석되도록 DNS 레코드를 생성하세요 — INGEST_DOMAIN은 공용 Traefik LB로, DASHBOARD_DOMAIN은 대시보드 Traefik LB로:
- AWS Route 53:
Alias = Yes로A레코드 생성, 대상 = LB 호스트명. 일반 A → IP는 사용하지 마세요. ELB IP는 교체됩니다. - 다른 제공업체: 호스트명에서 LB 호스트명으로
CNAME생성.
$PUBLIC_IP 및 $INTERNAL_IP와 동일한 주소가 반환되어야 합니다 (EKS에서는 동일한 *.elb.amazonaws.com 호스트명으로 해석).
DNS가 해석되면 cert-manager는 Phase 3.5의 보류 중인 ACME 주문을 1분 이내에 완료합니다. ingest-tls와 dashboard-tls 모두 Ready: True가 될 때까지 kubectl get certificates -n agenteye를 다시 실행하세요.
4.3 수집 엔드포인트 접근
공용 수집 엔드포인트는 상호 TLS를 강제하므로/health를 포함한 모든 요청에 클라이언트 인증서가 필요합니다. 첫 번째 클라이언트 인증서는 Phase 5에서 발급합니다. 이미 인증서가 있다면 지금 접근 가능 여부를 확인하세요:
{"status":"ok"}. -k는 필요하지 않습니다 — 서버 인증서는 INGEST_DOMAIN에 대해 공용 CA에 체인되어 있으므로 시스템 신뢰 저장소에서 검증됩니다. 원시 LoadBalancer IP/호스트명이 아닌 INGEST_DOMAIN 호스트명으로 수집 엔드포인트에 접근하세요 (발급된 인증서와 호스트명이 일치해야 함).
대시보드 엔드포인트는 DASHBOARD_DOMAIN에서 공개 신뢰 인증서로 제공되며 mTLS 뒤에 있지 않으므로, -k와 클라이언트 인증서가 필요하지 않습니다:
DASHBOARD_DOMAIN에 바인딩되어 있으므로 원시 주소는 인증서 이름 불일치를 표시합니다.
실패 시: curl이 멈추면 해당 머신에서 LB에 접근 가능한지 확인하세요 (VPN, 보안 그룹, 방화벽 규칙). 수집 호스트명에서 certificate required 핸드셰이크 오류는 클라이언트 인증서가 제공되지 않은 것입니다. Phase 5를 먼저 완료하세요. 수집 호스트명에서 TLS 유효성 검사 오류는 서버 인증서 발급이 완료되지 않은 것입니다. Phase 3.5로 돌아가서 해결하세요.
Phase 5 — mTLS 클라이언트 인증서 발급 (~클러스터당 10분)
수집기는 두 가지 요소로 인증합니다: 클라이언트 인증서(전송 계층, 요청이 승인된 클러스터에서 온 것을 증명)와 API 키(애플리케이션 계층, 요청이events:add 권한을 가진 수집기에서 온 것을 증명). 유출된 키는 인증서 없이 쓸모없고, 도난당한 인증서는 유효한 키 없이 쓸모없습니다.
5.1 인증서 발급
수집기를 실행하는 각 클러스터에는 고유한 클라이언트 인증서가 필요합니다. 매니페스트 디렉터리에서:<cluster-name>을 의미 있는 식별자(예: us-east-1-prod, staging)로 교체하세요.
확인: 스크립트가 ==> Done!을 출력하고 출력 파일 목록을 나열합니다.
Ready: True.
issued/<cluster-name>/의 출력 파일:
| 파일 | 목적 |
|---|---|
client.crt | 클라이언트 인증서 (90일 유효) |
client.key | 클라이언트 개인 키 |
ca.crt | 서버 검증을 위한 CA 인증서 |
collector-mtls-secret.yaml | 수집기 클러스터에 바로 적용 가능한 Kubernetes Secret |
5.1b 대체 전달 방법: AWS Secrets Manager
인증서 소비자가client.crt와 client.key를 디스크에 필요로 하는 Kubernetes Pod인 경우 — agenteye-collector를 애플리케이션 파드의 사이드카로 실행할 때의 일반적인 경우 — 인증서 번들을 AWS Secrets Manager에 저장하세요. 그러면 애플리케이션 파드는 IRSA와 함께 Secrets Store CSI Driver를 통해 마운트하고, 인증서 교체가 자동으로 처리됩니다.
PutSecretValue를 호출하므로 ARN과 이름이 안정적으로 유지됩니다. CSI Driver는 다음 교체 폴링 시 새 버전을 가져와 파드 내부 파일을 덮어씁니다.
사전 요구 사항:
- AWS 계정에 인증된
awsCLI v2. jq설치됨.AWS_REGION환경 변수 설정됨.- 호출자 ID의 IAM 권한 (
Resource를arn:aws:secretsmanager:<region>:<account>:secret:agenteye/mtls-client/*로 제한):secretsmanager:CreateSecretsecretsmanager:DescribeSecretsecretsmanager:PutSecretValuesecretsmanager:TagResource
| 단계 | 작업 |
|---|---|
| 1 | cert-manager를 통해 인증서를 발급/재추출합니다 (기본 모드와 동일). |
| 2 | agenteye/mtls-client/<cluster-name>에서 DescribeSecret을 호출하여 생성 또는 업데이트를 결정합니다. |
| 3 | 최초 실행: 세 개의 키 JSON 페이로드(client.crt, client.key, ca.crt)와 AgentEyeCluster=<cluster-name> 태그로 CreateSecret. 이후 실행: 새 버전을 게시하는 PutSecretValue; TagResource로 태그 갱신. |
| 4 | 성공적인 업로드 후에만 issued/<cluster-name>/를 삭제합니다. 실패 시 디렉터리를 보존하여 재시도할 수 있습니다. |
aws secretsmanager restore-secret --secret-id agenteye/mtls-client/<cluster-name>을 실행하라는 명확한 오류 메시지와 함께 실패합니다.
전체 파드 연결 설정(SecretProviderClass, IRSA 설정, 교체 동작, 문제 해결)은 enterprise-docs/single-pod-deployment.md를 참조하세요.
5.2 인증서 동작 확인
mTLS 인그레스에 발급된 인증서를 테스트하세요:{"status":"ok"}
실패 시:
| 오류 | 원인 | 해결 방법 |
|---|---|---|
certificate required | 인증서가 제공되지 않음 | curl 명령의 파일 경로 확인 |
bad certificate | CA 불일치 | mtls-ca-issuer가 인증서를 발급했는지 확인: kubectl describe certificate mtls-client-<name> -n agenteye |
connection refused | 잘못된 호스트명 또는 LB에 접근 불가 | /etc/hosts 또는 DNS 확인 |
5.3 수집기 클러스터에 전달
collector-mtls-secret.yaml을 수집기 클러스터를 운영하는 팀에 전달하세요. 팀은 이를 적용합니다:
client.crt, client.key, ca.crt)를 가진 시크릿이 존재해야 합니다.
5.4 인증서 수명 주기
| 속성 | 값 |
|---|---|
| 클라이언트 인증서 유효 기간 | 90일 |
| 자동 갱신 | cert-manager가 만료 15일 전에 갱신 |
| CA 유효 기간 | 10년 |
| 만료 알림 | CronJob이 만료 30일 전에 알림 (Phase 6) |

