Azure에서 Helm으로 배포(Deploy on Azure with Helm)
Azure에서 Helm으로 배포(Deploy on Azure with Helm)
인프라가 준비되면, Terraform 출력값을 사용해 confident-ai Helm 차트를 설치해요. 차트는 Confident AI 레지스트리에서 이미지를 가져오고 앱과 클러스터 내부 ClickHouse를 설치해요. Azure에서는 config.isAzureEnvironment: true로 설정하고 Blob 스토리지에는 연결 문자열로 접근해요.
출처: 문서
본문
권장 설정은 앱 시크릿을 Azure Key Vault에 두고 (External Secrets Operator가 동기화) Redis를 Azure Managed Redis에서 실행하는 거예요. 둘 다 Terraform 모듈이 프로비저닝해요. 클러스터 내부 Redis와 Kubernetes Secret은 더 간단한 대안으로 지원되며, 더 간단한 옵션을 참고하세요.
Enterprise 라이선스와 함께 Confident AI에서 두 가지를 받아요:
- 이미지 풀 자격 증명: 클러스터가 퍼스트파티 이미지를 가져올 수 있게 하는 AWS access key ID와 시크릿. 차트가 이 자격 증명으로 풀 시크릿을 자동으로 만들고 갱신해요.
- 라이선스 키 (
CONFIDENT_LICENSE_KEY): 플랜의 기능을 활성화하는 서명된 키.
OPENAI_API_KEY에 대해: Confident AI의 내장 평가 제공자가 OpenAI에서 실행되는데, 이를 뒷받침해요. 선택 사항이에요. 생략하면 자체 모델 제공자를 연결하거나, 앱의 AI Connections에서 프로젝트별 LLM 게이트웨이를 연결하면 돼요.
네임스페이스 생성
kubectl create namespace confident-ai
Key Vault에 시크릿 넣기
각 값을 Key Vault 시크릿으로 저장해요. Key Vault 이름은 _를 포함할 수 없으므로 -를 사용하고, 차트가 들어갈 때 -를 _로 되돌려 써요 (예: DATABASE-URL → DATABASE_URL). 스토리지 연결 문자열도 여기에 포함해요. Key Vault가 전체 시크릿 세트를 소유하기 때문이에요:
KV_URI=$(terraform output -raw key_vault_uri)
KV_NAME=$(echo "$KV_URI" | sed -E 's#https://([^.]+).*#\1#')
az keyvault secret set --vault-name "$KV_NAME" --name DATABASE-URL --value "$(terraform output -raw database_url)"
az keyvault secret set --vault-name "$KV_NAME" --name AZURE-STORAGE-CONNECTION-STRING --value "$(terraform output -raw storage_connection_string)"
az keyvault secret set --vault-name "$KV_NAME" --name BETTER-AUTH-SECRET --value "$(openssl rand -hex 32)"
az keyvault secret set --vault-name "$KV_NAME" --name OPENAI-API-KEY --value "sk-..."
az keyvault secret set --vault-name "$KV_NAME" --name CONFIDENT-LICENSE-KEY --value "..."
이것은
confident_create_key_vault = true로 Terraform이 만든 볼트를 사용해요. 활성화하지 않았다면 켜고 다시 적용하거나, 더 간단한 옵션을 쓰세요.
페더레이션 자격 증명으로 ESO의 아이덴티티 연결
Terraform이 ESO용 관리 아이덴티티를 만들지만, external-secrets-sa Kubernetes 계정으로 동작하게 하는 페더레이션 자격 증명은 만들지 않아요. AKS는 이미 Workload Identity를 활성화하므로, 연결만 추가하면 돼요.
클러스터의 OIDC 발급자와 Terraform이 만든 ESO 아이덴티티를 확인해요:
RESOURCE_GROUP=confident-prod-rg
CLUSTER_NAME=$(terraform output -raw cluster_name)
OIDC_ISSUER_URL=$(az aks show -g $RESOURCE_GROUP -n $CLUSTER_NAME --query oidcIssuerProfile.issuerUrl -o tsv)
ESO_IDENTITY_NAME=$(az identity list -g $RESOURCE_GROUP --query "[?ends_with(name,'eso-identity')].name | [0]" -o tsv)
ESO_CLIENT_ID=$(az identity show -g $RESOURCE_GROUP -n "$ESO_IDENTITY_NAME" --query clientId -o tsv)
아이덴티티를 서비스 계정에 바인딩하는 페더레이션 자격 증명을 만들어요:
az identity federated-credential create --name eso-confident \
--identity-name "$ESO_IDENTITY_NAME" --resource-group "$RESOURCE_GROUP" \
--issuer "$OIDC_ISSUER_URL" \
--subject system:serviceaccount:confident-ai:external-secrets-sa \
--audience api://AzureADTokenExchange
External Secrets Operator 설치
helm repo add external-secrets https://charts.external-secrets.io && helm repo update
helm install external-secrets external-secrets/external-secrets \
-n external-secrets --create-namespace --set installCRDs=true
kubectl create serviceaccount external-secrets-sa -n confident-ai
kubectl annotate serviceaccount external-secrets-sa -n confident-ai \
azure.workload.identity/client-id=$ESO_CLIENT_ID
인그레스 설정 (HTTPS용)
관리형 NGINX 인그레스 컨트롤러를 실행하는 AKS 애플리케이션 라우팅 애드온을 켜요:
az aks approuting enable --resource-group confident-prod-rg --name <cluster_name>
아래 values 파일은 className: webapprouting.kubernetes.io를 사용하고 네 개의 서브도메인(app., api., evals., otel.)을 모두 노출해요. 네 개를 모두 커버하는 Kubernetes 시크릿이나 cert-manager로 TLS를 추가해요.
그냥 시험해 보는 중이라면 values 파일에서
ingress.enabled: false로 두고kubectl port-forward -n confident-ai svc/confident-frontend 3000:3000로 앱에 접근하세요.
values 파일 작성
values.azure.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: AZURE
isAzureEnvironment: true
frontendUrl: https://app.yourdomain.com
backendUrl: https://api.yourdomain.com
subdomain: yourdomain.com
serviceAccount:
create: true
storage:
testCasesBucket: <test_cases_container>
payloadsBucket: <payloads_container>
azure:
storageAccountName: <storage_account_name>
# Recommended: all app secrets (including the storage connection string) come
# from Azure Key Vault via ESO.
secrets:
externalSecrets:
enabled: true
provider: azurekv
createStore: true
serviceAccountRef:
name: external-secrets-sa
azure:
vaultUrl: <key_vault_uri>
tenantId: <your-tenant-id>
clickhouse:
internal: true
password: "<choose-a-password>"
# Recommended: managed Redis (Azure Managed Redis) from Terraform.
redis:
internal: false
externalUrl: <redis_url>
# Required for code-based and transformer metrics (Azure Function sandbox from Terraform).
codeExecutor:
provider: AZURE_FUNCTIONS
azure:
functionUrl: <code_executor_function_url>/api/execute
ingress:
enabled: true
className: webapprouting.kubernetes.io
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.azure.yaml
kubectl get pods -n confident-ai -w
ClickHouse 오퍼레이터가 먼저 시작되고, 마이그레이션 작업이 실행된 다음 앱 파드가 올라와요. 몇 분 걸려요.
검증
kubectl get externalsecret -n confident-ai # STATUS should be SecretSynced
kubectl get svc -n app-routing-system # note the EXTERNAL-IP
그 IP에 app., api., evals., otel. DNS 레코드를 만들고, https://app.yourdomain.com을 열어 로그인하세요.
더 간단한 옵션: 클러스터 내부 Redis와 Kubernetes Secret
Key Vault나 관리형 Redis를 운영하고 싶지 않다면, 차트가 Kubernetes Secret에 시크릿을 담고 Redis를 클러스터 안에서 실행할 수 있어요. 프로덕션 하드닝은 덜 되지만(시크릿이 클러스터 안에 있고 Redis에 관리형 백업이 없음), Key Vault, 페더레이션 자격 증명, ESO 단계를 없애요. 위의 2~4단계는 건너뛰고 values 파일의 secrets와 redis 블록을 이렇게 바꿔 주세요:
secrets:
data:
DATABASE_URL: "<database_url>"
AZURE_STORAGE_CONNECTION_STRING: "<storage_connection_string>"
BETTER_AUTH_SECRET: "<openssl rand -hex 32>"
OPENAI_API_KEY: "sk-..."
CONFIDENT_LICENSE_KEY: "<your license key>"
redis:
internal: true
코드 실행기 키
Azure Function 샌드박스는 함수 키로 보호돼요. Terraform이 Function을 만든 뒤 Azure 포털에서 읽을 수 있어요. 앱이 샌드박스를 호출할 수 있게 시크릿으로 추가해요:
- Key Vault (권장):
az keyvault secret set --vault-name "$KV_NAME" --name CODE-EXECUTOR-AZURE-FUNCTION-KEY --value "<function key>" - 더 간단한 옵션:
secrets.data에CODE_EXECUTOR_AZURE_FUNCTION_KEY: "<function key>"추가.
ClickHouse 백업 (권장)
프로덕션에서는 매일 밤 ClickHouse를 Blob 스토리지로 백업해요. 스토리지 연결 문자열로 인증해요. 백업 컨테이너를 프로비저닝하고 자격 증명에 대한 자세한 내용은 Disaster Recovery 페이지를 참고하세요. 기존 clickhouse: 블록 아래에 추가하고 helm upgrade로 적용하세요:
clickhouse:
backup:
enabled: true
provider: azure
schedule: "0 2 * * *" # nightly at 02:00 UTC
azure:
container: <clickhouse_backup_container>
문제 해결(Troubleshooting)
| 증상 | 원인과 조치 |
|---|---|
externalsecret가 SecretSynced에 도달하지 못함 |
페더레이션 자격 증명 subject는 정확히 system:serviceaccount:confident-ai:external-secrets-sa여야 하고, external-secrets-sa 어노테이션이 ESO 아이덴티티의 client ID를 담아야 해요. 둘 다 다시 확인하세요. |
| Key Vault 시크릿이 앱에 도달하지 못함 | Key Vault 이름은 -를 사용하고 차트가 다시 _로 매핑해요. 시크릿을 DATABASE_URL이 아니라 DATABASE-URL로 이름 지으세요. |
| Blob 스토리지 접근 실패 | config.isAzureEnvironment: true와 AZURE-STORAGE-CONNECTION-STRING이 Key Vault에 있는지(더 간단한 옵션에서는 secrets.data에) 확인하세요. |
Ingress가 EXTERNAL-IP를 얻지 못함 |
애플리케이션 라우팅 애드온이 활성화되지 않았어요. az aks approuting enable을 실행하고 className: webapprouting.kubernetes.io를 유지하세요. |
프론트엔드가 ENOTFOUND confident-backend로 500을 반환 |
프론트엔드가 차트 접두사 이름으로 백엔드 서비스를 확인해요. fullnameOverride: confident(차트 기본값)를 유지하세요. 바꾸지 마세요. |
ClickHouse Keeper가 Not authenticated 로그 |
이전 실패한 설치의 오래된 PersistentVolumeClaim이에요. helm uninstall, kubectl delete pvc -n confident-ai --all, 그 다음 재설치하세요. |
앱 이미지에서 ImagePullBackOff |
imagePullSecretRefresh가 활성화됐고 Confident AI의 AWS 키가 올바른지 확인하세요. |
업데이트와 제거
- 앱 변경:
values.azure.yaml를 편집한 뒤helm upgrade confident-ai oci://ghcr.io/confident-ai/charts/confident-ai --version 0.2.0 -n confident-ai -f values.azure.yaml. - 시크릿 회전: Key Vault에 새 버전을 작성하세요. ESO가 다시 동기화하고, 파드를 재시작해 변경사항을 반영해요(시크릿을 환경 변수로 보유하다가 재시작할 때까지):
kubectl rollout restart deployment -n confident-ai. - 인프라 변경: Terraform 설정을 편집하고
terraform apply. - 모두 제거:
helm uninstall confident-ai -n confident-ai,helm uninstall external-secrets -n external-secrets, 그 다음terraform destroy, 1단계 리소스를 지우고 싶으면az group delete --name confident-prod-rg --yes.