diff --git a/README.md b/README.md index ccd8931f7a..14cab83cf8 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ This repository periodically synchronizes all official Kubeflow components from | KServe | applications/kserve/kserve | [v0.15.0](https://github.com/kserve/kserve/releases/tag/v0.15.0/install/v0.15.0) | 600m | 1200Mi | 0GB | | KServe Models Web Application | applications/kserve/models-web-app | [v0.15.0](https://github.com/kserve/models-web-app/tree/v0.15.0/config) | 6m | 259Mi | 0GB | | Kubeflow Pipelines | applications/pipeline/upstream | [2.14.3](https://github.com/kubeflow/pipelines/tree/2.14.3/manifests/kustomize) | 970m | 3552Mi | 35GB | -| Kubeflow Model Registry | applications/model-registry/upstream | [v0.3.0](https://github.com/kubeflow/model-registry/tree/v0.3.0/manifests/kustomize) | 510m | 2112Mi | 20GB | +| Kubeflow Model Registry | applications/model-registry/upstream | [v0.3.2](https://github.com/kubeflow/model-registry/tree/v0.3.2/manifests/kustomize) | 510m | 2112Mi | 20GB | | Spark Operator | applications/spark/spark-operator | [2.3.0](https://github.com/kubeflow/spark-operator/tree/v2.3.0) | 9m | 41Mi | 0GB | | Istio | common/istio | [1.27.0](https://github.com/istio/istio/releases/tag/1.27.0) | 750m | 2364Mi | 0GB | | Knative | common/knative/knative-serving
common/knative/knative-eventing | [v1.16.2](https://github.com/knative/serving/releases/tag/knative-v1.16.2)
[v1.16.4](https://github.com/knative/eventing/releases/tag/knative-v1.16.4) | 1450m | 1038Mi | 0GB | diff --git a/applications/model-registry/upstream/base/kustomization.yaml b/applications/model-registry/upstream/base/kustomization.yaml index bf931e9aee..64bf9030f0 100644 --- a/applications/model-registry/upstream/base/kustomization.yaml +++ b/applications/model-registry/upstream/base/kustomization.yaml @@ -8,4 +8,4 @@ resources: images: - name: ghcr.io/kubeflow/model-registry/server newName: ghcr.io/kubeflow/model-registry/server - newTag: v0.3.0 + newTag: v0.3.2 diff --git a/applications/model-registry/upstream/options/catalog/README.md b/applications/model-registry/upstream/options/catalog/README.md index a3bdeef033..40c6a8a5a6 100644 --- a/applications/model-registry/upstream/options/catalog/README.md +++ b/applications/model-registry/upstream/options/catalog/README.md @@ -1,40 +1,115 @@ # Model Catalog Manifests -To deploy the model catalog: +This directory contains manifests for deploying the Model Catalog using Kustomize. + +## Deployment + +The model catalog manifests deploy a PostgreSQL database, set `POSTGRES_PASSWORD` in `postgres.env` before deploying the manifests. On Linux, you can generate a random password with: ```sh -kubectl apply -k . -n NAMESPACE +(echo POSTGRES_USER=postgres ; echo -n POSTGRES_PASSWORD=; dd if=/dev/random of=/dev/stdout bs=15 count=1 status=none | base64) >base/postgres.env ``` -Replace `NAMESPACE` with your desired Kubernetes namespace. +To deploy the Model Catalog to your Kubernetes cluster (without Kubeflow--see below for Istio support), run the following command from this directory: -## sources.yaml Configuration +```sh +kubectl apply -k base -n +``` -The `sources.yaml` file configures the model catalog sources. It contains a top-level `catalogs` list, where each entry defines a single catalog source. +Replace `` with the Kubernetes namespace where you want to deploy the catalog. -### Common Properties +This command will create: +* A `Deployment` to run the Model Catalog server. +* A `Service` to expose the Model Catalog server. +* A `ConfigMap` named `model-catalog-sources` containing the configuration for the catalog sources. +* A `StatefulSet` with a PostgreSQL database +* A `PersistentVolumeClaim` for PostgreSQL -Each catalog source entry supports the following common properties: +For deployment in a Kubeflow environment with Istio support, use the `overlay` directory instead: -- **`name`** (*string*, required): A user-friendly name for the catalog source. -- **`id`** (*string*, required): A unique identifier for the catalog source. -- **`type`** (*string*, required): The type of catalog source. Supported values are `yaml` and `rhec`. -- **`enabled`** (*boolean*, optional): Whether the catalog source is enabled. Defaults to `true` if not specified. +```sh +kubectl apply -k overlay -n +``` -### Catalog Source Types +## Configuring Catalog Sources -Below are the supported catalog source types and their specific `properties`. +The Model Catalog is configured via the `sources.yaml` file. This file is **not** a Kubernetes manifest itself, but rather a configuration file for the application. -#### `yaml` +When you run `kubectl apply -k .`, Kustomize generates a `ConfigMap` that includes `sources.yaml` and any referenced local YAML catalog files. This `ConfigMap` is then mounted into the Model Catalog pod, making the files available to the application. -The `yaml` type sources model metadata from a local YAML file. +### Adding your own YAML-based catalog + +You can define your own model catalog by providing a YAML file with model definitions. Here's how to add your own catalog source: + +1. **Create your catalog definition file.** Create a new YAML file with your model definitions. You can use `sample-catalog.yaml` as a reference for the format. Let's say you name it `my-catalog.yaml` and place it in this directory. + +2. **Add your file to the ConfigMap.** Edit `kustomization.yaml` to include your new file in the `configMapGenerator`: + + ```yaml + # kustomization.yaml + ... + configMapGenerator: + - behavior: create + files: + - sources.yaml=sources.yaml + - sample-catalog.yaml=sample-catalog.yaml + - my-catalog.yaml=my-catalog.yaml # <-- Add your file here + name: sources + options: + disableNameSuffixHash: true + ``` + +3. **Add a new source entry.** Edit `sources.yaml` to add a new entry for your catalog under the `catalogs` list. + + ```yaml + # sources.yaml + catalogs: + - name: Sample Catalog + id: sample_custom_catalog + type: yaml + enabled: true + properties: + yamlCatalogPath: sample-catalog.yaml + - name: My Custom Catalog + id: my_custom_catalog + type: yaml + enabled: true + properties: + yamlCatalogPath: my-catalog.yaml # <-- Path to your file + ``` + The `yamlCatalogPath` must be the filename of your catalog definition, as it will be mounted into the same directory as `sources.yaml` inside the pod. + +4. **Apply the changes.** + + ```sh + kubectl apply -k . -n + ``` + +### Multiple Catalog Sources + +The Model Catalog can be configured with multiple sources. You can add multiple entries to the `catalogs` list in `sources.yaml`. The catalog application only loads the single `sources.yaml` file specified at startup, so all sources must be defined within that file. -##### Properties -- **`yamlCatalogPath`** (*string*, required): The path to the YAML file containing the model definitions. This path is relative to the directory where the `sources.yaml` file is located. -- **`excludedModels`** (*string list*, optional): A list of models to exclude from the catalog. These can be an exact name with a tag (e.g., `model-a:1.0`) or a pattern ending with `*` to exclude all tags for a repository (e.g., `model-b:*`). -##### Example +### Catalog Source Configuration Details + +Each entry in the `catalogs` list configures a single catalog source. + +#### Common Properties + +- **`name`** (*string*, required): A user-friendly name for the catalog source. +- **`id`** (*string*, required): A unique identifier for the catalog source. +- **`type`** (*string*, required): The type of catalog source. Currently supported types are: `yaml`. +- **`enabled`** (*boolean*, optional): Whether the catalog source is enabled. Defaults to `true`. + +#### `yaml` source type properties + +The `yaml` type sources model metadata from a local YAML file. + +- **`yamlCatalogPath`** (*string*, required): The path to the YAML file containing the model definitions. This file must be available in the `ConfigMap` alongside `sources.yaml`. +- **`excludedModels`** (*string list*, optional): A list of models to exclude from the catalog. These can be an exact name with a tag (e.g., `model-a:1.0`) or a pattern ending with `*` to exclude all tags for a model (e.g., `model-b:*`). + +##### Example `sources.yaml` entry ```yaml catalogs: @@ -49,27 +124,6 @@ catalogs: - model-b:* ``` -#### `rhec` - -The `rhec` type sources model metadata from the Red Hat Ecosystem Catalog. +### Sample Catalog File -##### Properties - -- **`models`** (*string list*, required): A list of models to include from the Red Hat Ecosystem Catalog. Each entry contains the full name of the model repository in the Red Hat Ecosystem Catalog (e.g., `rhelai1/modelcar-granite-7b-starter`). -- **`excludedModels`** (*string list*, optional): A list of models to exclude from the catalog. These can be an exact name with a tag (e.g., `rhelai1/modelcar-granite-7b-starter:b9514c3`) or a pattern ending with `*` to exclude all tags for a repository (e.g., `rhelai1/modelcar-granite-7b-starter:*`). - -##### Example - -```yaml -catalogs: - - name: Red Hat Ecosystem Catalog - id: sample_rhec_catalog - type: rhec - enabled: true - properties: - models: - - rhelai1/modelcar-granite-7b-starter - excludedModels: - - rhelai1/modelcar-granite-7b-starter:v0 - - rhelai1/modelcar-granite-* -``` \ No newline at end of file +You can refer to `sample-catalog.yaml` in this directory for an example of how to structure your model definitions file. diff --git a/applications/model-registry/upstream/options/catalog/deployment.yaml b/applications/model-registry/upstream/options/catalog/base/deployment.yaml similarity index 60% rename from applications/model-registry/upstream/options/catalog/deployment.yaml rename to applications/model-registry/upstream/options/catalog/base/deployment.yaml index 2e953a776e..3051f24fe9 100644 --- a/applications/model-registry/upstream/options/catalog/deployment.yaml +++ b/applications/model-registry/upstream/options/catalog/base/deployment.yaml @@ -1,19 +1,25 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: server + name: model-catalog-server labels: - component: model-catalog-server + app.kubernetes.io/name: model-catalog + app.kubernetes.io/part-of: model-catalog + app.kubernetes.io/component: server spec: replicas: 1 selector: matchLabels: - component: model-catalog-server + app.kubernetes.io/name: model-catalog + app.kubernetes.io/part-of: model-catalog + app.kubernetes.io/component: server template: metadata: labels: sidecar.istio.io/inject: "true" - component: model-catalog-server + app.kubernetes.io/name: model-catalog + app.kubernetes.io/part-of: model-catalog + app.kubernetes.io/component: server spec: securityContext: seccompProfile: @@ -25,6 +31,19 @@ spec: name: model-catalog-sources containers: - name: catalog + env: + - name: PGHOST + value: model-catalog-postgres + - name: PGUSER + valueFrom: + secretKeyRef: + name: model-catalog-postgres + key: POSTGRES_USER + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: model-catalog-postgres + key: POSTGRES_PASSWORD command: - /model-registry - catalog diff --git a/applications/model-registry/upstream/options/catalog/hf-sources-example.yaml b/applications/model-registry/upstream/options/catalog/base/hf-sources-example.yaml similarity index 100% rename from applications/model-registry/upstream/options/catalog/hf-sources-example.yaml rename to applications/model-registry/upstream/options/catalog/base/hf-sources-example.yaml diff --git a/applications/model-registry/upstream/options/catalog/kustomization.yaml b/applications/model-registry/upstream/options/catalog/base/kustomization.yaml similarity index 61% rename from applications/model-registry/upstream/options/catalog/kustomization.yaml rename to applications/model-registry/upstream/options/catalog/base/kustomization.yaml index 56d3ba34d2..cd7cb4ecff 100644 --- a/applications/model-registry/upstream/options/catalog/kustomization.yaml +++ b/applications/model-registry/upstream/options/catalog/base/kustomization.yaml @@ -1,21 +1,29 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization -namePrefix: model-catalog- - resources: - deployment.yaml - service.yaml +- postgres-statefulset.yaml +- postgres-pvc.yaml +- postgres-service.yaml configMapGenerator: - behavior: create files: - sources.yaml=sources.yaml - sample-catalog.yaml=sample-catalog.yaml - name: sources + name: model-catalog-sources + options: + disableNameSuffixHash: true + +secretGenerator: +- envs: + - postgres.env + name: model-catalog-postgres options: disableNameSuffixHash: true images: - name: ghcr.io/kubeflow/model-registry/server newName: ghcr.io/kubeflow/model-registry/server - newTag: v0.3.0 + newTag: v0.3.2 diff --git a/applications/model-registry/upstream/options/catalog/base/postgres-pvc.yaml b/applications/model-registry/upstream/options/catalog/base/postgres-pvc.yaml new file mode 100644 index 0000000000..140cf476cc --- /dev/null +++ b/applications/model-registry/upstream/options/catalog/base/postgres-pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: model-catalog-postgres +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi diff --git a/applications/model-registry/upstream/options/catalog/base/postgres-service.yaml b/applications/model-registry/upstream/options/catalog/base/postgres-service.yaml new file mode 100644 index 0000000000..e06377dbba --- /dev/null +++ b/applications/model-registry/upstream/options/catalog/base/postgres-service.yaml @@ -0,0 +1,18 @@ +kind: Service +apiVersion: v1 +metadata: + labels: + app.kubernetes.io/name: model-catalog + app.kubernetes.io/part-of: model-catalog + app.kubernetes.io/component: database + name: model-catalog-postgres +spec: + selector: + app.kubernetes.io/part-of: model-catalog + app.kubernetes.io/name: postgres + app.kubernetes.io/component: database + type: ClusterIP + ports: + - port: 5432 + protocol: TCP + name: postgres diff --git a/applications/model-registry/upstream/options/catalog/base/postgres-statefulset.yaml b/applications/model-registry/upstream/options/catalog/base/postgres-statefulset.yaml new file mode 100644 index 0000000000..4ea85ae6e2 --- /dev/null +++ b/applications/model-registry/upstream/options/catalog/base/postgres-statefulset.yaml @@ -0,0 +1,52 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: model-catalog-postgres + labels: + component: model-catalog-server +spec: + selector: + matchLabels: + app.kubernetes.io/name: postgres + app.kubernetes.io/part-of: model-catalog + replicas: 1 + template: + metadata: + name: postgres + labels: + app.kubernetes.io/name: postgres + app.kubernetes.io/part-of: model-catalog + app.kubernetes.io/component: database + sidecar.istio.io/inject: "false" + spec: + securityContext: + seccompProfile: + type: RuntimeDefault + runAsNonRoot: true + fsGroup: 70 + containers: + - name: postgres + image: postgres:17.6 + env: + - name: PGDATA + value: /var/lib/postgresql/data/pgdata + envFrom: + - secretRef: + name: model-catalog-postgres + ports: + - name: postgres + containerPort: 5432 + volumeMounts: + - name: model-catalog-postgres + mountPath: /var/lib/postgresql/data + securityContext: + runAsUser: 70 + runAsGroup: 70 + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + volumes: + - name: model-catalog-postgres + persistentVolumeClaim: + claimName: model-catalog-postgres diff --git a/applications/model-registry/upstream/options/catalog/base/postgres.env b/applications/model-registry/upstream/options/catalog/base/postgres.env new file mode 100644 index 0000000000..07cfbd56eb --- /dev/null +++ b/applications/model-registry/upstream/options/catalog/base/postgres.env @@ -0,0 +1,2 @@ +POSTGRES_USER=postgres +POSTGRES_PASSWORD=postgres diff --git a/applications/model-registry/upstream/options/catalog/sample-catalog.yaml b/applications/model-registry/upstream/options/catalog/base/sample-catalog.yaml similarity index 100% rename from applications/model-registry/upstream/options/catalog/sample-catalog.yaml rename to applications/model-registry/upstream/options/catalog/base/sample-catalog.yaml diff --git a/applications/model-registry/upstream/options/catalog/base/service.yaml b/applications/model-registry/upstream/options/catalog/base/service.yaml new file mode 100644 index 0000000000..2fde7d007e --- /dev/null +++ b/applications/model-registry/upstream/options/catalog/base/service.yaml @@ -0,0 +1,18 @@ +kind: Service +apiVersion: v1 +metadata: + labels: + app.kubernetes.io/name: model-catalog + app.kubernetes.io/component: server + app.kubernetes.io/part-of: model-catalog + name: model-catalog +spec: + selector: + app.kubernetes.io/part-of: model-catalog + app.kubernetes.io/component: server + type: ClusterIP + ports: + - port: 8080 + protocol: TCP + appProtocol: http + name: http-api diff --git a/applications/model-registry/upstream/options/catalog/sources.yaml b/applications/model-registry/upstream/options/catalog/base/sources.yaml similarity index 100% rename from applications/model-registry/upstream/options/catalog/sources.yaml rename to applications/model-registry/upstream/options/catalog/base/sources.yaml diff --git a/applications/model-registry/upstream/options/catalog/overlay/destination-rule.yaml b/applications/model-registry/upstream/options/catalog/overlay/destination-rule.yaml new file mode 100644 index 0000000000..b358adf1c8 --- /dev/null +++ b/applications/model-registry/upstream/options/catalog/overlay/destination-rule.yaml @@ -0,0 +1,9 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: model-catalog-service +spec: + host: model-catalog.kubeflow.svc.cluster.local + trafficPolicy: + tls: + mode: ISTIO_MUTUAL diff --git a/applications/model-registry/upstream/options/catalog/overlay/kustomization.yaml b/applications/model-registry/upstream/options/catalog/overlay/kustomization.yaml new file mode 100644 index 0000000000..029a6937ca --- /dev/null +++ b/applications/model-registry/upstream/options/catalog/overlay/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- istio-authorization-policy.yaml +- destination-rule.yaml +- virtual-service.yaml diff --git a/applications/model-registry/upstream/options/catalog/overlay/virtual-service.yaml b/applications/model-registry/upstream/options/catalog/overlay/virtual-service.yaml new file mode 100644 index 0000000000..cedc235c78 --- /dev/null +++ b/applications/model-registry/upstream/options/catalog/overlay/virtual-service.yaml @@ -0,0 +1,18 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: model-catalog +spec: + gateways: + - kubeflow-gateway + hosts: + - "*" + http: + - match: + - uri: + prefix: /api/model_catalog/ + route: + - destination: + host: model-catalog.kubeflow.svc.cluster.local + port: + number: 8080 diff --git a/applications/model-registry/upstream/options/catalog/service.yaml b/applications/model-registry/upstream/options/catalog/service.yaml deleted file mode 100644 index 6e87175dbe..0000000000 --- a/applications/model-registry/upstream/options/catalog/service.yaml +++ /dev/null @@ -1,20 +0,0 @@ -kind: Service -apiVersion: v1 -metadata: - labels: - app: model-catalog-service - app.kubernetes.io/component: model-catalog - app.kubernetes.io/instance: model-catalog-service - app.kubernetes.io/name: model-catalog-service - app.kubernetes.io/part-of: model-catalog - component: model-catalog - name: model-catalog-service -spec: - selector: - component: model-catalog-server - type: ClusterIP - ports: - - port: 8080 - protocol: TCP - appProtocol: http - name: http-api diff --git a/applications/model-registry/upstream/options/csi/kustomization.yaml b/applications/model-registry/upstream/options/csi/kustomization.yaml index c6e7c5b8af..c285d94c65 100644 --- a/applications/model-registry/upstream/options/csi/kustomization.yaml +++ b/applications/model-registry/upstream/options/csi/kustomization.yaml @@ -7,4 +7,4 @@ resources: images: - name: ghcr.io/kubeflow/model-registry/storage-initializer newName: ghcr.io/kubeflow/model-registry/storage-initializer - newTag: v0.3.0 + newTag: v0.3.2 diff --git a/applications/model-registry/upstream/options/ui/base/kustomization.yaml b/applications/model-registry/upstream/options/ui/base/kustomization.yaml index 6ee72f56bc..3e9a4516bb 100644 --- a/applications/model-registry/upstream/options/ui/base/kustomization.yaml +++ b/applications/model-registry/upstream/options/ui/base/kustomization.yaml @@ -10,4 +10,4 @@ resources: images: - name: model-registry-ui newName: ghcr.io/kubeflow/model-registry/ui - newTag: v0.3.0 + newTag: v0.3.2 diff --git a/tests/model_catalog_install.sh b/tests/model_catalog_install.sh index f1541224ec..56f2ca57de 100755 --- a/tests/model_catalog_install.sh +++ b/tests/model_catalog_install.sh @@ -2,7 +2,7 @@ set -euxo pipefail ( - cd applications/model-registry/upstream/options/catalog + cd applications/model-registry/upstream/options/catalog/base kustomize build . | kubectl apply -n kubeflow -f - ) diff --git a/tests/model_catalog_test.sh b/tests/model_catalog_test.sh index 7684d7646c..06669405b6 100755 --- a/tests/model_catalog_test.sh +++ b/tests/model_catalog_test.sh @@ -7,14 +7,14 @@ if ! kubectl get deployment/model-catalog-server -n kubeflow; then exit 1 fi -if ! kubectl get svc/model-catalog-model-catalog-service -n kubeflow; then +if ! kubectl get svc/model-catalog -n kubeflow; then echo "ERROR: Model Catalog service not found" exit 1 fi -kubectl get pods -n kubeflow -l component=model-catalog-server +kubectl get pods -n kubeflow -l app.kubernetes.io/name=model-catalog,app.kubernetes.io/component=server -nohup kubectl port-forward svc/model-catalog-model-catalog-service -n kubeflow 8082:8080 & +nohup kubectl port-forward svc/model-catalog -n kubeflow 8082:8080 & PORT_FORWARD_PID=$! MAX_RETRIES=30