From 74eb6fc02deeb8c26b867d263178008480e237c0 Mon Sep 17 00:00:00 2001 From: Rishi Jat Date: Thu, 26 Feb 2026 05:40:54 +0530 Subject: [PATCH 1/3] docs: add Kubeflow Model Registry integration guide Signed-off-by: Rishi Jat --- docs/.vitepress/config.mts | 1 + docs/src/docs/integrations/integrations.md | 2 + .../integrations/kubeflow-model-registry.md | 472 ++++++++++++++++++ 3 files changed, 475 insertions(+) create mode 100644 docs/src/docs/integrations/kubeflow-model-registry.md diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 7cc282dff..d68351820 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -135,6 +135,7 @@ export default defineConfig({ { text: 'Kubernetes - initContainer', link: '/docs/integrations/k8s-init-container/' }, { text: 'KServe', link: '/docs/integrations/kserve/' }, { text: 'Kubeflow Pipelines', link: '/docs/integrations/kubeflow/' }, + { text: 'Kubeflow Model Registry', link: '/docs/integrations/kubeflow-model-registry/' }, { text: 'ModelPack', link: '/docs/integrations/modelpack/' }, ] }, diff --git a/docs/src/docs/integrations/integrations.md b/docs/src/docs/integrations/integrations.md index db91ece82..4e702d765 100644 --- a/docs/src/docs/integrations/integrations.md +++ b/docs/src/docs/integrations/integrations.md @@ -19,6 +19,7 @@ The KitOps community has built some great integrations: - Deploying to any [Kubernetes distribution](../k8s-init-container.md) - Working with ML in [KServe](../kserve.md) - Building ML pipelines with [Kubeflow Pipeline components](../kubeflow.md) +- Model versioning with [Kubeflow Model Registry](../kubeflow-model-registry.md) ## 🗄️ KitOps Compliant OCI Registries (A-Z) @@ -108,3 +109,4 @@ Thanks to its OCI-compatibility, KitOps works nearly any tool: If you've used KitOps with a product or project we've missed, please [open an issue](https://github.com/jozu-ai/kitops/issues/new/choose) in our GitHub repository. For help please join our [Discord community](https://discord.gg/Tapeh8agYy). + diff --git a/docs/src/docs/integrations/kubeflow-model-registry.md b/docs/src/docs/integrations/kubeflow-model-registry.md new file mode 100644 index 000000000..9bbaf249e --- /dev/null +++ b/docs/src/docs/integrations/kubeflow-model-registry.md @@ -0,0 +1,472 @@ +--- +title: KitOps Integration with Kubeflow Model Registry +description: Learn how to use KitOps ModelKits with Kubeflow Model Registry for model versioning, discovery, and deployment in Kubeflow environments. +keywords: kubeflow model registry, modelkit kubeflow, oci model registry, ml model versioning, kubeflow kitops integration, model artifact management, kubeflow oci storage, modelpack kubeflow +--- + +# Integrating KitOps with Kubeflow Model Registry + +KitOps ModelKits and the Kubeflow Model Registry both use OCI-compliant storage to manage machine learning artifacts. This guide shows how to package models with KitOps and register them in the Kubeflow Model Registry for tracking, versioning, and downstream use within Kubeflow workflows. + +## Overview + +This integration workflow: + +1. **Packages** models, datasets, code, and configuration as OCI-compliant ModelKits using KitOps +2. **Pushes** ModelKits to an OCI-compatible registry +3. **Registers** the ModelKit URI in Kubeflow Model Registry for centralized tracking +4. **Discovers** and retrieves models via the Model Registry API +5. **Deploys** models using KServe or other Kubeflow components + +``` +Local Model → kit pack → OCI Registry → Model Registry → Kubeflow Pipelines/KServe +``` + +## Prerequisites + +- [KitOps CLI installed](../cli/installation.md) +- Kubernetes cluster with [Kubeflow](https://www.kubeflow.org/docs/started/installing-kubeflow/) installed +- [Kubeflow Model Registry](https://www.kubeflow.org/docs/components/model-registry/installation/) deployed +- Access to an OCI-compatible registry +- `kubectl` configured to access your cluster +- Python >= 3.9 (for Model Registry client) + +## Environment Setup + +### Local Setup + +Install and verify the KitOps CLI: + +```sh +# Verify installation +kit version + +# Log in to your OCI registry +kit login jozu.ml +``` + +### Kubeflow Setup + +Install the Model Registry Python client in your notebook or pipeline environment: + +```sh +pip install model-registry=="0.3.5" +``` + +Verify connectivity to Model Registry from within a Kubeflow Notebook: + +```sh +curl http://model-registry-service.kubeflow.svc.cluster.local:8080/api/model_registry/v1alpha3/registered_models +``` + +## Workflow + +### Step 1: Create and Package a ModelKit + +Prepare your model artifacts and create a Kitfile: + +```yaml +# Kitfile +manifestVersion: 1.0.0 + +package: + name: iris-classifier + version: 1.0.0 + description: Iris species classification model + authors: + - ML Team + +model: + name: sklearn-iris + path: ./model/iris_model.joblib + framework: scikit-learn + version: "1.0" + license: Apache-2.0 + +datasets: + - name: training-data + path: ./data/iris_train.csv + description: Training dataset for iris classifier + +docs: + - path: ./README.md +``` + +Pack the ModelKit: + +```sh +kit pack . -t jozu.ml/my-org/iris-classifier:v1.0.0 +``` + +Verify the ModelKit: + +```sh +kit list +``` + +### Step 2: Push to OCI Registry + +Push the ModelKit to your registry: + +```sh +kit push jozu.ml/my-org/iris-classifier:v1.0.0 +``` + +Get the digest for immutable referencing: + +```sh +kit inspect jozu.ml/my-org/iris-classifier:v1.0.0 +``` + +### Step 3: Register in Kubeflow Model Registry + +Use the Model Registry Python client to register the ModelKit: + +```python +from model_registry import ModelRegistry + +# Connect to Model Registry +registry = ModelRegistry( + server_address="http://model-registry-service.kubeflow.svc.cluster.local", + port=8080, + author="ml-team", + is_secure=False +) + +# Register the ModelKit with its OCI URI +rm = registry.register_model( + "iris-classifier", + "oci://jozu.ml/my-org/iris-classifier:v1.0.0", # OCI URI to ModelKit + model_format_name="sklearn", + model_format_version="1", + version="v1.0.0", + description="Iris species classification model packaged with KitOps", + metadata={ + "framework": "scikit-learn", + "packaged_with": "kitops", + "license": "Apache-2.0", + } +) + +print(f"Registered model with ID: {rm.id}") +``` + +### Step 4: Discover and Query Models + +Retrieve model metadata from the registry: + +```python +# Get the registered model +model = registry.get_registered_model("iris-classifier") +print(f"Model: {model.name}, ID: {model.id}") + +# Get a specific version +version = registry.get_model_version("iris-classifier", "v1.0.0") +print(f"Version: {version.name}, ID: {version.id}") + +# Get the artifact details (including the OCI URI) +artifact = registry.get_model_artifact("iris-classifier", "v1.0.0") +print(f"Artifact URI: {artifact.uri}") +``` + +List all registered models: + +```python +models = registry.get_registered_models() +for m in models: + print(f"- {m.name}") +``` + +### Step 5: Pull and Use ModelKits + +Once you have the OCI URI from the registry, use KitOps to retrieve the model: + +```sh +# Pull the ModelKit +kit pull jozu.ml/my-org/iris-classifier:v1.0.0 + +# Unpack to a directory +kit unpack jozu.ml/my-org/iris-classifier:v1.0.0 -d ./model-artifacts +``` + +Unpack only specific components: + +```sh +# Unpack only the model +kit unpack jozu.ml/my-org/iris-classifier:v1.0.0 --filter=model -d ./model-only + +# Unpack only datasets +kit unpack jozu.ml/my-org/iris-classifier:v1.0.0 --filter=datasets -d ./data-only +``` + +## Using ModelKits in Kubeflow Pipelines + +### Pipeline Component for Unpacking ModelKits + +Create a reusable component to unpack ModelKits within your pipeline: + +```python +from kfp import dsl, kubernetes + +@dsl.container_component +def unpack_modelkit( + modelkit_reference: str, + extract_path: str, +) -> dsl.ContainerSpec: + return dsl.ContainerSpec( + image='ghcr.io/kitops-ml/kitops:latest', + command=['kit'], + args=['unpack', modelkit_reference, '-d', extract_path, '-o'], + ) +``` + +Use in a pipeline: + +```python +@dsl.pipeline(name="inference-pipeline") +def inference_pipeline(model_ref: str = "jozu.ml/my-org/iris-classifier:v1.0.0"): + # Unpack the ModelKit + unpack_task = unpack_modelkit( + modelkit_reference=model_ref, + extract_path="/tmp/model", + ) + + # Mount registry credentials + kubernetes.use_secret_as_volume( + unpack_task, + secret_name='docker-config', + mount_path='/home/user/.docker', + ) + + # Continue with inference using unpacked model... +``` + +### Integration with KServe + +After registering a ModelKit in the Model Registry, deploy it with KServe. For KitOps-based model storage, use the [KitOps KServe integration](./kserve.md): + +```yaml +apiVersion: serving.kserve.io/v1beta1 +kind: InferenceService +metadata: + name: iris-classifier + labels: + modelregistry/registered-model-id: "1" + modelregistry/model-version-id: "1" +spec: + predictor: + model: + modelFormat: + name: sklearn + storageUri: kit://jozu.ml/my-org/iris-classifier:v1.0.0 +``` + +## Version Management + +### Tagging Strategy + +Use semantic versioning for ModelKit tags: + +```sh +# Development versions +kit pack . -t jozu.ml/my-org/iris-classifier:dev +kit pack . -t jozu.ml/my-org/iris-classifier:v1.0.0-rc1 + +# Release versions +kit pack . -t jozu.ml/my-org/iris-classifier:v1.0.0 +kit pack . -t jozu.ml/my-org/iris-classifier:latest +``` + +Register each version in Model Registry: + +```python +# Register v1.0.0 +registry.register_model( + "iris-classifier", + "oci://jozu.ml/my-org/iris-classifier:v1.0.0", + model_format_name="sklearn", + model_format_version="1", + version="v1.0.0", + description="Initial release", +) + +# Register v1.1.0 +registry.register_model( + "iris-classifier", + "oci://jozu.ml/my-org/iris-classifier:v1.1.0", + model_format_name="sklearn", + model_format_version="1", + version="v1.1.0", + description="Improved accuracy with additional training data", +) +``` + +### Digest-Based References + +For production deployments, use digest-based references for immutability: + +```python +# Get the digest from kit inspect output +digest_ref = "jozu.ml/my-org/iris-classifier@sha256:abc123..." + +registry.register_model( + "iris-classifier", + f"oci://{digest_ref}", + model_format_name="sklearn", + model_format_version="1", + version="v1.0.0-stable", + description="Production-pinned release", +) +``` + +## Registry Authentication + +### Creating Registry Secrets + +For Kubeflow components to access your OCI registry: + +```sh +kubectl create secret docker-registry oci-registry-creds \ + --docker-server=jozu.ml \ + --docker-username=myuser \ + --docker-password=mypassword \ + --docker-email=user@example.com \ + --namespace=kubeflow +``` + +Or use an existing Docker config: + +```sh +kubectl create secret generic docker-config \ + --from-file=config.json="$HOME/.docker/config.json" \ + --namespace=kubeflow +``` + +### Using Secrets in Pipelines + +Mount the secret in your pipeline components: + +```python +kubernetes.use_secret_as_volume( + unpack_task, + secret_name='docker-config', + mount_path='/home/user/.docker', +) +``` + +## End-to-End Example + +Complete workflow from training to deployment: + +```python +from model_registry import ModelRegistry +import subprocess + +# 1. Pack the trained model +subprocess.run([ + "kit", "pack", ".", + "-t", "jozu.ml/my-org/churn-predictor:v1.0.0" +], check=True) + +# 2. Push to registry +subprocess.run([ + "kit", "push", "jozu.ml/my-org/churn-predictor:v1.0.0" +], check=True) + +# 3. Register in Model Registry +registry = ModelRegistry( + server_address="http://model-registry-service.kubeflow.svc.cluster.local", + port=8080, + author="data-science-team", + is_secure=False +) + +rm = registry.register_model( + "churn-predictor", + "oci://jozu.ml/my-org/churn-predictor:v1.0.0", + model_format_name="xgboost", + model_format_version="1", + version="v1.0.0", + description="Customer churn prediction model", + metadata={ + "accuracy": "0.94", + "auc": "0.97", + "training_date": "2025-02-01", + } +) + +# 4. Query the model +artifact = registry.get_model_artifact("churn-predictor", "v1.0.0") +print(f"Model registered at: {artifact.uri}") + +# 5. Pull for inference +subprocess.run([ + "kit", "unpack", "jozu.ml/my-org/churn-predictor:v1.0.0", + "-d", "/tmp/model", "-o" +], check=True) +``` + +## Troubleshooting + +### Authentication Errors + +**Symptom:** `unauthorized: authentication required` when pushing or pulling. + +**Solution:** +```sh +# Re-authenticate with the registry +kit login jozu.ml + +# Verify access by inspecting a remote artifact +kit inspect --remote jozu.ml/my-org/iris-classifier:v1.0.0 +``` + +### Model Registry Connection Failures + +**Symptom:** Cannot connect to Model Registry service. + +**Solution:** +```sh +# Verify the service is running +kubectl get pods -n kubeflow -l app=model-registry + +# Check service endpoint +kubectl get svc model-registry-service -n kubeflow +``` + +### ModelKit Not Found + +**Symptom:** `manifest unknown` when pulling a ModelKit. + +**Solution:** +```sh +# Verify the ModelKit exists +kit list jozu.ml/my-org/model-name + +# Check the exact tag +kit inspect --remote jozu.ml/my-org/model-name:tag +``` + +### OCI URI Format + +**Symptom:** Model Registry does not recognize the artifact URI. + +**Solution:** Ensure the URI uses the correct format: +- For OCI artifacts: `oci://registry/repository:tag` +- For digests: `oci://registry/repository@sha256:...` + +## Best Practices + +1. **Version everything**: Tag ModelKits with semantic versions and register each version in Model Registry. + +2. **Use digests in production**: Pin production deployments to digest-based references for immutability. + +3. **Include metadata**: Add training metrics, hyperparameters, and lineage information when registering models. + +4. **Automate registration**: Integrate ModelKit packing and registration into CI/CD pipelines. + +5. **Secure credentials**: Use Kubernetes secrets for registry authentication; never hardcode credentials. + +6. **Selective unpacking**: Use `--filter` flags to extract only the components you need, reducing storage and transfer overhead. + +--- \ No newline at end of file From f1cf2fc57ed558b43982f17811e1c2e37e78a8bc Mon Sep 17 00:00:00 2001 From: Rishi Jat Date: Thu, 26 Feb 2026 17:21:18 +0530 Subject: [PATCH 2/3] docs: make registry examples environment-agnostic and clarify validation scope Signed-off-by: Rishi Jat --- .../integrations/kubeflow-model-registry.md | 81 +++++++++++-------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/docs/src/docs/integrations/kubeflow-model-registry.md b/docs/src/docs/integrations/kubeflow-model-registry.md index 9bbaf249e..de22a87c3 100644 --- a/docs/src/docs/integrations/kubeflow-model-registry.md +++ b/docs/src/docs/integrations/kubeflow-model-registry.md @@ -24,12 +24,15 @@ Local Model → kit pack → OCI Registry → Model Registry → Kubeflow Pipeli ## Prerequisites -- [KitOps CLI installed](../cli/installation.md) +- [KitOps CLI installed](../../cli/installation.md) - Kubernetes cluster with [Kubeflow](https://www.kubeflow.org/docs/started/installing-kubeflow/) installed - [Kubeflow Model Registry](https://www.kubeflow.org/docs/components/model-registry/installation/) deployed - Access to an OCI-compatible registry - `kubectl` configured to access your cluster - Python >= 3.9 (for Model Registry client) +- Kubeflow Pipelines SDK (`kfp`) installed for pipeline examples + +> Note: If your OCI registry is private, configure Kubernetes imagePullSecrets or registry credentials for Kubeflow workloads before proceeding. See the **Registry Authentication** section below. ## Environment Setup @@ -42,7 +45,7 @@ Install and verify the KitOps CLI: kit version # Log in to your OCI registry -kit login jozu.ml +kit login ``` ### Kubeflow Setup @@ -50,13 +53,14 @@ kit login jozu.ml Install the Model Registry Python client in your notebook or pipeline environment: ```sh -pip install model-registry=="0.3.5" +pip install "model-registry>=0.3" ``` Verify connectivity to Model Registry from within a Kubeflow Notebook: ```sh -curl http://model-registry-service.kubeflow.svc.cluster.local:8080/api/model_registry/v1alpha3/registered_models +# Replace with your Model Registry service endpoint +curl /api/model_registry/v1alpha3/registered_models ``` ## Workflow @@ -95,7 +99,7 @@ docs: Pack the ModelKit: ```sh -kit pack . -t jozu.ml/my-org/iris-classifier:v1.0.0 +kit pack . -t //iris-classifier:v1.0.0 ``` Verify the ModelKit: @@ -109,13 +113,13 @@ kit list Push the ModelKit to your registry: ```sh -kit push jozu.ml/my-org/iris-classifier:v1.0.0 +kit push //iris-classifier:v1.0.0 ``` Get the digest for immutable referencing: ```sh -kit inspect jozu.ml/my-org/iris-classifier:v1.0.0 +kit inspect //iris-classifier:v1.0.0 ``` ### Step 3: Register in Kubeflow Model Registry @@ -127,7 +131,8 @@ from model_registry import ModelRegistry # Connect to Model Registry registry = ModelRegistry( - server_address="http://model-registry-service.kubeflow.svc.cluster.local", + # Replace with your Model Registry service endpoint + server_address="", port=8080, author="ml-team", is_secure=False @@ -136,7 +141,7 @@ registry = ModelRegistry( # Register the ModelKit with its OCI URI rm = registry.register_model( "iris-classifier", - "oci://jozu.ml/my-org/iris-classifier:v1.0.0", # OCI URI to ModelKit + "oci:////iris-classifier:v1.0.0", # OCI URI to ModelKit model_format_name="sklearn", model_format_version="1", version="v1.0.0", @@ -183,20 +188,20 @@ Once you have the OCI URI from the registry, use KitOps to retrieve the model: ```sh # Pull the ModelKit -kit pull jozu.ml/my-org/iris-classifier:v1.0.0 +kit pull //iris-classifier:v1.0.0 # Unpack to a directory -kit unpack jozu.ml/my-org/iris-classifier:v1.0.0 -d ./model-artifacts +kit unpack //iris-classifier:v1.0.0 -d ./model-artifacts ``` Unpack only specific components: ```sh # Unpack only the model -kit unpack jozu.ml/my-org/iris-classifier:v1.0.0 --filter=model -d ./model-only +kit unpack //iris-classifier:v1.0.0 --filter=model -d ./model-only # Unpack only datasets -kit unpack jozu.ml/my-org/iris-classifier:v1.0.0 --filter=datasets -d ./data-only +kit unpack //iris-classifier:v1.0.0 --filter=datasets -d ./data-only ``` ## Using ModelKits in Kubeflow Pipelines @@ -224,7 +229,7 @@ Use in a pipeline: ```python @dsl.pipeline(name="inference-pipeline") -def inference_pipeline(model_ref: str = "jozu.ml/my-org/iris-classifier:v1.0.0"): +def inference_pipeline(model_ref: str = "//iris-classifier:v1.0.0"): # Unpack the ModelKit unpack_task = unpack_modelkit( modelkit_reference=model_ref, @@ -243,7 +248,7 @@ def inference_pipeline(model_ref: str = "jozu.ml/my-org/iris-classifier:v1.0.0") ### Integration with KServe -After registering a ModelKit in the Model Registry, deploy it with KServe. For KitOps-based model storage, use the [KitOps KServe integration](./kserve.md): +After registering a ModelKit in the Model Registry, deploy it with KServe. For KitOps-based model storage, use the [KitOps KServe integration](../kserve.md): ```yaml apiVersion: serving.kserve.io/v1beta1 @@ -258,7 +263,7 @@ spec: model: modelFormat: name: sklearn - storageUri: kit://jozu.ml/my-org/iris-classifier:v1.0.0 + storageUri: kit:////iris-classifier:v1.0.0 ``` ## Version Management @@ -269,12 +274,12 @@ Use semantic versioning for ModelKit tags: ```sh # Development versions -kit pack . -t jozu.ml/my-org/iris-classifier:dev -kit pack . -t jozu.ml/my-org/iris-classifier:v1.0.0-rc1 +kit pack . -t //iris-classifier:dev +kit pack . -t //iris-classifier:v1.0.0-rc1 # Release versions -kit pack . -t jozu.ml/my-org/iris-classifier:v1.0.0 -kit pack . -t jozu.ml/my-org/iris-classifier:latest +kit pack . -t //iris-classifier:v1.0.0 +kit pack . -t //iris-classifier:latest ``` Register each version in Model Registry: @@ -283,7 +288,7 @@ Register each version in Model Registry: # Register v1.0.0 registry.register_model( "iris-classifier", - "oci://jozu.ml/my-org/iris-classifier:v1.0.0", + "oci:////iris-classifier:v1.0.0", model_format_name="sklearn", model_format_version="1", version="v1.0.0", @@ -293,7 +298,7 @@ registry.register_model( # Register v1.1.0 registry.register_model( "iris-classifier", - "oci://jozu.ml/my-org/iris-classifier:v1.1.0", + "oci:////iris-classifier:v1.1.0", model_format_name="sklearn", model_format_version="1", version="v1.1.0", @@ -307,7 +312,7 @@ For production deployments, use digest-based references for immutability: ```python # Get the digest from kit inspect output -digest_ref = "jozu.ml/my-org/iris-classifier@sha256:abc123..." +digest_ref = "//iris-classifier@sha256:abc123..." registry.register_model( "iris-classifier", @@ -327,7 +332,7 @@ For Kubeflow components to access your OCI registry: ```sh kubectl create secret docker-registry oci-registry-creds \ - --docker-server=jozu.ml \ + --docker-server= \ --docker-username=myuser \ --docker-password=mypassword \ --docker-email=user@example.com \ @@ -365,17 +370,18 @@ import subprocess # 1. Pack the trained model subprocess.run([ "kit", "pack", ".", - "-t", "jozu.ml/my-org/churn-predictor:v1.0.0" + "-t", "//churn-predictor:v1.0.0" ], check=True) # 2. Push to registry subprocess.run([ - "kit", "push", "jozu.ml/my-org/churn-predictor:v1.0.0" + "kit", "push", "//churn-predictor:v1.0.0" ], check=True) # 3. Register in Model Registry registry = ModelRegistry( - server_address="http://model-registry-service.kubeflow.svc.cluster.local", + # Replace with your Model Registry service endpoint + server_address="", port=8080, author="data-science-team", is_secure=False @@ -383,7 +389,7 @@ registry = ModelRegistry( rm = registry.register_model( "churn-predictor", - "oci://jozu.ml/my-org/churn-predictor:v1.0.0", + "oci:////churn-predictor:v1.0.0", model_format_name="xgboost", model_format_version="1", version="v1.0.0", @@ -401,7 +407,7 @@ print(f"Model registered at: {artifact.uri}") # 5. Pull for inference subprocess.run([ - "kit", "unpack", "jozu.ml/my-org/churn-predictor:v1.0.0", + "kit", "unpack", "//churn-predictor:v1.0.0", "-d", "/tmp/model", "-o" ], check=True) ``` @@ -415,10 +421,10 @@ subprocess.run([ **Solution:** ```sh # Re-authenticate with the registry -kit login jozu.ml +kit login # Verify access by inspecting a remote artifact -kit inspect --remote jozu.ml/my-org/iris-classifier:v1.0.0 +kit inspect --remote //iris-classifier:v1.0.0 ``` ### Model Registry Connection Failures @@ -441,10 +447,10 @@ kubectl get svc model-registry-service -n kubeflow **Solution:** ```sh # Verify the ModelKit exists -kit list jozu.ml/my-org/model-name +kit list //model-name # Check the exact tag -kit inspect --remote jozu.ml/my-org/model-name:tag +kit inspect --remote //model-name:tag ``` ### OCI URI Format @@ -469,4 +475,11 @@ kit inspect --remote jozu.ml/my-org/model-name:tag 6. **Selective unpacking**: Use `--filter` flags to extract only the components you need, reducing storage and transfer overhead. ---- \ No newline at end of file +## Tested With + +This guide was validated conceptually against: +- KitOps CLI: latest +- Kubeflow: v1.x +- Kubeflow Model Registry: v1alpha3 API + +Update with exact versions after environment validation. \ No newline at end of file From 9ca6ee383b0bf3a3f86354975199746ee225ab5f Mon Sep 17 00:00:00 2001 From: Rishi Jat Date: Thu, 26 Feb 2026 17:36:44 +0530 Subject: [PATCH 3/3] docs: polish Kubeflow Model Registry integration guide (fix commands, URLs, and troubleshooting) Signed-off-by: Rishi Jat --- .../integrations/kubeflow-model-registry.md | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/docs/src/docs/integrations/kubeflow-model-registry.md b/docs/src/docs/integrations/kubeflow-model-registry.md index de22a87c3..8df97d39e 100644 --- a/docs/src/docs/integrations/kubeflow-model-registry.md +++ b/docs/src/docs/integrations/kubeflow-model-registry.md @@ -18,8 +18,12 @@ This integration workflow: 4. **Discovers** and retrieves models via the Model Registry API 5. **Deploys** models using KServe or other Kubeflow components -``` -Local Model → kit pack → OCI Registry → Model Registry → Kubeflow Pipelines/KServe +```mermaid +graph LR + A[Local Model] -->|kit pack| B[ModelKit] + B -->|kit push| C[OCI Registry] + C -->|Register URI| D[Kubeflow Model Registry] + D -->|Reference| E[Kubeflow Pipelines/KServe] ``` ## Prerequisites @@ -62,6 +66,13 @@ Verify connectivity to Model Registry from within a Kubeflow Notebook: # Replace with your Model Registry service endpoint curl /api/model_registry/v1alpha3/registered_models ``` +`` must include the protocol (for example, `http://` or `https://`). + +> For in-cluster notebooks or pipelines, the Model Registry service is typically reachable via the Kubernetes DNS name: +> +> `http://model-registry-service.kubeflow.svc.cluster.local:8080` +> +> External access may instead use a LoadBalancer or Ingress endpoint depending on your Kubeflow installation. ## Workflow @@ -75,7 +86,7 @@ manifestVersion: 1.0.0 package: name: iris-classifier - version: 1.0.0 + version: v1.0.0 description: Iris species classification model authors: - ML Team @@ -204,6 +215,8 @@ kit unpack //iris-classifier:v1.0.0 --filter=model -d ./model-onl kit unpack //iris-classifier:v1.0.0 --filter=datasets -d ./data-only ``` +The commands above demonstrate manual CLI usage. In Kubeflow environments, these steps are typically executed inside pipeline containers or notebook workloads as shown below. + ## Using ModelKits in Kubeflow Pipelines ### Pipeline Component for Unpacking ModelKits @@ -239,7 +252,7 @@ def inference_pipeline(model_ref: str = "//iris-classifier:v1.0.0 # Mount registry credentials kubernetes.use_secret_as_volume( unpack_task, - secret_name='docker-config', + secret_name='oci-registry-creds', mount_path='/home/user/.docker', ) @@ -354,7 +367,7 @@ Mount the secret in your pipeline components: ```python kubernetes.use_secret_as_volume( unpack_task, - secret_name='docker-config', + secret_name='oci-registry-creds', mount_path='/home/user/.docker', ) ``` @@ -447,7 +460,7 @@ kubectl get svc model-registry-service -n kubeflow **Solution:** ```sh # Verify the ModelKit exists -kit list //model-name +kit list --remote //model-name # Check the exact tag kit inspect --remote //model-name:tag @@ -477,7 +490,7 @@ kit inspect --remote //model-name:tag ## Tested With -This guide was validated conceptually against: +This guide is based on: - KitOps CLI: latest - Kubeflow: v1.x - Kubeflow Model Registry: v1alpha3 API