# Perses 배포 (Keycloak OIDC 로그인 + 대시보드 프로비저닝) Perses는 Apache 2.0 라이선스의 대시보드/시각화 플랫폼이다(Grafana AGPLv3 대체). Keycloak OIDC로 로그인하고, VictoriaMetrics·VictoriaLogs를 데이터소스로 사용한다. ## 1. 배포 방법 ### 사전 준비 > Keycloak 리소스는 배포 환경에 **항상 존재하는 `paasup` realm**에 생성한다 (realm 신규 생성 금지). issuer: `https://keycloak.example.org/realms/paasup`. 1. **Client `perses`** 생성 (confidential, Valid Redirect URIs: `https://perses.example.org/api/auth/providers/oidc/keycloak/callback`) 2. **datasource용 service-account Client `perses-vmauth`** 생성 (client_credentials 활성화, `vm-access` Client Scope 연결 → `vm_access` 클레임으로 플랫폼 조회 권한). vmauth `CUSTOM-README.md` 3장 참조. 3. (사내 CA 사용 시) Keycloak TLS CA Secret 생성 ```sh kubectl create secret generic root-ca-cert -n monitoring --from-file=ca.crt=./ca.crt ``` ```sh helm upgrade perses ./ -f custom-values.yaml --install -n monitoring ``` ## 2. custom-values.yaml 설정 설명 ### 2.1 OIDC 로그인 (`config.security`) `enable_auth: true` + Keycloak OIDC provider. `enable_native: true`로 네이티브 로그인도 병행 가능하다. ### 2.2 secret_key (쿠키 서명 키) 미설정 시 파드 재시작마다 랜덤 생성되어 OIDC state 쿠키가 무효화된다. **운영에서는 Secret으로 고정**한다(`custom-values.yaml`의 `PERSES_SECURITY_ENCRYPTION_KEY` 주석 참조). ### 2.3 SSL_CERT_FILE 사내 CA로 서명된 Keycloak을 신뢰하도록 `/ca/ca.crt`를 마운트하고 환경변수로 지정한다. ### 2.4 사이드카 프로비저닝 `sidecar.enabled: true`이면 `perses.dev/resource: "true"` 라벨이 붙은 ConfigMap을 자동 로드한다. 대시보드·데이터소스·프로젝트가 이 방식으로 등록된다(아래 4장). ## 3. 권한 관리 (Perses RBAC) > ⚠️ **Perses v0.53.1은 OIDC groups claim 자동 동기화를 지원하지 않는다.** 로그인 시 Keycloak `sub`(UUID)가 Perses User의 `name`이 된다. 따라서 권한은 Perses 자체 RBAC로 관리한다. - **Role** (Project별): `owner`(`actions:[*]`), `editor`(Dashboard/Datasource/Folder/Secret/Variable 전체 + Project/Role/RoleBinding read), `viewer`(read-only) - **RoleBinding**: `subject = {kind: User, name: }` 그룹 멤버 → RoleBinding 매핑은 자동이 아니므로, **운영자가 온보딩 시점에 직접** Keycloak UUID를 조회해 RoleBinding을 생성한다(또는 CronJob으로 자동화 — 참고 구현: vm-stack `install/14-onboard-project.sh`). 별도 스크립트는 카탈로그에 포함하지 않는다. ### 온보딩 절차 (테넌트마다, Perses REST API) ```sh PERSES=https://perses.example.org KC=https://keycloak.example.org # Keycloak 관리자 토큰 → UUID 조회 (sub == Perses User name) KTOKEN=$(curl -s -X POST "$KC/realms/master/protocol/openid-connect/token" \ -d grant_type=password -d client_id=admin-cli -d username=admin -d password="$KC_ADMIN_PW" | jq -r .access_token) UID=$(curl -s "$KC/admin/realms/paasup/users?username=alice" -H "Authorization: Bearer $KTOKEN" | jq -r '.[0].id') # 1) Project 생성 (이미 사이드카로 생성됐다면 생략) curl -s -X POST "$PERSES/api/v1/projects" -H 'Content-Type: application/json' \ -d '{"kind":"Project","metadata":{"name":"tenant-demo01"}}' # 2) editor RoleBinding (subject = Keycloak UUID) curl -s -X POST "$PERSES/api/v1/projects/tenant-demo01/rolebindings" \ -H 'Content-Type: application/json' -d "{ \"kind\":\"RoleBinding\", \"metadata\":{\"name\":\"editors\",\"project\":\"tenant-demo01\"}, \"spec\":{\"role\":\"editor\",\"subjects\":[{\"kind\":\"User\",\"name\":\"$UID\"}]} }" ``` > Role(`owner`/`editor`/`viewer`)은 Project 생성 시 1회만 정의하면 재사용된다(`/api/v1/projects/

/roles`). ## 4. 대시보드/데이터소스 프로비저닝 (`files/perses-provisioning.yaml`) `perses.dev/resource: "true"` 라벨 ConfigMap이며 사이드카가 자동 로드한다. ```sh # 데이터소스 URL / OAuth client_secret 등을 환경에 맞게 수정 후 적용 kubectl apply -f files/perses-provisioning.yaml ``` ### 포함 리소스 (project: `monitoring`) | 리소스 | 이름 | 비고 | |--------|------|------| | Dashboard | k8s-node-overview | 노드 CPU/메모리/디스크/네트워크 | | Dashboard | k8s-workloads | 네임스페이스별 Pod/리소스/Deployment/PVC | | Dashboard | k8s-pod-diagnostics | Pod 로그·이벤트 (VictoriaLogs) | | Dashboard | k8s-pod-history | Pod 재배포/재시작 이력 | | Datasource | victoriametrics | Prometheus 호환 → vmauth:8427 | | Datasource | victorialogs | LogsQL → vmauth:8427 | | Secret | vmauth-platform-admin | vmauth용 OAuth client_credentials | ### 4.1 데이터소스 인증 — OAuth client_credentials (전면 JWT/OIDC) `victoriametrics`/`victorialogs` 데이터소스는 vmauth(`:8427`)를 향하며, HTTPProxy `secret`으로 **Keycloak service-account 토큰**(client_credentials)을 사용한다. ```json { "kind": "Secret", "metadata": {"name": "vmauth-platform-admin", "project": "monitoring"}, "spec": { "oauth": { "clientID": "perses-vmauth", "clientSecret": "perses-vmauth-secret-changeme", "tokenURL": "https://keycloak.example.org/realms/paasup/protocol/openid-connect/token", "scopes": ["openid"] } } } ``` Perses가 토큰을 자동 발급·갱신하며, 해당 토큰의 `vm_access` 클레임이 vmauth에서 테넌트 라우팅을 결정한다. > ⚠️ Perses는 **로그인 사용자의 OIDC 토큰을 업스트림 데이터소스로 전달하지 않는다.** 데이터소스 쿼리는 항상 위 service-account 토큰(서버사이드)으로 나간다. 사용자 단위 데이터 격리가 필요하면 Project별 데이터소스+service-account를 분리한다. ## 5. 배포 검증 ```sh kubectl port-forward -n monitoring svc/perses 8080:8080 # 브라우저: http://localhost:8080 → Keycloak 로그인 → monitoring 프로젝트 대시보드 확인 ```