Keycloak
Keycloak은 내부 운영자 도구를 위한 인프라 SSO를 제공합니다. 현재 저장소 상태에서는 주로 Coder, Vault, Zot, Gitea, RabbitMQ 같은 애플리케이션을 위한 infra realm이 핵심입니다.
책임
keycloak네임스페이스에서 Keycloak 실행- 브라우저 기반 흐름을 위해
auth.lumie-edu.com에서 직접 OIDC 엔드포인트 제공 - 공유
infra-dbPostgreSQL 클러스터에 realm 상태 저장 kc.sh import대신 post-sync job으로 선언적 realm 구성을 수렴
소스 경로
| 경로 | 역할 |
|---|---|
lumie-infra/security/keycloak/argocd.yaml | 차트 values, 공통 차트 values, 추가 매니페스트를 포함하는 ArgoCD Application |
lumie-infra/security/keycloak/helm-values.yaml | 서버 시작, DB, metrics, health 설정 |
lumie-infra/security/keycloak/common-values.yaml | 외부 ingress, realm import ConfigMap, Vault 시크릿 렌더링 |
lumie-infra/security/keycloak/manifests/realm-sync-job.yaml | keycloak-config-cli를 사용하는 PostSync realm 수렴 job |
lumie-infra/charts/common/templates/additional-ingresses.yaml | auth.lumie-edu.com을 렌더링하는 템플릿 |
lumie-infra/charts/common/templates/vault-static-secrets.yaml | 로컬 Vault 시 크릿 선언이 사용하는 템플릿 |
lumie-infra/security/teleport/agent/helm-values.yaml | Keycloak UI용 별도 Teleport 앱 진입점 |
퍼블릭 표면과 계약
| 표면 | 계약 |
|---|---|
| 직접 OIDC ingress | https://auth.lumie-edu.com |
| 인클러스터 HTTP 서비스 | keycloak-keycloakx-http.keycloak.svc.cluster.local |
| 데이터베이스 | 공유 infra-db, 데이터베이스 keycloak, 사용자 keycloak |
| Admin bootstrap 시크릿 | keycloak-secrets |
| Realm sync 시크릿 | keycloak-oauth-secrets |
| Teleport 앱 | keycloak |
직접 ingress가 중요한 이유는 Coder와 Vault 같은 클라이언트의 브라우저 OIDC 흐름이 Teleport 앱 프록시만으로는 종료될 수 없기 때문입니다.
런타임 흐름
선언된 렐름 계약
체크인된 infra-realm.json은 다음을 정의합니다.
- realm
infra - realm 역할
admin,developer - client scope
rabbitmq-admin,groups - OIDC client:
codervaultzotgitearabbitmq
- realm 역할
admin,developer를 가진 사용자bluemayne
client secret은 Git에 하드코딩되지 않습니다. keycloak-realm-sync job이 keycloak-oauth-secrets에서 이를 읽어 realm JSON에 치환한 뒤 라이브 admin REST API로 적용합니다.
렐름 동기화가 Job인 이유
저장소는 realm 관리를 위해 의도적으로 kc.sh import --override를 피합니다. realm-sync-job.yaml의 post-sync job이 존재하는 이유는 다음과 같습니다.
- REST 기반 생성이 Keycloak의 표준 client-scope 초기화를 보존하기 때문
- secret placeholder를 realm JSON이 데이터베이스에 기록되기 전에 클라이언트 측에서 치환할 수 있기 때문
- 부분 실패 후에도 재실행이 멱등적이고 안전하기 때문
장애 동작과 운영 리스크
- OAuth 시크릿이 누락되면 Keycloak pod 자체는 healthy여도 로그인 시
invalid_client실패가 발생합니다. - PostSync job이 중간에 실패하면 realm이 부분적으로만 업데이트될 수 있으며, 문서화된 복구 경로는 데이터베이스를 수동 롤백하는 것이 아니라 job을 재실행하는 것입니다.
- 데이터베이스 bootstrap 또는 admin-password 시크릿 장애는 realm sync가 실행되기 전에 시작 자체를 막습니다.
- 직접 ingress가 Teleport 앱 경로와 분리되어 있으므로, ingress나 인증서 장애로 Teleport 프록시 UI는 살아 있어도 OIDC는 깨질 수 있습니다.
계약 드리프트
주의해야 할 실제 체크인 불일치가 있습니다.
security/keycloak/helm-values.yaml주석은 realminfra,lumie,lumie-dev를 설명합니다.security/keycloak/manifests/realm-sync-job.yaml주석도 ConfigMap이infra-realm.json,lumie-realm.json,lumie-dev-realm.json을 마운트한다고 말합니다.- 하지만 현재
security/keycloak/common-values.yaml은infra-realm.json만 렌더링하고, 현재 Vault 시크릿 템플릿도 그 파일이 사용하는 infra client secret만 노출합니다.
추가 realm JSON 파일이 다시 추가되기 전까지는 현재 저장소 상태를 infra realm 전용으로 취급하세요.
관측성
serviceMonitor.enabled: true가 Keycloak 메트릭을 Prometheus에 노출합니다.health.enabled: true와/healthstartup probe가 부팅 readiness를 커버합니다.keycloak-realm-syncjob 로그가 realm 수렴 실패의 단일 출처입니다.
검증
kubectl get applications.argoproj.io -n argocd keycloak
kubectl get statefulset,pods,svc,ingress,secrets -n keycloak
kubectl get jobs -n keycloak -l app.kubernetes.io/component=realm-sync
kubectl logs -n keycloak job/keycloak-realm-sync
kubectl port-forward -n keycloak svc/keycloak-keycloakx-http 8080:80
curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/health
curl -sS -o /dev/null -w "%{http_code}\n" \
https://auth.lumie-edu.com/realms/infra/.well-known/openid-configuration
성공 신호:
keycloakArgo CD application이Healthy및Synced상태입니다.- StatefulSet
keycloak이 준비 상태이고auth.lumie-edu.com용 직접 ingressIngress가 존재합니다. keycloak-realm-syncJob이 성공적으로 완료되고, 로그에 반복적인invalid_client또는 import substitution 오류가 없습니다.- 인클러스터 서비스의
GET /health가 HTTP200을 반환합니다. - realm
infra의 퍼블릭 OIDC discovery 엔드포인트가 HTTP200을 반환합니다.