Kind 로컬 ML 엔지니어링 UI 검증
2026-05-28 시점 기록 — 본문의 구
/models/*개별 메뉴·경로는 현재 ML 허브 스테이지(/ml-hub/*)로 자동 리다이렉트됩니다.
ML lifecycle live-run (AKS prod) + KOGAS LNG anomaly live-run 외에, Kind 로컬 cluster (datax-local) 에서도 동일 UI 메뉴 접근을 검증.
환경
- Kind cluster
datax-local(Kind 0.32, K8s 1.35) - 3 nodes (control-plane + 2 workers)
- 9 days uptime
- ingress-nginx → host port
:8080(docker-desktop) - Keycloak admin/admin
접근
# /etc/hosts
127.0.0.1 gend.local
# UI
open http://gend.local:8080/login
ML 엔지니어링 사이드바 검증 (3 페이지)
실험 (Experiments)

MLflow proxy /api/v1/mlflow/experiments 경유. Kind 의 MLflow 가 비어있어 실험 0건 상태 — 정상 (실 실험은 credit_risk live-run 의 AKS prod 에서 진행).
등록 모델 (Registered Models)

/api/v1/mlflow/registered proxy. Kind 는 비어있음.
노트북 (Notebooks)

JupyterHub 서버 관리. "서버 시작" 버튼 가용성 확인.
검증 결과
| 페이지 | HTTP | 사이드바 | 빈 상태 메시지 | UI 깨짐 |
|---|---|---|---|---|
/models/experiments | ✅ 200 | ✅ | "등록된 실험이 없습니다" | 없음 |
/models/registered | ✅ 200 | ✅ | "등록된 모델이 없습니다" | 없음 |
/notebooks | ✅ 200 | ✅ | "활성 노트북 서버가 없습니다" | 없음 |
Kind dev 환경에서 ML 엔지니어링 메뉴 3 페이지 모두 정상 렌더링.
Playwright 스크립트 (ui/.local/verify-kind-ml.mjs)
import { chromium } from "@playwright/test";
const BASE = "http://gend.local:8080";
const browser = await chromium.launch({ headless: true });
const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 }, ignoreHTTPSErrors: true });
const page = await ctx.newPage();
// Keycloak password grant token
const tokenRes = await page.request.post(`${BASE}/auth/realms/gend/protocol/openid-connect/token`,
{ form: { grant_type:"password", client_id:"gend-ui", username:"admin", password:"admin", scope:"openid profile email" }});
const tb = await tokenRes.json();
// localStorage 주입 (oidc-client-ts)
await page.goto(`${BASE}/login`, { waitUntil:"domcontentloaded" });
await page.evaluate(([tb, base]) => {
const k = `oidc.user:${base}/auth/realms/gend:gend-ui`;
const v = JSON.stringify({
id_token: tb.id_token, access_token: tb.access_token, refresh_token: tb.refresh_token,
token_type:"Bearer", scope: tb.scope, profile: {},
expires_at: Math.floor(Date.now()/1000) + tb.expires_in,
});
localStorage.setItem(k, v); sessionStorage.setItem(k, v);
}, [tb, BASE]);
for (const [p, name] of [
["/models/experiments", "kind-ml-experiments"],
["/models/registered", "kind-ml-registered"],
["/notebooks", "kind-ml-notebooks"],
]) {
const r = await page.goto(`${BASE}${p}`, { waitUntil:"networkidle" });
await page.waitForTimeout(2500);
await page.screenshot({ path: `screenshots/${name}.png`, fullPage: true });
}
Known Issues
| 항목 | 영향 | 상태 |
|---|---|---|
datax-local MLflow 비어있음 | 실험/등록 모델 페이지 빈 상태 | known (이전 cycle 의 datax-local seed 부재) |
falco CrashLoopBackOff (3800+ restart) | 무관 (보안 정책 — UI 무영향) | 별도 issue (#?) |
gend-ui image 0.4.0-kind-2e97491 | 본 cycle 이전 빌드 | OK (UI 렌더링 정상) |
관련
- ml-lifecycle-live-run — AKS prod credit_risk 7-step
- lng-anomaly-walkthrough — AKS prod KOGAS LNG 4-step
- Meta Epic #1085