Add VictoriaMetrics observability stack + sync catalog for monitoring test

- VM stack 10 charts: victoria-metrics-cluster/auth, victoria-logs-cluster,
  victoria-metrics-agent/alert, opentelemetry-collector, kube-state-metrics,
  prometheus-node-exporter, alertmanager, perses (JWT/OIDC, Infisical-ready)
- ArgoCD ApplicationSet (syncWave) + per-chart dip-values overlays
- doc/victoria-metrics-architecture.md, define-chart-resources updates
- includes pending working-tree changes (mlflow, kubeflow, apisix, CLAUDE.md)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
wbsong111
2026-06-25 11:10:51 +09:00
parent a55427730e
commit 6290322f1b
514 changed files with 68103 additions and 40 deletions
+62 -34
View File
@@ -112,9 +112,11 @@ def get_user_workspaces(access_token: str) -> list:
]
```
플러그인 소스는 `files/mlflow_workspace_detector.py` 로 포함되어 있다.
```sh
kubectl create configmap mlflow-workspace-plugin -n mlflow \
--from-file=mlflow_workspace_detector.py=mlflow_workspace_detector.py
--from-file=mlflow_workspace_detector.py=manifests/helm/mlflow/1.9.0/files/mlflow_workspace_detector.py
```
---
@@ -315,16 +317,21 @@ kubectl create configmap mlflow-hooks-patch -n mlflow \
---
### 3.8 Ingress 설정
### 3.8 Ingress 설정 (APISIX)
> Kong → APISIX 마이그레이션(issue #139) 반영. ingress class 는 `apisix` 를 사용하고,
> CORS·HTTPS redirect 는 별도 `ApisixPluginConfig`(아래 3.9)로 처리한다.
```yaml
ingress:
enabled: true
className: "kong"
className: "apisix"
annotations:
cert-manager.io/cluster-issuer: "selfsigned-issuer"
cert-manager.io/duration: 8760h
cert-manager.io/renew-before: 720h
# CORS + http→https 를 ApisixPluginConfig(mlflow-cors)로 연결
k8s.apisix.apache.org/plugin-config-name: mlflow-cors
hosts:
- host: mlflow.example.org
paths:
@@ -336,7 +343,10 @@ ingress:
- mlflow.example.org
```
`mlflow.example.org`를 실제 도메인으로 변경한다.
`mlflow.example.org`를 실제 도메인으로 변경한다. TLS 는 표준 Ingress `tls` 필드로 APISIX 가 termination 한다.
> **mlflow OIDC 는 앱 레벨**(`mlflow-oidc-auth`)에서 처리하므로, ingress 에는 `openid-connect`/`keycloak-authz`
> 플러그인을 **추가하지 않는다.** 일반 서비스(jupyter 등)의 Kong→APISIX 전환과 다른 점이다.
---
@@ -359,45 +369,49 @@ extraArgs:
corsAllowedOrigins: "https://mlflow.example.org,https://other.example.org"
```
#### Kong Ingress CORS 플러그인
#### APISIX Ingress CORS + HTTPS redirect (ApisixPluginConfig)
Kong이 CORS preflight(OPTIONS) 요청을 처리하고 응답 헤더를 보완하도록 KongPlugin을 추가한다.
APISIX 가 CORS preflight(OPTIONS) 처리와 http→https redirect 를 수행하도록 `ApisixPluginConfig` 를 생성한다.
(Kong 의 `KongPlugin(cors)` + `konghq.com/protocols: https` 조합 대체)
```sh
kubectl apply -f - <<EOF
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
kubectl apply -f manifests/helm/mlflow/1.9.0/files/mlflow-apisix-cors.yaml
```
`files/mlflow-apisix-cors.yaml`:
```yaml
apiVersion: apisix.apache.org/v2
kind: ApisixPluginConfig
metadata:
name: mlflow-cors
namespace: mlflow
plugin: cors
config:
origins:
- "https://mlflow.example.org"
methods:
- GET
- POST
- PUT
- DELETE
- OPTIONS
- PATCH
headers:
- Accept
- Authorization
- Content-Type
credentials: true
max_age: 3600
EOF
spec:
plugins:
- name: redirect
enable: true
config:
http_to_https: true
- name: cors
enable: true
config:
allow_origins: "https://mlflow.example.org"
allow_methods: "GET,POST,PUT,DELETE,OPTIONS,PATCH"
allow_headers: "Accept,Authorization,Content-Type"
allow_credential: true
max_age: 3600
```
Ingress에 플러그인을 연결한다.
Ingress plugin-config 를 연결한다 (3.8 참조).
```yaml
ingress:
annotations:
konghq.com/plugins: mlflow-cors
k8s.apisix.apache.org/plugin-config-name: mlflow-cors
```
> `allow_credential: true` 일 때 `allow_origins` 는 `*` 를 쓸 수 없으므로 명시적 origin 을 지정한다.
#### 동작 검증
```sh
@@ -447,7 +461,21 @@ extraEnvVars:
---
### 3.11 S3 (MinIO) 설정
### 3.11 S3 (rustfs) 설정
아티팩트 저장소로 클러스터의 rustfs(S3 호환)를 사용한다. 사전에 `mlflow` 버킷을 생성한다.
```sh
# rustfs 자격증명 확인
kubectl get secret rustfs-secret -n rustfs \
-o jsonpath='{.data.RUSTFS_ACCESS_KEY}' | base64 -d; echo
kubectl get secret rustfs-secret -n rustfs \
-o jsonpath='{.data.RUSTFS_SECRET_KEY}' | base64 -d; echo
# mlflow 버킷 생성 (mc 사용 예시)
mc alias set rfs http://rustfs-svc.rustfs.svc.cluster.local:9000 <ACCESS_KEY> <SECRET_KEY>
mc mb -p rfs/mlflow
```
```yaml
artifactRoot:
@@ -457,15 +485,15 @@ artifactRoot:
enabled: true
bucket: mlflow
path: artifacts
awsAccessKeyId: "adminuser" # MinIO access key
awsSecretAccessKey: "adminuser" # MinIO secret key
awsAccessKeyId: "adminuser" # rustfs access key
awsSecretAccessKey: "adminuser" # rustfs secret key
extraEnvVars:
MLFLOW_S3_ENDPOINT_URL: "http://minio.minio.svc.cluster.local:9000"
MLFLOW_S3_ENDPOINT_URL: "http://rustfs-svc.rustfs.svc.cluster.local:9000"
MLFLOW_S3_IGNORE_TLS: "true"
```
외부 MinIO 사용 시 `MLFLOW_S3_ENDPOINT_URL`을 해당 엔드포인트로 변경한다.
외부 S3/MinIO 사용 시 `MLFLOW_S3_ENDPOINT_URL` 과 자격증명을 해당 엔드포인트로 변경한다.
---
@@ -43,7 +43,7 @@ artifactRoot:
extraEnvVars:
# --- 기본 설정 ---
MLFLOW_S3_ENDPOINT_URL: "http://minio.minio.svc.cluster.local:9000"
MLFLOW_S3_ENDPOINT_URL: "http://rustfs-svc.rustfs.svc.cluster.local:9000"
MLFLOW_S3_IGNORE_TLS: "true"
SSL_CERT_FILE: "/etc/ssl/certs/custom-ca.crt"
@@ -91,12 +91,17 @@ service:
ingress:
enabled: true
className: "kong"
className: "apisix"
annotations:
cert-manager.io/cluster-issuer: "selfsigned-issuer"
# root-ca-issuer 사용: selfsigned-issuer 는 subject 가 빈 자체서명 인증서를 발급하여
# APISIX ingress controller 가 SSL 오브젝트로 동기화하지 않는다(TLS handshake 실패).
# 클러스터의 다른 ingress 와 동일하게 CA 서명 issuer 를 사용한다.
cert-manager.io/cluster-issuer: "root-ca-issuer"
cert-manager.io/duration: 8760h
cert-manager.io/renew-before: 720h
konghq.com/plugins: mlflow-cors
# APISIX: http→https redirect 를 ApisixPluginConfig 로 처리 (files/mlflow-apisix-redirect.yaml)
# CORS 는 mlflow 앱 네이티브(extraArgs.corsAllowedOrigins)로 처리
k8s.apisix.apache.org/plugin-config-name: https-redirect
hosts:
- host: mlflow.example.org
paths:
@@ -0,0 +1,19 @@
# APISIX http→https redirect 플러그인 (클러스터의 다른 네임스페이스와 동일한 https-redirect 관례).
# Ingress 의 annotation `k8s.apisix.apache.org/plugin-config-name: https-redirect` 가 이 리소스를 참조한다.
#
# CORS 는 mlflow 앱 네이티브 설정(extraArgs.corsAllowedOrigins)으로 처리하므로
# ingress 레벨 cors 플러그인은 사용하지 않는다.
#
# 주의: mlflow-oidc-auth 는 *앱 레벨* 에서 OIDC 인증을 처리하므로
# ingress 에 openid-connect / keycloak-authz 플러그인을 추가하지 않는다.
apiVersion: apisix.apache.org/v2
kind: ApisixPluginConfig
metadata:
name: https-redirect
namespace: mlflow
spec:
plugins:
- name: redirect
enable: true
config:
http_to_https: true
@@ -0,0 +1,23 @@
import base64
import json
def get_user_workspaces(access_token: str) -> list:
"""
JWT access_token의 groups 클레임에서 mlflow-team-* 그룹을 읽어
workspace 이름 목록을 반환한다.
예: ["mlflow-team-ds", "mlflow"] → ["team-ds"]
"""
try:
payload = access_token.split(".")[1]
payload += "=" * (4 - len(payload) % 4)
claims = json.loads(base64.b64decode(payload))
except Exception:
return []
groups = claims.get("groups", [])
return [
g[len("mlflow-"):]
for g in groups
if g.startswith("mlflow-team-")
]