Kind 로컬 설치
Kind(Kubernetes in Docker)를 사용한 GenD 로컬 개발 클러스터 구성 방법입니다.
개요
GenD 로컬 환경은 Kind 클러스터(gend-local)에 1 control-plane + 2 worker 노드로 구성됩니다. Worker 노드에는 데이터 저장을 위한 호스트 볼륨이 마운트됩니다.
클러스터 생성
kind create cluster --config infra/kind/gend-cluster.yaml
클러스터 설정(infra/kind/gend-cluster.yaml)의 핵심 구성:
- 노드: control-plane 1개 + worker 2개
- 워커 볼륨:
/tmp/gend-worker1,/tmp/gend-worker2->/mnt/data - 네트워크: podSubnet
10.244.0.0/16, serviceSubnet10.96.0.0/12 - Ingress: control-plane에
ingress-ready=true라벨
주요 포트 매핑
| 호스트 포트 | 서비스 | 호스트 포트 | 서비스 |
|---|---|---|---|
| 8080/8443 | Ingress HTTP/S | 31443 | ArgoCD |
| 31080 | Trino UI | 31500 | Harbor |
| 31300 | Grafana | 31800 | Keycloak |
| 30950/30951 | Kyuubi Thrift/REST | 31900 | Vault |
gend-api · gend-ui · Dagster · Kafka UI 는 ingress(
gend.local:8443)로 접근 (NodePort 없음). SeaweedFS 는 ClusterIP(내부 전용).
네임스페이스 구성
kubectl create namespace gend # 메인 서비스
kubectl create namespace gend-dmz # DMZ Relay
kubectl create namespace monitoring # Prometheus, Grafana
kubectl create namespace velero # 백업
이미지 로드
Kind는 별도 레지스트리 없이 로컬 이미지를 직접 로드합니다.
docker build -t gend/gend-api:0.2.0 -f apps/api/Dockerfile apps/api
kind load docker-image gend/gend-api:0.2.0 --name gend-local
이미지 태그를 변경할 때마다 고유 태그를 사용하세요.
latest태그는 Kind에서 캐시 문제를 유발합니다.
클러스터 관리
# 상태 확인
kubectl get nodes
kubectl get pods -n gend
# 클러스터 삭제
kind delete cluster --name gend-local
KServe Stage 3 (선택) — ML Lifecycle E2E (#1566)
ml-lifecycle-end-to-end-e2e.spec.ts Stage 3 (KServe predict tester) 의 hard
assertion 을 Kind 에서 통과시키려면 controller 설치 + seed orchestration 필요.
prerequisite
# 1. cert-manager (KServe 의존)
kubectl --context kind-gend-local apply -f \
https://github.com/cert-manager/cert-manager/releases/download/v1.15.3/cert-manager.yaml
# 2. KServe controller (RawDeployment 모드 — Knative Serving 불필요)
kubectl --context kind-gend-local apply \
--server-side -f https://github.com/kserve/kserve/releases/download/v0.13.1/kserve.yaml
# 3. ServiceAccount + S3 credentials (Kind 내부 SeaweedFS 또는 MLflow 와 같은 backend)
kubectl --context kind-gend-local -n gend create serviceaccount kserve-sa
kubectl --context kind-gend-local -n gend create secret generic kserve-s3-creds \
--from-literal=AWS_ACCESS_KEY_ID=... --from-literal=AWS_SECRET_ACCESS_KEY=...
# #1597 (#1596 Gemini Major): SeaweedFS 의 실제 S3 endpoint 는 service name
# 'seaweedfs-s3' 이 아닌 'seaweedfs.seaweedfs.svc.cluster.local:8333' (helm
# release name=seaweedfs). 실제 클러스터의 svc 이름을 'kubectl get svc -n
# seaweedfs' 로 확인 후 정렬하세요.
kubectl --context kind-gend-local -n gend annotate serviceaccount kserve-sa \
serving.kserve.io/s3-endpoint=seaweedfs.seaweedfs.svc.cluster.local:8333 \
serving.kserve.io/s3-usehttps=0 \
serving.kserve.io/s3-useanoncredential=false
seed 실행
# scripts/seed_demo_credit_risk.py 가 학습 후 InferenceService apply 자동 수행.
# storageUri 의 s3 prefix override 가 필요하면 GEND_MLFLOW_S3_ROOT env 설정.
GEND_SEED_KSERVE=1 \
GEND_MLFLOW_S3_ROOT=s3://gend-mlflow \
./.venv/bin/python scripts/seed_demo_credit_risk.py
Playwright hard assertion
GEND_E2E_REQUIRE_SEED=1 pnpm exec playwright test \
ui/tests/ml-lifecycle-end-to-end-e2e.spec.ts
env 미설정 시 Stage 3 는 conditional skip + console.log 명시 (silent skip 금지
패턴 유지).
문제 해결
- 포트 충돌:
lsof -i :31080(예: Trino NodePort)으로 사용 중인 포트 확인 - 메모리 부족: Docker Desktop 메모리를 12GB 이상으로 증가
- 이미지 로드 실패:
docker save img | kind load image-archive방식 사용