-
Notifications
You must be signed in to change notification settings - Fork 178
Add Kind dev environment setup skill and slash command #2307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
google-oss-prow
merged 5 commits into
kubeflow:main
from
manaswinidas:kind-cluster-skill-command
Apr 15, 2026
+324
−5
Merged
Changes from 4 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
e9c6b06
Add Kind dev environment setup skill and slash command
manaswinidas 7956900
Update Kind dev setup: default to real K8s, add RBAC fix, fix MinIO n…
manaswinidas 826ed61
Address review comments and add kind cluster teardown command
manaswinidas a8307a0
Replace .cursor/.claude dirs with AGENTS.md, scripts, and docs
manaswinidas 844cd8f
Update scripts/dev_teardown.sh
manaswinidas File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,184 @@ | ||
| # Kind Dev Environment | ||
|
|
||
| Local Kubernetes development environment for the model-registry UI using Kind and Tilt. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - A Docker-compatible runtime (e.g. Docker Desktop, Colima, Podman with `podman-docker`) | ||
| - [Kind](https://kind.sigs.k8s.io/) installed | ||
| - kubectl installed | ||
| - Go >= 1.25.7 | ||
| - Node.js >= 22.0.0 | ||
| - Tilt v0.33.22+ (auto-downloaded by `make tilt-up` if not present) | ||
|
|
||
| ## Architecture | ||
|
|
||
| The dev environment runs three concurrent processes: | ||
|
|
||
| | Component | Directory | Port | Purpose | | ||
| |-----------|-----------|------|---------| | ||
| | Infrastructure | `devenv/` | 10350 (Tilt) | Kind cluster + Tilt for deploying model-registry resources | | ||
| | BFF | `clients/ui/bff/` | 4000 | Go backend-for-frontend server | | ||
| | Frontend | `clients/ui/frontend/` | 9000 | React dev server (proxies to BFF) | | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ### 1. Start Infrastructure | ||
|
|
||
| ```bash | ||
| # Start your Docker runtime (example with Colima on macOS): | ||
| colima start | ||
|
|
||
| # Create the Kind cluster (if it doesn't exist): | ||
| kind get clusters | grep -q '^model-registry$' || kind create cluster --name model-registry | ||
| kubectl config use-context kind-model-registry | ||
|
|
||
| # Start Tilt (auto-downloads if not installed): | ||
| cd devenv && make tilt-up | ||
| ``` | ||
|
|
||
| ### 2. Start BFF | ||
|
|
||
| ```bash | ||
| cd clients/ui/bff | ||
| go run ./cmd --port=4000 --dev-mode \ | ||
| --dev-mode-model-registry-port=8080 \ | ||
| --dev-mode-catalog-port=8082 \ | ||
| --deployment-mode=standalone | ||
| ``` | ||
|
|
||
| Add `--mock-k8s-client` if you don't need a real cluster for basic UI testing. | ||
|
|
||
| ### 3. Start Frontend | ||
|
|
||
| ```bash | ||
| cd clients/ui/frontend | ||
| DEPLOYMENT_MODE=standalone STYLE_THEME=patternfly npm run start:dev | ||
| ``` | ||
|
|
||
| ### 4. RBAC Setup (real K8s only) | ||
|
|
||
| When using the real K8s client, the BFF's namespace registry access check uses SubjectAccessReview with only the `User` field (no groups), so group-based RoleBindings don't take effect. Create a ClusterRoleBinding that directly binds each namespace's default ServiceAccount: | ||
|
|
||
| ```bash | ||
| kubectl apply -f - <<EOF | ||
| apiVersion: rbac.authorization.k8s.io/v1 | ||
| kind: ClusterRoleBinding | ||
| metadata: | ||
| name: model-registry-all-sa-service-access | ||
| roleRef: | ||
| apiGroup: rbac.authorization.k8s.io | ||
| kind: ClusterRole | ||
| name: model-registry-ui-services-reader | ||
| subjects: | ||
| - kind: ServiceAccount | ||
| name: default | ||
| namespace: default | ||
| - kind: ServiceAccount | ||
| name: default | ||
| namespace: kubeflow | ||
| - kind: ServiceAccount | ||
| name: default | ||
| namespace: minio | ||
| - kind: ServiceAccount | ||
| name: default | ||
| namespace: kube-system | ||
| - kind: ServiceAccount | ||
| name: default | ||
| namespace: kube-public | ||
| - kind: ServiceAccount | ||
| name: default | ||
| namespace: kube-node-lease | ||
| - kind: ServiceAccount | ||
| name: default | ||
| namespace: local-path-storage | ||
| EOF | ||
| ``` | ||
|
|
||
| Without this, the UI shows "The selected namespace does not have access to this model registry" for every namespace. | ||
|
|
||
| ## Optional Components | ||
|
|
||
| ### Model Catalog (with performance data) | ||
|
|
||
| ```bash | ||
| ./scripts/deploy_catalog_demo_on_kind.sh | ||
| kubectl port-forward -n model-catalog svc/model-catalog-server 8082:8080 | ||
| ``` | ||
|
|
||
| The BFF connects to this on `--dev-mode-catalog-port=8082`. See [deploy_catalog_demo_on_kind.sh](../scripts/deploy_catalog_demo_on_kind.sh) for details. | ||
|
|
||
| ### MinIO (S3 storage for transfer jobs) | ||
|
|
||
| ```bash | ||
| ./scripts/deploy_minio_on_kind.sh | ||
| ``` | ||
|
|
||
| | Detail | Value | | ||
| |--------|-------| | ||
| | Internal endpoint | `http://minio.minio.svc.cluster.local:9000` | | ||
| | Bucket | `default` | | ||
| | Credentials | `minioadmin` / `minioadmin` | | ||
| | Console NodePort | `30091` | | ||
| | K8s Secret | `minio-secret` (namespace: `minio`) | | ||
|
|
||
| Upload test data: | ||
|
|
||
| ```bash | ||
| kubectl run minio-upload --rm -i --restart=Never -n minio \ | ||
| --image=minio/mc --command -- sh -c ' | ||
| mc --config-dir /tmp alias set local http://minio:9000 minioadmin minioadmin | ||
| echo "sample model content" | mc --config-dir /tmp pipe local/default/models/sample-model/model.txt | ||
| ' | ||
| ``` | ||
|
|
||
| ### OCI Model Transfer Jobs | ||
|
|
||
| Test S3-to-OCI model transfer jobs end-to-end. Requires MinIO (above) and a destination OCI registry (e.g. quay.io). | ||
|
|
||
| No local ARM64 image build is needed — upstream, midstream, and downstream each have their own async-upload images. | ||
|
|
||
| **Form values when creating a transfer job via UI:** | ||
|
|
||
| | Field | Value | Notes | | ||
| |-------|-------|-------| | ||
| | Source type | `s3` | | | ||
| | S3 endpoint | `http://minio.minio:9000` | Internal cluster DNS | | ||
| | S3 bucket | `default` | | | ||
| | S3 key | `models/sample-model/` | Directory prefix, **not** full file path | | ||
| | S3 access key | `minioadmin` | | | ||
| | S3 secret key | `minioadmin` | | | ||
| | Destination type | `oci` | | | ||
| | Destination URI | `quay.io/yourorg/yourrepo:tag` | OCI ref format, **no** `https://` | | ||
| | Destination registry | `quay.io` | | | ||
|
|
||
| ## Teardown | ||
|
|
||
| ```bash | ||
| # Stop everything and delete cluster: | ||
| ./scripts/dev_teardown.sh | ||
|
|
||
| # Or keep the cluster for quick restart: | ||
| ./scripts/dev_teardown.sh --keep-cluster | ||
| ``` | ||
|
|
||
| Override default ports with environment variables: | ||
|
|
||
| ```bash | ||
| FRONTEND_PORT=9001 BFF_PORT=4001 ./scripts/dev_teardown.sh | ||
| ``` | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| | Problem | Fix | | ||
| |---------|-----| | ||
| | Tilt refuses to start (production context) | `kubectl config use-context kind-model-registry` | | ||
| | Port conflict (4000, 9000, or 10350) | `lsof -ti:PORT \| xargs kill -9` | | ||
| | Frontend proxy `ECONNREFUSED` | BFF not ready yet; wait for it to start | | ||
| | `ImagePullBackOff` on async-upload job | Verify the correct image is configured for your environment (upstream/midstream/downstream each have their own) | | ||
| | "namespace does not have access to this model registry" | Apply the RBAC ClusterRoleBinding (see above). The BFF's SAR uses `User` only, not groups. | | ||
| | MinIO nodePort 30091 already allocated | MinIO already exists in `minio` namespace. Don't apply without `-n minio` or it creates a duplicate in `default`. | | ||
| | MinIO bucket missing after pod restart | MinIO has no PV. Re-run: `./scripts/deploy_minio_on_kind.sh` | | ||
| | `envtest` port lock error in Go tests | `rm -f ~/Library/Caches/kubebuilder-envtest/port-*` | | ||
| | Transfer job S3 download fails with EBUSY | Use directory prefix as source key, not full file path | | ||
| | Transfer job OCI push "invalid reference" | Use OCI ref format `quay.io/org/repo:tag`, not web URL | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| #!/usr/bin/env bash | ||
| # Run a kind cluster with Model Catalog demo overlay (full performance data). | ||
| # Prerequisites: Docker (or Colima) running, kind and kubectl installed. | ||
|
|
||
| set -e | ||
|
|
||
| CATALOG_NAMESPACE="${CATALOG_NAMESPACE:-model-catalog}" | ||
| CLUSTER_NAME="${CLUSTER_NAME:-model-registry}" | ||
| REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" | ||
|
|
||
| cd "$REPO_ROOT" | ||
|
|
||
| echo "=== Creating kind cluster (if needed) ===" | ||
| if kind get clusters 2>/dev/null | grep -q "^${CLUSTER_NAME}$"; then | ||
| echo "Cluster ${CLUSTER_NAME} already exists." | ||
| kubectl config use-context "kind-${CLUSTER_NAME}" | ||
| else | ||
| kind create cluster --name "$CLUSTER_NAME" | ||
| fi | ||
|
|
||
| echo "=== Creating namespace ${CATALOG_NAMESPACE} ===" | ||
| kubectl create namespace "$CATALOG_NAMESPACE" --dry-run=client -o yaml | kubectl apply -f - | ||
|
|
||
| echo "=== Deploying Model Catalog with demo overlay (full performance data) ===" | ||
| kubectl apply -k manifests/kustomize/options/catalog/overlays/demo -n "$CATALOG_NAMESPACE" | ||
|
|
||
| echo "=== Waiting for Model Catalog Postgres to be ready ===" | ||
| kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=postgres,app.kubernetes.io/part-of=model-catalog -n "$CATALOG_NAMESPACE" --timeout=120s 2>/dev/null || true | ||
| echo "=== Waiting for Model Catalog server (with perf data) to be available ===" | ||
| kubectl wait --for=condition=available deployment/model-catalog-server -n "$CATALOG_NAMESPACE" --timeout=5m | ||
|
|
||
| echo "=== Done ===" | ||
| kubectl get pods -n "$CATALOG_NAMESPACE" | ||
| echo "" | ||
| echo "To access the Model Catalog API (with performance metrics):" | ||
| echo " kubectl port-forward -n $CATALOG_NAMESPACE svc/model-catalog-server 8080:8080" | ||
| echo "Then open http://localhost:8080 (or use the API with performance-metrics from /perf-data)." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| #!/usr/bin/env bash | ||
| # Tear down the model-registry dev environment. | ||
| # Stops Frontend, BFF, and Tilt. Optionally deletes the Kind cluster. | ||
| # | ||
| # Usage: | ||
| # ./scripts/dev_teardown.sh # Stop everything, delete cluster | ||
| # ./scripts/dev_teardown.sh --keep-cluster # Stop processes, keep cluster | ||
| # | ||
| # Environment variables (override default ports): | ||
| # FRONTEND_PORT (default: 9000) | ||
| # BFF_PORT (default: 4000) | ||
|
|
||
| set -e | ||
|
|
||
| FRONTEND_PORT="${FRONTEND_PORT:-9000}" | ||
| BFF_PORT="${BFF_PORT:-4000}" | ||
| CLUSTER_NAME="${CLUSTER_NAME:-model-registry}" | ||
| KEEP_CLUSTER=false | ||
| REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" | ||
|
|
||
| for arg in "$@"; do | ||
| case "$arg" in | ||
| --keep-cluster) KEEP_CLUSTER=true ;; | ||
| esac | ||
| done | ||
|
|
||
| cd "$REPO_ROOT" | ||
|
|
||
| echo "=== Stopping Frontend (port ${FRONTEND_PORT}) ===" | ||
| lsof -ti:"${FRONTEND_PORT}" | xargs kill -9 2>/dev/null || true | ||
|
|
||
| echo "=== Stopping BFF (port ${BFF_PORT}) ===" | ||
| lsof -ti:"${BFF_PORT}" | xargs kill -9 2>/dev/null || true | ||
|
|
||
| echo "=== Stopping Tilt ===" | ||
| cd devenv && make tilt-down 2>/dev/null || true | ||
| cd "$REPO_ROOT" | ||
|
|
||
| if [ "$KEEP_CLUSTER" = false ]; then | ||
| echo "=== Deleting Kind cluster '${CLUSTER_NAME}' ===" | ||
| kind delete cluster --name "$CLUSTER_NAME" | ||
|
|
||
| echo "=== Stopping Colima ===" | ||
| colima stop 2>/dev/null || true | ||
| else | ||
| echo "=== Keeping Kind cluster and Colima running ===" | ||
| fi | ||
|
|
||
| echo "=== Done ===" | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.