AWS에서 Helm으로 배포(Deploy on AWS with Helm)
AWS에서 Helm으로 배포(Deploy on AWS with Helm)
인프라가 준비되면, Terraform 출력값을 사용해 confident-ai Helm 차트를 설치해요. 차트는 Confident AI 레지스트리에서 이미지를 가져오고 앱과 클러스터 내부 ClickHouse를 설치해요. 앱이 EKS Pod Identity를 사용하므로 ServiceAccount에 어노테이션이 필요 없어요.
출처: 문서
본문
권장 설정은 앱 시크릿을 AWS Secrets Manager에 두고 (External Secrets Operator가 동기화) Redis를 ElastiCache에서 실행하는 거예요. 둘 다 Terraform 모듈이 프로비저닝해요. 클러스터 내부 Redis와 Kubernetes Secret은 더 간단한 대안으로 지원되며, 더 간단한 옵션을 참고하세요.
Enterprise 라이선스와 함께 Confident AI에서 두 가지를 받아요:
- 이미지 풀 자격 증명: 클러스터가 퍼스트파티 이미지를 가져올 수 있게 하는 AWS access key ID와 시크릿 (별도 ECR 계정에 호스팅됨). 차트가 이 자격 증명으로 풀 시크릿을 자동으로 만들고 갱신해요.
- 라이선스 키 (
CONFIDENT_LICENSE_KEY): 플랜의 기능을 활성화하는 서명된 키.
OPENAI_API_KEY에 대해: Confident AI의 내장 평가 제공자가 OpenAI에서 실행되는데, 이를 뒷받침해요. 선택 사항이에요. 생략하면 자체 모델 제공자를 연결하거나, 앱의 AI Connections에서 프로젝트별 LLM 게이트웨이를 연결하면 돼요.
네임스페이스 생성
kubectl create namespace confident-ai
Secrets Manager에 시크릿 넣기
DATABASE_URL은 Terraform에서 바로 나와요. 이 JSON 객체의 각 키는 앱 시크릿이 돼요:
SECRET_NAME=$(terraform output -raw secrets_manager_secret_name)
REGION=$(terraform output -raw region)
aws secretsmanager put-secret-value --secret-id "$SECRET_NAME" --region "$REGION" \
--secret-string "{
\"DATABASE_URL\":\"$(terraform output -raw database_url)\",
\"BETTER_AUTH_SECRET\":\"$(openssl rand -hex 32)\",
\"OPENAI_API_KEY\":\"sk-...\",
\"CONFIDENT_LICENSE_KEY\":\"...\"
}"
이것은
confident_create_secrets_manager = true로 Terraform이 만든 시크릿을 사용해요. 활성화하지 않았다면 켜고 다시 적용하거나, 더 간단한 옵션을 쓰세요.
External Secrets Operator 설치
confident-ai 네임스페이스에 external-secrets-sa 계정으로 설치해요. Terraform이 읽기 역할을 부여한 바로 그 계정이에요. ESO는 키 없이 Pod Identity를 통해 AWS 접근을 상속받죠:
helm repo add external-secrets https://charts.external-secrets.io && helm repo update
helm install external-secrets external-secrets/external-secrets \
-n confident-ai \
--set installCRDs=true \
--set serviceAccount.name=external-secrets-sa
ALB 인그레스 설정 (HTTPS용)
도메인에서 HTTPS로 앱을 제공하려면 AWS Load Balancer Controller를 설치하고 (Ingress에서 ALB 프로비저닝), 리전에서 yourdomain.com의 네 개 서브도메인 app., api., evals., otel.을 커버하는 ACM 인증서를 요청해요 (와일드카드 *.yourdomain.com도 동작해요). 아래 values 파일에서 인증서 ARN을 참조하게 됩니다.
그냥 시험해 보는 중이라면 values 파일에서
ingress.enabled: false로 두고kubectl port-forward -n confident-ai svc/confident-frontend 3000:3000로 앱에 접근하세요.
values 파일 작성
values.aws.yaml로 저장해요. 대괄호 값들은 Terraform 출력값과 Confident AI가 준 자격 증명으로 채우세요.
# The chart mints and refreshes the ECR pull secret from these credentials.
imagePullSecrets:
- name: ecr-registry-credentials
imagePullSecretRefresh:
enabled: true
region: us-east-1
awsAccessKeyId: "<from Confident AI>"
awsSecretAccessKey: "<from Confident AI>"
config:
cloudProvider: AWS
frontendUrl: https://app.yourdomain.com
backendUrl: https://api.yourdomain.com
subdomain: yourdomain.com
serviceAccount:
create: true # Pod Identity is already wired to this SA, no annotation needed
storage:
testCasesBucket: <test_cases_bucket>
payloadsBucket: <payloads_bucket>
aws:
region: <region>
# Recommended: app secrets come from AWS Secrets Manager via ESO.
secrets:
externalSecrets:
enabled: true
provider: aws
createStore: true
remoteKey: <secrets_manager_secret_name>
aws:
region: <region>
clickhouse:
internal: true
password: "<choose-a-password>"
storageClass: gp3
keeper:
storageClass: gp3
# Recommended: managed Redis (ElastiCache) from Terraform.
redis:
internal: false
externalUrl: <redis_url>
# Required for code-based and transformer metrics (Lambda sandbox from Terraform).
codeExecutor:
provider: AWS_LAMBDA
aws:
lambdaFunctionName: <code_executor_function_name>
lambdaRegion: <region>
ingress:
enabled: true
className: alb
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/group.name: confident
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
alb.ingress.kubernetes.io/certificate-arn: <your-acm-cert-arn>
hosts:
evals: evals.yourdomain.com
otel: otel.yourdomain.com
차트 설치
차트는 OCI 아티팩트로 GHCR에 게시돼요:
helm install confident-ai \
oci://ghcr.io/confident-ai/charts/confident-ai \
--version 0.2.0 \
-n confident-ai \
-f values.aws.yaml
kubectl get pods -n confident-ai -w
ClickHouse 오퍼레이터가 먼저 시작되고, 마이그레이션 작업이 실행된 다음 앱 파드가 올라와요. 몇 분 걸려요.
검증
kubectl get externalsecret -n confident-ai # STATUS should be SecretSynced
kubectl get ingress -n confident-ai # ADDRESS is the ALB hostname
app., api., evals., otel. DNS 레코드(CNAME 또는 Route 53 별칭)를 ALB 호스트네임을 가리키도록 만들고, https://app.yourdomain.com을 열어 로그인하세요.
더 간단한 옵션: 클러스터 내부 Redis와 Kubernetes Secret
클라우드 시크릿 스토어나 관리형 Redis를 운영하고 싶지 않다면, 차트가 Kubernetes Secret에 시크릿을 담고 Redis를 클러스터 안에서 실행할 수 있어요. 프로덕션 하드닝(경화)은 덜 되지만(시크릿이 클러스터 안에 있고 Redis에 관리형 백업이 없음), ESO와 ElastiCache 단계를 없애요. 위의 2·3단계는 건너뛰고 values 파일의 secrets와 redis 블록을 이렇게 바꿔 주세요:
secrets:
data:
DATABASE_URL: "<database_url>"
BETTER_AUTH_SECRET: "<openssl rand -hex 32>"
OPENAI_API_KEY: "sk-..."
CONFIDENT_LICENSE_KEY: "<your license key>"
redis:
internal: true
storageClass: gp3
ClickHouse 백업 (권장)
프로덕션에서는 매일 밤 ClickHouse를 S3로 백업하세요. 백업 버킷을 프로비저닝하고 (confident_clickhouse_backup_bucket_enabled = true), 백업 파드가 Pod Identity로 쓰므로 serviceAccountName을 그 버킷에 쓸 수 있는 역할을 가진 서비스 계정으로 설정해요. 자세한 내용은 Disaster Recovery 페이지에 있어요. 기존 clickhouse: 블록 아래에 추가하고 helm upgrade로 적용하세요:
clickhouse:
backup:
enabled: true
provider: s3
schedule: "0 2 * * *" # nightly at 02:00 UTC
serviceAccountName: confident
s3:
bucket: <clickhouse_backup_bucket>
region: <region>
문제 해결(Troubleshooting)
| 증상 | 원인과 조치 |
|---|---|
externalsecret가 SecretSynced에 도달하지 못함 |
ESO가 confident-ai 네임스페이스에서 external-secrets-sa로 실행되어야 Pod Identity 읽기 역할을 상속받아요. helm install 플래그와 confident_create_secrets_manager = true를 다시 확인하세요. |
파드가 Pending에 갇히고, PVC가 바인딩되지 않음 |
EKS에는 기본 StorageClass가 없어요. 인프라 페이지에서 gp3 기본값을 만들고, values 파일이 ClickHouse에 storageClass: gp3를 설정했는지 확인하세요. |
앱 이미지에서 ImagePullBackOff |
이미지가 별도 ECR 계정에 있어 노드 IAM으로 가져올 수 없어요. imagePullSecretRefresh가 활성화됐고 Confident AI의 AWS 키가 올바른지 확인하세요. |
Ingress가 ADDRESS를 얻지 못함 |
AWS Load Balancer Controller가 설치되지 않았거나 서브넷이 태그되지 않았어요. 공개 서브넷은 kubernetes.io/role/elb=1이 필요하며 네트워크 단계가 태그를 붙여줘요. |
프론트엔드가 ENOTFOUND confident-backend로 500을 반환 |
프론트엔드가 차트 접두사(prefix) 이름으로 백엔드 서비스를 확인해요. fullnameOverride: confident(차트 기본값)를 유지하세요. 바꾸지 마세요. |
| 앱에서 S3 접근 거부 | Pod Identity가 연결되지 않았어요. serviceAccount.create: true를 기본 이름으로 유지해 Terraform이 만든 연결과 일치시키세요. |
ClickHouse Keeper가 Not authenticated 로그 |
이전 실패한 설치의 오래된 PersistentVolumeClaim이에요. helm uninstall, kubectl delete pvc -n confident-ai --all, 그 다음 재설치하세요. |
kubectl port-forward 중 broken pipe 오류 |
무해한 연결 재설정이에요. port-forward를 다시 실행하세요. |
업데이트와 제거
- 앱 변경:
values.aws.yaml를 편집한 뒤helm upgrade confident-ai oci://ghcr.io/confident-ai/charts/confident-ai --version 0.2.0 -n confident-ai -f values.aws.yaml. - 시크릿 회전:
aws secretsmanager put-secret-value를 다시 실행하세요. ESO가 다시 동기화하고, 파드를 재시작해 변경사항을 반영해요(시크릿을 환경 변수로 보유하다가 재시작할 때까지):kubectl rollout restart deployment -n confident-ai. - 인프라 변경: Terraform 설정을 편집하고
terraform apply. - 모두 제거:
helm uninstall confident-ai -n confident-ai, 그 다음terraform destroy, Terraform이 소유하지 않았다면 Infrastructure 페이지에서 네트워크를 삭제하세요.