diff --git a/charts/model-registry/OWNERS b/charts/model-registry/OWNERS new file mode 100644 index 0000000..4e58087 --- /dev/null +++ b/charts/model-registry/OWNERS @@ -0,0 +1,8 @@ +approvers: + - tarilabs + - rareddy + - Tomcli +reviewers: + - tarilabs + - rareddy + - Tomcli diff --git a/charts/model-registry/README.md b/charts/model-registry/README.md new file mode 100644 index 0000000..65d4787 --- /dev/null +++ b/charts/model-registry/README.md @@ -0,0 +1,136 @@ +# Install Kubeflow Model Registry + +This folder contains [Kubeflow Model Registry](https://www.kubeflow.org/docs/components/model-registry/installation/) Kustomize manifests + +## Overview + +This is the full installation guide, for a quick install in an existing Kubeflow installation, follow [these instructions](https://www.kubeflow.org/docs/components/model-registry/installation/). +**Ensure you are running all these commands from the directory containing this README.md file (e.g.: you could check with `pwd`).** + +## Kubeflow Central Dashboard Installation + +These instructions assume that you've installed Kubeflow from the [manifests](https://github.com/kubeflow/manifests/), if you're using a distribution consult its documentation instead. + +Kubeflow Central Dashboard uses [profiles](https://www.kubeflow.org/docs/components/central-dash/profiles/) to handle user namespaces and permissions. You will need to deploy Model Registry into a profile namespace. + +> **๐Ÿ›ˆ Note:** If you're not sure of the profile name, you can find it in the name space drop-down on the Kubeflow Dashboard. + +The commands in this section assume that you've defined an environment variable with the target profile namespace: + +```sh +PROFILE_NAME= +``` + +Deploy Model Registry: + +```sh +kubectl apply -k overlays/db -n $PROFILE_NAME +kubectl apply -k options/istio -n $PROFILE_NAME +``` + +Check that everything is up and running: + +```bash +kubectl wait --for=condition=available-n $PROFILE_NAME deployment/model-registry-deployment --timeout=2m +kubectl logs -n $PROFILE_NAME deployment/model-registry-deployment +``` + +Now, to install the Model Registry UI as a Kubeflow component, you need first to deploy the Model Registry UI: + +```bash +kubectl apply -k options/ui/overlays/istio +``` + +And then to make it accessible through Kubeflow Central Dashboard, you need to edit the `centraldashboard-config` ConfigMap to add the Model Registry UI link to the Central Dashboard by running the following command: + +```bash +kubectl get configmap centraldashboard-config -n kubeflow -o json | jq '.data.links |= (fromjson | .menuLinks += [{"icon": "assignment", "link": "/model-registry/", "text": "Model Registry", "type": "item"}] | tojson)' | kubectl apply -f - -n kubeflow +``` + +Alternatively, you can edit the ConfigMap manually by running: + +```bash +kubectl edit configmap -n kubeflow centraldashboard-config +``` + +```yaml +apiVersion: v1 +data: + links: |- + { + "menuLinks": [ + { + "icon": "assignment", + "link": "/model-registry/", + "text": "Model Registry", + "type": "item" + }, + ... +``` + +Now you should be able to see the Model Registry UI in the Kubeflow Central Dashboard, and access to the Model Registry deployment in the profile namespace. + +### Uninstall + +To uninstall the Kubeflow Model Registry run: + +```bash +# Uninstall Model Registry Instance +PROFILE_NAME= +kubectl delete -k overlays/db -n $PROFILE_NAME +kubectl delete -k options/istio -n $PROFILE_NAME + +# Uninstall Model Registry UI +kubectl delete -k options/ui/overlays/istio +``` + +## Model Registry as a separate component Installation + +The following instructions will summarize how to deploy Model Registry as separate component in the context of a default Kubeflow >=1.9 installation. + +```bash +kubectl apply -k overlays/db -n kubeflow +``` + +As the default Kubeflow installation provides an Istio mesh, apply the necessary manifests: + +```bash +kubectl apply -k options/istio -n kubeflow +``` + +Check everything is up and running: + +```bash +kubectl wait --for=condition=available -n kubeflow deployment/model-registry-deployment --timeout=2m +kubectl logs -n kubeflow deployment/model-registry-deployment +``` + +Optionally, you can also port-forward the REST API container port of Model Registry to interact with it from your terminal: + +```bash +kubectl port-forward svc/model-registry-service -n kubeflow 8081:8080 +``` + +And then, from another terminal: + +```bash +curl -sX 'GET' \ + 'http://localhost:8081/api/model_registry/v1alpha3/registered_models?pageSize=100&orderBy=ID&sortOrder=DESC' \ + -H 'accept: application/json' | jq +``` + +### Usage + +For a basic usage of the Kubeflow Model Registry, follow the [Kubeflow Model Registry getting started documentation](https://www.kubeflow.org/docs/components/model-registry/getting-started/) + +### Uninstall + +To uninstall the Kubeflow Model Registry run: + +```bash +# Delete istio options +kubectl delete -k options/istio -n kubeflow + +# Delete model registry db and deployment +kubectl delete -k overlays/db -n kubeflow +``` diff --git a/charts/model-registry/base/kustomization.yaml b/charts/model-registry/base/kustomization.yaml new file mode 100644 index 0000000..bf7107f --- /dev/null +++ b/charts/model-registry/base/kustomization.yaml @@ -0,0 +1,11 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- model-registry-configmap.yaml +- model-registry-deployment.yaml +- model-registry-service.yaml +- model-registry-sa.yaml +images: +- name: ghcr.io/kubeflow/model-registry/server + newName: ghcr.io/kubeflow/model-registry/server + newTag: v0.2.19 diff --git a/charts/model-registry/base/model-registry-configmap.yaml b/charts/model-registry/base/model-registry-configmap.yaml new file mode 100644 index 0000000..b8ff8ce --- /dev/null +++ b/charts/model-registry/base/model-registry-configmap.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: model-registry-configmap + labels: + component: model-registry-server +data: + MODEL_REGISTRY_REST_SERVICE_HOST: "model-registry-service" + MODEL_REGISTRY_REST_SERVICE_PORT: "8080" + MODEL_REGISTRY_GRPC_SERVICE_HOST: "model-registry-service" + MODEL_REGISTRY_GRPC_SERVICE_PORT: "9090" + MODEL_REGISTRY_DATA_STORE_TYPE: "mlmd" diff --git a/charts/model-registry/base/model-registry-deployment.yaml b/charts/model-registry/base/model-registry-deployment.yaml new file mode 100644 index 0000000..4adfb16 --- /dev/null +++ b/charts/model-registry/base/model-registry-deployment.yaml @@ -0,0 +1,121 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: model-registry-deployment + labels: + component: model-registry-server +spec: + replicas: 1 + selector: + matchLabels: + component: model-registry-server + template: + metadata: + labels: + sidecar.istio.io/inject: "true" + component: model-registry-server + spec: + securityContext: + seccompProfile: + type: RuntimeDefault + runAsNonRoot: true + containers: + - name: rest-container + args: + - --hostname=0.0.0.0 + - --port=8080 + - --mlmd-hostname=localhost + - --mlmd-port=9090 + - --datastore-type=mlmd + command: + - /model-registry + - proxy + image: ghcr.io/kubeflow/model-registry/server:latest + # empty placeholder environment for patching + env: [] + ports: + - name: http-api + containerPort: 8080 + livenessProbe: + initialDelaySeconds: 30 + periodSeconds: 5 + tcpSocket: + port: http-api + timeoutSeconds: 2 + readinessProbe: + initialDelaySeconds: 3 + periodSeconds: 5 + tcpSocket: + port: http-api + timeoutSeconds: 2 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + - name: grpc-container + # ! Sync to the same MLMD version: + # * backend/metadata_writer/requirements.in and requirements.txt + # * @kubeflow/frontend/src/mlmd/generated + # * .cloudbuild.yaml and .release.cloudbuild.yaml + # * manifests/kustomize/base/metadata/base/model-registry-deployment.yaml + # * test/tag_for_hosted.sh + image: gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0 + env: + - name: DBCONFIG_USER + valueFrom: + secretKeyRef: + name: mysql-secret + key: username + - name: DBCONFIG_PASSWORD + valueFrom: + secretKeyRef: + name: mysql-secret + key: password + - name: MYSQL_DATABASE + valueFrom: + configMapKeyRef: + name: pipeline-install-config + key: mlmdDb + - name: MYSQL_HOST + valueFrom: + configMapKeyRef: + name: pipeline-install-config + key: dbHost + - name: MYSQL_PORT + valueFrom: + configMapKeyRef: + name: pipeline-install-config + key: dbPort + command: ["/bin/metadata_store_server"] + args: ["--grpc_port=9090", + "--mysql_config_database=$(MYSQL_DATABASE)", + "--mysql_config_host=$(MYSQL_HOST)", + "--mysql_config_port=MYSQL_PORT_PLACEHOLDER", + "--mysql_config_user=$(DBCONFIG_USER)", + "--mysql_config_password=$(DBCONFIG_PASSWORD)", + "--enable_database_upgrade=true" + ] + ports: + - name: grpc-api + containerPort: 9090 + livenessProbe: + tcpSocket: + port: grpc-api + initialDelaySeconds: 3 + periodSeconds: 5 + timeoutSeconds: 2 + readinessProbe: + tcpSocket: + port: grpc-api + initialDelaySeconds: 3 + periodSeconds: 5 + timeoutSeconds: 2 + securityContext: + runAsUser: 65534 + runAsGroup: 65534 + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + serviceAccountName: model-registry-server diff --git a/charts/model-registry/base/model-registry-sa.yaml b/charts/model-registry/base/model-registry-sa.yaml new file mode 100644 index 0000000..8cfc77e --- /dev/null +++ b/charts/model-registry/base/model-registry-sa.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: model-registry-server diff --git a/charts/model-registry/base/model-registry-service.yaml b/charts/model-registry/base/model-registry-service.yaml new file mode 100644 index 0000000..c4251cf --- /dev/null +++ b/charts/model-registry/base/model-registry-service.yaml @@ -0,0 +1,27 @@ +kind: Service +apiVersion: v1 +metadata: + labels: + app: model-registry-service + app.kubernetes.io/component: model-registry + app.kubernetes.io/instance: model-registry-service + app.kubernetes.io/name: model-registry-service + app.kubernetes.io/part-of: model-registry + component: model-registry + annotations: + displayName: Kubeflow Model Registry + description: An example model registry + name: model-registry-service +spec: + selector: + component: model-registry-server + type: ClusterIP + ports: + - port: 8080 + protocol: TCP + appProtocol: http + name: http-api + - port: 9090 + protocol: TCP + appProtocol: grpc + name: grpc-api diff --git a/charts/model-registry/options/controller/default/kustomization.yaml b/charts/model-registry/options/controller/default/kustomization.yaml new file mode 100644 index 0000000..f7e627d --- /dev/null +++ b/charts/model-registry/options/controller/default/kustomization.yaml @@ -0,0 +1,177 @@ +# Adds namespace to all resources. +namespace: kubeflow + +# Value of this field is prepended to the +# names of all resources, e.g. a deployment named +# "wordpress" becomes "alices-wordpress". +# Note that it should also match with the prefix (text before '-') of the namespace +# field above. +namePrefix: controller- + +# Labels to add to all resources and selectors. +#labels: +#- includeSelectors: true +# pairs: +# someName: someValue + +resources: +#- ../crd +- ../rbac +- ../manager +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +#- ../webhook +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. +#- ../certmanager +# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. +#- ../prometheus +# [METRICS] Expose the controller manager metrics service. +- metrics_service.yaml +# [NETWORK POLICY] Protect the /metrics endpoint and Webhook Server with NetworkPolicy. +# Only Pod(s) running a namespace labeled with 'metrics: enabled' will be able to gather the metrics. +# Only CR(s) which requires webhooks and are applied on namespaces labeled with 'webhooks: enabled' will +# be able to communicate with the Webhook Server. +#- ../network-policy + +# Uncomment the patches line if you enable Metrics, and/or are using webhooks and cert-manager +patches: +# [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. +# More info: https://book.kubebuilder.io/reference/metrics +- path: manager_metrics_patch.yaml + target: + kind: Deployment + +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +#- path: manager_webhook_patch.yaml + +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. +# Uncomment the following replacements to add the cert-manager CA injection annotations +#replacements: +# - source: # Uncomment the following block if you have any webhook +# kind: Service +# version: v1 +# name: webhook-service +# fieldPath: .metadata.name # Name of the service +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# fieldPaths: +# - .spec.dnsNames.0 +# - .spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 0 +# create: true +# - source: +# kind: Service +# version: v1 +# name: webhook-service +# fieldPath: .metadata.namespace # Namespace of the service +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# fieldPaths: +# - .spec.dnsNames.0 +# - .spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 1 +# create: true +# +# - source: # Uncomment the following block if you have a ValidatingWebhook (--programmatic-validation) +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.namespace # Namespace of the certificate CR +# targets: +# - select: +# kind: ValidatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# create: true +# - source: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.name +# targets: +# - select: +# kind: ValidatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 1 +# create: true +# +# - source: # Uncomment the following block if you have a DefaultingWebhook (--defaulting ) +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.namespace # Namespace of the certificate CR +# targets: +# - select: +# kind: MutatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# create: true +# - source: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.name +# targets: +# - select: +# kind: MutatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 1 +# create: true +# +# - source: # Uncomment the following block if you have a ConversionWebhook (--conversion) +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.namespace # Namespace of the certificate CR +# targets: +# - select: +# kind: CustomResourceDefinition +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# create: true +# - source: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.name +# targets: +# - select: +# kind: CustomResourceDefinition +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 1 +# create: true diff --git a/charts/model-registry/options/controller/default/manager_metrics_patch.yaml b/charts/model-registry/options/controller/default/manager_metrics_patch.yaml new file mode 100644 index 0000000..2aaef65 --- /dev/null +++ b/charts/model-registry/options/controller/default/manager_metrics_patch.yaml @@ -0,0 +1,4 @@ +# This patch adds the args to allow exposing the metrics endpoint using HTTPS +- op: add + path: /spec/template/spec/containers/0/args/0 + value: --metrics-bind-address=:8443 diff --git a/charts/model-registry/options/controller/default/metrics_service.yaml b/charts/model-registry/options/controller/default/metrics_service.yaml new file mode 100644 index 0000000..ae73482 --- /dev/null +++ b/charts/model-registry/options/controller/default/metrics_service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + app.kubernetes.io/name: controller + app.kubernetes.io/managed-by: kustomize + name: controller-manager-metrics-service + namespace: system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + selector: + control-plane: controller-manager diff --git a/charts/model-registry/options/controller/manager/kustomization.yaml b/charts/model-registry/options/controller/manager/kustomization.yaml new file mode 100644 index 0000000..5c5f0b8 --- /dev/null +++ b/charts/model-registry/options/controller/manager/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- manager.yaml diff --git a/charts/model-registry/options/controller/manager/manager.yaml b/charts/model-registry/options/controller/manager/manager.yaml new file mode 100644 index 0000000..a630346 --- /dev/null +++ b/charts/model-registry/options/controller/manager/manager.yaml @@ -0,0 +1,103 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + control-plane: controller-manager + app.kubernetes.io/name: controller + app.kubernetes.io/managed-by: kustomize +spec: + selector: + matchLabels: + control-plane: controller-manager + replicas: 1 + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + spec: + # TODO(user): Uncomment the following code to configure the nodeAffinity expression + # according to the platforms which are supported by your solution. + # It is considered best practice to support multiple architectures. You can + # build your manager image using the makefile target docker-buildx. + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: kubernetes.io/arch + # operator: In + # values: + # - amd64 + # - arm64 + # - ppc64le + # - s390x + # - key: kubernetes.io/os + # operator: In + # values: + # - linux + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + containers: + - command: + - /manager + args: + - --leader-elect + - --health-probe-bind-address=:8081 + image: ghcr.io/kubeflow/model-registry/controller:latest + name: manager + env: + - name: NAMESPACE_LABEL + value: "" + - name: NAME_LABEL + value: "" + - name: URL_ANNOTATION + value: "" + - name: INFERENCE_SERVICE_ID_LABEL + value: "" + - name: MODEL_VERSION_ID_LABEL + value: "" + - name: REGISTERED_MODEL_ID_LABEL + value: "" + - name: FINALIZER + value: "" + - name: SERVICE_ANNOTATION + value: "" + - name: REGISTRIES_NAMESPACE + value: "" + - name: SKIP_TLS_VERIFY + value: "false" + - name: INFERENCE_SERVICE_CONTROLLER + value: "" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + # TODO(user): Configure the resources accordingly based on the project requirements. + # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: + limits: + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + serviceAccountName: controller-manager + terminationGracePeriodSeconds: 10 diff --git a/charts/model-registry/options/controller/network-policy/allow-metrics-traffic.yaml b/charts/model-registry/options/controller/network-policy/allow-metrics-traffic.yaml new file mode 100644 index 0000000..f6ddf95 --- /dev/null +++ b/charts/model-registry/options/controller/network-policy/allow-metrics-traffic.yaml @@ -0,0 +1,26 @@ +# This NetworkPolicy allows ingress traffic +# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those +# namespaces are able to gathering data from the metrics endpoint. +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/name: controller + app.kubernetes.io/managed-by: kustomize + name: allow-metrics-traffic + namespace: system +spec: + podSelector: + matchLabels: + control-plane: controller-manager + policyTypes: + - Ingress + ingress: + # This allows ingress traffic from any namespace with the label metrics: enabled + - from: + - namespaceSelector: + matchLabels: + metrics: enabled # Only from namespaces with this label + ports: + - port: 8443 + protocol: TCP diff --git a/charts/model-registry/options/controller/network-policy/kustomization.yaml b/charts/model-registry/options/controller/network-policy/kustomization.yaml new file mode 100644 index 0000000..ec0fb5e --- /dev/null +++ b/charts/model-registry/options/controller/network-policy/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- allow-metrics-traffic.yaml diff --git a/charts/model-registry/options/controller/overlays/base/kustomization.yaml b/charts/model-registry/options/controller/overlays/base/kustomization.yaml new file mode 100644 index 0000000..70569dd --- /dev/null +++ b/charts/model-registry/options/controller/overlays/base/kustomization.yaml @@ -0,0 +1,14 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- ../../default + +configMapGenerator: +- envs: + - params.env + name: model-registry-controller-parameters +generatorOptions: + disableNameSuffixHash: true +replacements: +- path: replacements.yaml diff --git a/charts/model-registry/options/controller/overlays/base/params.env b/charts/model-registry/options/controller/overlays/base/params.env new file mode 100644 index 0000000..eada06d --- /dev/null +++ b/charts/model-registry/options/controller/overlays/base/params.env @@ -0,0 +1,11 @@ +NAMESPACE_LABEL=modelregistry.kubeflow.org/namespace +NAME_LABEL=modelregistry.kubeflow.org/name +URL_ANNOTATION=modelregistry.kubeflow.org/url +INFERENCE_SERVICE_ID_LABEL=modelregistry.kubeflow.org/inference-service-id +MODEL_VERSION_ID_LABEL=modelregistry.kubeflow.org/model-version-id +REGISTERED_MODEL_ID_LABEL=modelregistry.kubeflow.org/registered-model-id +FINALIZER=modelregistry.kubeflow.org/finalizer +SERVICE_ANNOTATION=routing.kubeflow.org/external-address-rest +REGISTRIES_NAMESPACE=kubeflow +SKIP_TLS_VERIFY=false +INFERENCE_SERVICE_CONTROLLER=managed diff --git a/charts/model-registry/options/controller/overlays/base/replacements.yaml b/charts/model-registry/options/controller/overlays/base/replacements.yaml new file mode 100644 index 0000000..1f632ca --- /dev/null +++ b/charts/model-registry/options/controller/overlays/base/replacements.yaml @@ -0,0 +1,110 @@ +- source: + kind: ConfigMap + name: model-registry-controller-parameters + fieldPath: data.NAMESPACE_LABEL + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=NAMESPACE_LABEL].value +- source: + kind: ConfigMap + name: model-registry-controller-parameters + fieldPath: data.NAME_LABEL + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=NAME_LABEL].value +- source: + kind: ConfigMap + name: model-registry-controller-parameters + fieldPath: data.URL_ANNOTATION + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=URL_ANNOTATION].value +- source: + kind: ConfigMap + name: model-registry-controller-parameters + fieldPath: data.INFERENCE_SERVICE_ID_LABEL + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=INFERENCE_SERVICE_ID_LABEL].value +- source: + kind: ConfigMap + name: model-registry-controller-parameters + fieldPath: data.MODEL_VERSION_ID_LABEL + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=MODEL_VERSION_ID_LABEL].value +- source: + kind: ConfigMap + name: model-registry-controller-parameters + fieldPath: data.REGISTERED_MODEL_ID_LABEL + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=REGISTERED_MODEL_ID_LABEL].value +- source: + kind: ConfigMap + name: model-registry-controller-parameters + fieldPath: data.FINALIZER + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=FINALIZER].value +- source: + kind: ConfigMap + name: model-registry-controller-parameters + fieldPath: data.SERVICE_ANNOTATION + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=SERVICE_ANNOTATION].value +- source: + kind: ConfigMap + name: model-registry-controller-parameters + fieldPath: data.REGISTRIES_NAMESPACE + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=REGISTRIES_NAMESPACE].value +- source: + kind: ConfigMap + name: model-registry-controller-parameters + fieldPath: data.SKIP_TLS_VERIFY + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=SKIP_TLS_VERIFY].value +- source: + kind: ConfigMap + name: model-registry-controller-parameters + fieldPath: data.INFERENCE_SERVICE_CONTROLLER + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.[name=manager].env.[name=INFERENCE_SERVICE_CONTROLLER].value diff --git a/charts/model-registry/options/controller/prometheus/kustomization.yaml b/charts/model-registry/options/controller/prometheus/kustomization.yaml new file mode 100644 index 0000000..ed13716 --- /dev/null +++ b/charts/model-registry/options/controller/prometheus/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- monitor.yaml diff --git a/charts/model-registry/options/controller/prometheus/monitor.yaml b/charts/model-registry/options/controller/prometheus/monitor.yaml new file mode 100644 index 0000000..a9731e4 --- /dev/null +++ b/charts/model-registry/options/controller/prometheus/monitor.yaml @@ -0,0 +1,30 @@ +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + control-plane: controller-manager + app.kubernetes.io/name: controller + app.kubernetes.io/managed-by: kustomize + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - path: /metrics + port: https # Ensure this is the name of the port that exposes HTTPS metrics + scheme: https + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + tlsConfig: + # TODO(user): The option insecureSkipVerify: true is not recommended for production since it disables + # certificate verification. This poses a significant security risk by making the system vulnerable to + # man-in-the-middle attacks, where an attacker could intercept and manipulate the communication between + # Prometheus and the monitored services. This could lead to unauthorized access to sensitive metrics data, + # compromising the integrity and confidentiality of the information. + # Please use the following options for secure configurations: + # caFile: /etc/metrics-certs/ca.crt + # certFile: /etc/metrics-certs/tls.crt + # keyFile: /etc/metrics-certs/tls.key + insecureSkipVerify: true + selector: + matchLabels: + control-plane: controller-manager diff --git a/charts/model-registry/options/controller/rbac/kustomization.yaml b/charts/model-registry/options/controller/rbac/kustomization.yaml new file mode 100644 index 0000000..5619aa0 --- /dev/null +++ b/charts/model-registry/options/controller/rbac/kustomization.yaml @@ -0,0 +1,20 @@ +resources: +# All RBAC will be applied under this service account in +# the deployment namespace. You may comment out this resource +# if your manager will use a service account that exists at +# runtime. Be sure to update RoleBinding and ClusterRoleBinding +# subjects if changing service account names. +- service_account.yaml +- role.yaml +- role_binding.yaml +- leader_election_role.yaml +- leader_election_role_binding.yaml +# The following RBAC configurations are used to protect +# the metrics endpoint with authn/authz. These configurations +# ensure that only authorized users and service accounts +# can access the metrics endpoint. Comment the following +# permissions if you want to disable this protection. +# More info: https://book.kubebuilder.io/reference/metrics.html +- metrics_auth_role.yaml +- metrics_auth_role_binding.yaml +- metrics_reader_role.yaml diff --git a/charts/model-registry/options/controller/rbac/leader_election_role.yaml b/charts/model-registry/options/controller/rbac/leader_election_role.yaml new file mode 100644 index 0000000..445f027 --- /dev/null +++ b/charts/model-registry/options/controller/rbac/leader_election_role.yaml @@ -0,0 +1,40 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: controller + app.kubernetes.io/managed-by: kustomize + name: leader-election-role +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/charts/model-registry/options/controller/rbac/leader_election_role_binding.yaml b/charts/model-registry/options/controller/rbac/leader_election_role_binding.yaml new file mode 100644 index 0000000..aed609d --- /dev/null +++ b/charts/model-registry/options/controller/rbac/leader_election_role_binding.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: controller + app.kubernetes.io/managed-by: kustomize + name: leader-election-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: leader-election-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/charts/model-registry/options/controller/rbac/metrics_auth_role.yaml b/charts/model-registry/options/controller/rbac/metrics_auth_role.yaml new file mode 100644 index 0000000..32d2e4e --- /dev/null +++ b/charts/model-registry/options/controller/rbac/metrics_auth_role.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-auth-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/charts/model-registry/options/controller/rbac/metrics_auth_role_binding.yaml b/charts/model-registry/options/controller/rbac/metrics_auth_role_binding.yaml new file mode 100644 index 0000000..e775d67 --- /dev/null +++ b/charts/model-registry/options/controller/rbac/metrics_auth_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: metrics-auth-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: metrics-auth-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/charts/model-registry/options/controller/rbac/metrics_reader_role.yaml b/charts/model-registry/options/controller/rbac/metrics_reader_role.yaml new file mode 100644 index 0000000..51a75db --- /dev/null +++ b/charts/model-registry/options/controller/rbac/metrics_reader_role.yaml @@ -0,0 +1,9 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-reader +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get diff --git a/charts/model-registry/options/controller/rbac/role.yaml b/charts/model-registry/options/controller/rbac/role.yaml new file mode 100644 index 0000000..5481679 --- /dev/null +++ b/charts/model-registry/options/controller/rbac/role.yaml @@ -0,0 +1,36 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: model-registry-manager-role +rules: +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch +- apiGroups: + - serving.kserve.io + resources: + - inferenceservices + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - serving.kserve.io + resources: + - inferenceservices/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch diff --git a/charts/model-registry/options/controller/rbac/role_binding.yaml b/charts/model-registry/options/controller/rbac/role_binding.yaml new file mode 100644 index 0000000..8f4443f --- /dev/null +++ b/charts/model-registry/options/controller/rbac/role_binding.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: controller + app.kubernetes.io/managed-by: kustomize + name: model-registry-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: model-registry-manager-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/charts/model-registry/options/controller/rbac/service_account.yaml b/charts/model-registry/options/controller/rbac/service_account.yaml new file mode 100644 index 0000000..834b343 --- /dev/null +++ b/charts/model-registry/options/controller/rbac/service_account.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: controller + app.kubernetes.io/managed-by: kustomize + name: controller-manager + namespace: system diff --git a/charts/model-registry/options/csi/clusterstoragecontainer.yaml b/charts/model-registry/options/csi/clusterstoragecontainer.yaml new file mode 100644 index 0000000..aee0be3 --- /dev/null +++ b/charts/model-registry/options/csi/clusterstoragecontainer.yaml @@ -0,0 +1,19 @@ +apiVersion: "serving.kserve.io/v1alpha1" +kind: ClusterStorageContainer +metadata: + name: model-registry-storage-initializer +spec: + container: + name: storage-initializer + image: ghcr.io/kubeflow/model-registry/storage-initializer:latest + env: + - name: MODEL_REGISTRY_BASE_URL + value: "model-registry-service.kubeflow.svc.cluster.local:8080" + resources: + requests: + memory: 100Mi + cpu: 100m + limits: + memory: 1Gi + supportedUriFormats: + - prefix: model-registry:// diff --git a/charts/model-registry/options/csi/kustomization.yaml b/charts/model-registry/options/csi/kustomization.yaml new file mode 100644 index 0000000..75c974e --- /dev/null +++ b/charts/model-registry/options/csi/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: kubeflow + +resources: +- clusterstoragecontainer.yaml +images: +- name: ghcr.io/kubeflow/model-registry/storage-initializer + newName: ghcr.io/kubeflow/model-registry/storage-initializer + newTag: v0.2.19 diff --git a/charts/model-registry/options/istio/destination-rule.yaml b/charts/model-registry/options/istio/destination-rule.yaml new file mode 100644 index 0000000..179d62d --- /dev/null +++ b/charts/model-registry/options/istio/destination-rule.yaml @@ -0,0 +1,9 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: model-registry-service +spec: + host: model-registry-service.kubeflow.svc.cluster.local + trafficPolicy: + tls: + mode: ISTIO_MUTUAL diff --git a/charts/model-registry/options/istio/istio-authorization-policy.yaml b/charts/model-registry/options/istio/istio-authorization-policy.yaml new file mode 100644 index 0000000..36685d8 --- /dev/null +++ b/charts/model-registry/options/istio/istio-authorization-policy.yaml @@ -0,0 +1,11 @@ +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: model-registry-service +spec: + action: ALLOW + selector: + matchLabels: + component: model-registry-server + rules: + - {} diff --git a/charts/model-registry/options/istio/kustomization.yaml b/charts/model-registry/options/istio/kustomization.yaml new file mode 100644 index 0000000..029a693 --- /dev/null +++ b/charts/model-registry/options/istio/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/charts/model-registry/options/istio/virtual-service.yaml b/charts/model-registry/options/istio/virtual-service.yaml new file mode 100644 index 0000000..576c020 --- /dev/null +++ b/charts/model-registry/options/istio/virtual-service.yaml @@ -0,0 +1,29 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: model-registry +spec: + gateways: + - kubeflow-gateway + hosts: + - '*' + http: + - match: + - uri: + prefix: /api/model_registry/ + route: + - destination: + host: model-registry-service.kubeflow.svc.cluster.local + port: + number: 8080 + - match: + - port: 9090 + - authority: + regex: model-registry-service(\..+)?(:9090)? + - uri: + prefix: /ml_metadata.MetadataStoreService/ + route: + - destination: + host: model-registry-service.kubeflow.svc.cluster.local + port: + number: 9090 diff --git a/charts/model-registry/options/ui/base/kustomization.yaml b/charts/model-registry/options/ui/base/kustomization.yaml new file mode 100644 index 0000000..3c404ba --- /dev/null +++ b/charts/model-registry/options/ui/base/kustomization.yaml @@ -0,0 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- model-registry-ui-role.yaml +- model-registry-ui-service.yaml +- model-registry-ui-deployment.yaml +- model-registry-ui-service-account.yaml + +images: +- name: model-registry-ui + newName: ghcr.io/kubeflow/model-registry/ui + newTag: v0.2.19 diff --git a/charts/model-registry/options/ui/base/model-registry-ui-deployment.yaml b/charts/model-registry/options/ui/base/model-registry-ui-deployment.yaml new file mode 100644 index 0000000..a1fde60 --- /dev/null +++ b/charts/model-registry/options/ui/base/model-registry-ui-deployment.yaml @@ -0,0 +1,60 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: model-registry-ui + labels: + app: model-registry-ui +spec: + replicas: 1 + selector: + matchLabels: + app: model-registry-ui + template: + metadata: + labels: + app: model-registry-ui + spec: + serviceAccountName: model-registry-ui + securityContext: + seccompProfile: + type: RuntimeDefault + runAsNonRoot: true + containers: + - name: model-registry-ui + image: model-registry-ui + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthcheck + port: 8080 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 15 + periodSeconds: 30 + successThreshold: 1 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /healthcheck + port: 8080 + scheme: HTTP + initialDelaySeconds: 15 + timeoutSeconds: 15 + periodSeconds: 30 + successThreshold: 1 + failureThreshold: 3 + resources: + limits: + memory: 2Gi + requests: + cpu: 500m + memory: 2Gi + ports: + - containerPort: 8080 + args: + - "--port=8080" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL diff --git a/charts/model-registry/options/ui/base/model-registry-ui-role.yaml b/charts/model-registry/options/ui/base/model-registry-ui-role.yaml new file mode 100644 index 0000000..d1dfef4 --- /dev/null +++ b/charts/model-registry/options/ui/base/model-registry-ui-role.yaml @@ -0,0 +1,76 @@ +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: model-registry-ui-services-reader +rules: +- apiGroups: + - '' + resources: + - services + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: model-registry-ui-services-reader-binding +subjects: +- kind: ServiceAccount + name: model-registry-ui +roleRef: + kind: ClusterRole + name: model-registry-ui-services-reader + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: model-registry-retrieve-clusterrolebindings +rules: +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: model-registry-retrieve-clusterrolebindings-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: model-registry-retrieve-clusterrolebindings +subjects: +- kind: ServiceAccount + name: model-registry-ui +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: model-registry-create-sars +rules: +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: model-registry-create-sars-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: model-registry-create-sars +subjects: +- kind: ServiceAccount + name: model-registry-ui diff --git a/charts/model-registry/options/ui/base/model-registry-ui-service-account.yaml b/charts/model-registry/options/ui/base/model-registry-ui-service-account.yaml new file mode 100644 index 0000000..a35ae35 --- /dev/null +++ b/charts/model-registry/options/ui/base/model-registry-ui-service-account.yaml @@ -0,0 +1,5 @@ +--- +kind: ServiceAccount +apiVersion: v1 +metadata: + name: model-registry-ui diff --git a/charts/model-registry/options/ui/base/model-registry-ui-service.yaml b/charts/model-registry/options/ui/base/model-registry-ui-service.yaml new file mode 100644 index 0000000..c907d59 --- /dev/null +++ b/charts/model-registry/options/ui/base/model-registry-ui-service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: model-registry-ui-service + labels: + app: model-registry-ui + run: model-registry-ui +spec: + selector: + app: model-registry-ui + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 8080 + type: ClusterIP diff --git a/charts/model-registry/options/ui/overlays/integrated/kustomization.yaml b/charts/model-registry/options/ui/overlays/integrated/kustomization.yaml new file mode 100644 index 0000000..95429ed --- /dev/null +++ b/charts/model-registry/options/ui/overlays/integrated/kustomization.yaml @@ -0,0 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../../base + +patches: + - path: model-registry-ui-deployment.yaml + target: + group: apps + version: v1 + kind: Deployment + name: model-registry-ui diff --git a/charts/model-registry/options/ui/overlays/integrated/model-registry-ui-deployment.yaml b/charts/model-registry/options/ui/overlays/integrated/model-registry-ui-deployment.yaml new file mode 100644 index 0000000..cb2fc68 --- /dev/null +++ b/charts/model-registry/options/ui/overlays/integrated/model-registry-ui-deployment.yaml @@ -0,0 +1,5 @@ +- op: add + path: /spec/template/spec/containers/0/args + value: + - "--standalone-mode=false" + - "--port=8080" diff --git a/charts/model-registry/options/ui/overlays/istio/authorization-policy-ui.yaml b/charts/model-registry/options/ui/overlays/istio/authorization-policy-ui.yaml new file mode 100644 index 0000000..60dd145 --- /dev/null +++ b/charts/model-registry/options/ui/overlays/istio/authorization-policy-ui.yaml @@ -0,0 +1,16 @@ +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: model-registry-ui + labels: + app: model-registry-ui +spec: + action: ALLOW + rules: + - from: + - source: + principals: + - cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account + selector: + matchLabels: + app: model-registry-ui diff --git a/charts/model-registry/options/ui/overlays/istio/destination-rule-ui.yaml b/charts/model-registry/options/ui/overlays/istio/destination-rule-ui.yaml new file mode 100644 index 0000000..330366f --- /dev/null +++ b/charts/model-registry/options/ui/overlays/istio/destination-rule-ui.yaml @@ -0,0 +1,11 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: model-registry-ui + labels: + app: model-registry-ui +spec: + host: model-registry-ui-service.kubeflow.svc.cluster.local + trafficPolicy: + tls: + mode: ISTIO_MUTUAL diff --git a/charts/model-registry/options/ui/overlays/istio/kustomization.yaml b/charts/model-registry/options/ui/overlays/istio/kustomization.yaml new file mode 100644 index 0000000..c0f6f8f --- /dev/null +++ b/charts/model-registry/options/ui/overlays/istio/kustomization.yaml @@ -0,0 +1,17 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- ../integrated +- virtual-service.yaml +- destination-rule-ui.yaml +- authorization-policy-ui.yaml + +patches: + - path: model-registry-ui-service.yaml + target: + version: v1 + kind: Service + name: model-registry-ui-service + +namespace: kubeflow \ No newline at end of file diff --git a/charts/model-registry/options/ui/overlays/istio/model-registry-ui-service.yaml b/charts/model-registry/options/ui/overlays/istio/model-registry-ui-service.yaml new file mode 100644 index 0000000..9bcead7 --- /dev/null +++ b/charts/model-registry/options/ui/overlays/istio/model-registry-ui-service.yaml @@ -0,0 +1,3 @@ +- op: replace + path: /spec/ports/0/port + value: 80 diff --git a/charts/model-registry/options/ui/overlays/istio/virtual-service.yaml b/charts/model-registry/options/ui/overlays/istio/virtual-service.yaml new file mode 100644 index 0000000..1091600 --- /dev/null +++ b/charts/model-registry/options/ui/overlays/istio/virtual-service.yaml @@ -0,0 +1,26 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: model-registry-ui + labels: + app: model-registry-ui +spec: + gateways: + - kubeflow-gateway + hosts: + - '*' + http: + - headers: + request: + add: + x-forwarded-prefix: /model-registry + match: + - uri: + prefix: /model-registry/ + rewrite: + uri: / + route: + - destination: + host: model-registry-ui-service.kubeflow.svc.cluster.local + port: + number: 80 diff --git a/charts/model-registry/options/ui/overlays/standalone/kubeflow-dashboard-rbac.yaml b/charts/model-registry/options/ui/overlays/standalone/kubeflow-dashboard-rbac.yaml new file mode 100644 index 0000000..9bfca02 --- /dev/null +++ b/charts/model-registry/options/ui/overlays/standalone/kubeflow-dashboard-rbac.yaml @@ -0,0 +1,39 @@ +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: model-registry-ui-namespaces-reader +rules: +- apiGroups: + - '' + resources: + - namespaces + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: model-registry-ui-namespaces-reader-binding +subjects: +- kind: ServiceAccount + name: model-registry-ui +roleRef: + kind: ClusterRole + name: model-registry-ui-namespaces-reader + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: service-access-cluster-binding +subjects: + - kind: User + name: user@example.com + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io diff --git a/charts/model-registry/options/ui/overlays/standalone/kustomization.yaml b/charts/model-registry/options/ui/overlays/standalone/kustomization.yaml new file mode 100644 index 0000000..551b7d7 --- /dev/null +++ b/charts/model-registry/options/ui/overlays/standalone/kustomization.yaml @@ -0,0 +1,15 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- ../../base +- kubeflow-dashboard-rbac.yaml + +patches: +- path: model-registry-ui-deployment.yaml + target: + group: apps + kind: Deployment + name: model-registry-ui + version: v1 +namespace: kubeflow diff --git a/charts/model-registry/options/ui/overlays/standalone/model-registry-ui-deployment.yaml b/charts/model-registry/options/ui/overlays/standalone/model-registry-ui-deployment.yaml new file mode 100644 index 0000000..0d41529 --- /dev/null +++ b/charts/model-registry/options/ui/overlays/standalone/model-registry-ui-deployment.yaml @@ -0,0 +1,5 @@ +- op: add + path: /spec/template/spec/containers/0/args + value: + - "--standalone-mode=true" + - "--port=8080" diff --git a/charts/model-registry/overlays/argocd/README.md b/charts/model-registry/overlays/argocd/README.md new file mode 100644 index 0000000..77a3ee5 --- /dev/null +++ b/charts/model-registry/overlays/argocd/README.md @@ -0,0 +1,127 @@ +# ArgoCD Deployment for Kubeflow Model Registry + +์ด ๋””๋ ‰ํ† ๋ฆฌ๋Š” ArgoCD๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Kubeflow Model Registry Core ์ปดํฌ๋„ŒํŠธ๋ฅผ Profile ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ๋ฐฐํฌํ•˜๊ธฐ ์œ„ํ•œ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. + +## ๊ฐœ์š” + +์ด overlay๋Š” Model Registry์˜ **Core ์ปดํฌ๋„ŒํŠธ๋งŒ**์„ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค: +- **Database**: MySQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (initContainer ํฌํ•จ) +- **Model Registry Server**: REST/gRPC API ์„œ๋ฒ„ (๋ฆฌ์†Œ์Šค ์ œํ•œ ํฌํ•จ) + +> **์ฐธ๊ณ **: UI ์ปดํฌ๋„ŒํŠธ ๋ฐ Istio ์„ค์ •์€ ๋ณ„๋„๋กœ kubeflow ์นดํƒˆ๋กœ๊ทธ์—์„œ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. + +## ์‚ฌ์ „ ์š”๊ตฌ์‚ฌํ•ญ + +- ArgoCD๊ฐ€ ํด๋Ÿฌ์Šคํ„ฐ์— ์„ค์น˜๋˜๊ณ  ๊ตฌ์„ฑ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค +- ์ด ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋“ค์ด ํฌํ•จ๋œ Git ์ €์žฅ์†Œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค + +## ๋ฐฐํฌ ๋ฐฉ๋ฒ• + +### Core ์ปดํฌ๋„ŒํŠธ ๋ฐฐํฌ (Profile ๋„ค์ž„์ŠคํŽ˜์ด์Šค) + +1. **ArgoCD Application ๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŽธ์ง‘**: + ```bash + vim model-registry-application.yaml + ``` + + ๋‹ค์Œ ํ•ญ๋ชฉ๋“ค์„ ์ˆ˜์ •: + - `metadata.name`: Application ์ด๋ฆ„ (์˜ˆ: `model-registry-demo01-test`) + - `metadata.namespace`: ArgoCD ๋„ค์ž„์ŠคํŽ˜์ด์Šค (์˜ˆ: `platform`) + - `spec.source.repoURL`: Git ์ €์žฅ์†Œ URL + - `spec.source.targetRevision`: ๋ธŒ๋žœ์น˜/ํƒœ๊ทธ (์˜ˆ: `model-registry/v0.2.19`) + - `spec.destination.namespace`: ๋Œ€์ƒ Profile ๋„ค์ž„์ŠคํŽ˜์ด์Šค (์˜ˆ: `demo01-test`) + +2. **ArgoCD Application ๋ฐฐํฌ**: + ```bash + kubectl apply -f model-registry-application.yaml + ``` + +### ์‹ค์ œ ๋ฐฐํฌ ์˜ˆ์‹œ + +ํ…Œ์ŠคํŠธ๋œ ์„ค์ • ์˜ˆ์‹œ: +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: model-registry-demo01-test + namespace: platform +spec: + source: + repoURL: https://gitea.example.org/dip/tenant-catalog + targetRevision: model-registry/v0.2.19 + path: model-registry/overlays/argocd + destination: + namespace: demo01-test +``` + +## ๋ฐฐํฌ ํ™•์ธ + +### ArgoCD Application ์ƒํƒœ ํ™•์ธ +```bash +# ArgoCD CLI ์‚ฌ์šฉ (์„ค์น˜๋œ ๊ฒฝ์šฐ) +argocd app get model-registry-demo01-test + +# ์ˆ˜๋™ ๋™๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ +argocd app sync model-registry-demo01-test + +# kubectl๋กœ Application ์ƒํƒœ ํ™•์ธ +kubectl get application -n platform model-registry-demo01-test +``` + +### ๋ฐฐํฌ๋œ ๋ฆฌ์†Œ์Šค ํ™•์ธ +```bash +# Profile ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ๋ฆฌ์†Œ์Šค ํ™•์ธ +kubectl get pods -n demo01-test +kubectl get svc -n demo01-test +kubectl get deployment -n demo01-test + +# ํŠน์ • ์ปดํฌ๋„ŒํŠธ ์ƒํƒœ ํ™•์ธ +kubectl get pods -n demo01-test -l app.kubernetes.io/name=model-registry +``` + +## ํฌํ•จ๋œ ์ปดํฌ๋„ŒํŠธ ๋ฐ ๋ฆฌ์†Œ์Šค ์„ค์ • + +### 1. Model Registry Database (MySQL) +- **Deployment**: `model-registry-db` +- **Service**: `model-registry-db` +- **PVC**: `metadata-mysql` +- **ํŠน๋ณ„ ์„ค์ •**: + - initContainer๋กœ ๊ถŒํ•œ ์„ค์ • (`chown 999:999 /var/lib/mysql`) + - ๋ฆฌ์†Œ์Šค ์š”์ฒญ: CPU 100m, Memory 100M + +### 2. Model Registry Server +- **Deployment**: `model-registry-deployment` +- **Service**: `model-registry-service` +- **์ปจํ…Œ์ด๋„ˆ๋ณ„ ๋ฆฌ์†Œ์Šค ์„ค์ •**: + - **rest-container**: + - Requests: CPU 100m, Memory 256Mi + - Limits: CPU 500m, Memory 512Mi + - **grpc-container**: + - Requests: CPU 100m, Memory 128Mi + - Limits: CPU 500m, Memory 512Mi + +### 3. Istio ๋„คํŠธ์›Œํ‚น +- **VirtualService**: ๋ผ์šฐํŒ… ๊ทœ์น™ +- **DestinationRule**: ํŠธ๋ž˜ํ”ฝ ์ •์ฑ… +- **AuthorizationPolicy**: ์ ‘๊ทผ ์ œ์–ด + +## ์ œ๊ฑฐ + +```bash +# ArgoCD Application ์ œ๊ฑฐ +kubectl delete -f model-registry-application.yaml + +# ๋˜๋Š” ์ง์ ‘ ์‚ญ์ œ +kubectl delete application -n platform model-registry-demo01-test +``` + +## ํŒŒ์ผ ๊ตฌ์กฐ + +``` +overlays/argocd/ +โ”œโ”€โ”€ README.md # ์ด ํŒŒ์ผ +โ”œโ”€โ”€ kustomization.yaml # ๋ฉ”์ธ kustomization ์„ค์ • +โ”œโ”€โ”€ model-registry-application.yaml # ArgoCD Application ๋งค๋‹ˆํŽ˜์ŠคํŠธ +โ”œโ”€โ”€ patch-db-deployment.yaml # DB ๋ฐฐํฌ ํŒจ์น˜ (initContainer + ๋ฆฌ์†Œ์Šค) +โ””โ”€โ”€ patch-model-registry-deployment.yaml # ์„œ๋ฒ„ ๋ฐฐํฌ ํŒจ์น˜ (๋ฆฌ์†Œ์Šค ์ œํ•œ) +``` diff --git a/charts/model-registry/overlays/argocd/kustomization.yaml b/charts/model-registry/overlays/argocd/kustomization.yaml new file mode 100644 index 0000000..a1affb5 --- /dev/null +++ b/charts/model-registry/overlays/argocd/kustomization.yaml @@ -0,0 +1,30 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +# Include core model registry components (for profile namespace) +resources: + # Database and core model registry components + - ../db + # Istio networking components + - ../../options/istio + +# Patches for deployments +patches: + - path: patch-db-deployment.yaml + target: + group: apps + version: v1 + kind: Deployment + name: model-registry-db + - path: patch-model-registry-deployment.yaml + target: + group: apps + version: v1 + kind: Deployment + name: model-registry-deployment + +# Common labels for all resources +commonLabels: + app.kubernetes.io/name: model-registry + app.kubernetes.io/component: model-registry-core + app.kubernetes.io/part-of: kubeflow \ No newline at end of file diff --git a/charts/model-registry/overlays/argocd/model-registry-application.yaml b/charts/model-registry/overlays/argocd/model-registry-application.yaml new file mode 100644 index 0000000..db1a676 --- /dev/null +++ b/charts/model-registry/overlays/argocd/model-registry-application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: model-registry-demo01-test + namespace: platform + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + source: + repoURL: https://gitea.example.org/dip/tenant-catalog # Replace with your actual repository URL + targetRevision: model-registry/v0.2.19 + path: model-registry/overlays/argocd + destination: + server: https://kubernetes.default.svc + namespace: demo01-test # Replace with your actual profile namespace + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ApplyOutOfSyncOnly=true + ignoreDifferences: + - group: apps + kind: Deployment + jsonPointers: + - /spec/replicas \ No newline at end of file diff --git a/charts/model-registry/overlays/argocd/patch-db-deployment.yaml b/charts/model-registry/overlays/argocd/patch-db-deployment.yaml new file mode 100644 index 0000000..35a0b33 --- /dev/null +++ b/charts/model-registry/overlays/argocd/patch-db-deployment.yaml @@ -0,0 +1,33 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: model-registry-db +spec: + template: + spec: + ## initContainer ์ถ”๊ฐ€ + initContainers: + - args: + - /bin/sh + - -c + - chown 999:999 /var/lib/mysql + image: busybox:1.36 + imagePullPolicy: IfNotPresent + name: init-permissions + resources: + requests: + cpu: 100m + memory: 100Mi + securityContext: + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 + volumeMounts: + - mountPath: /var/lib/mysql + name: metadata-mysql + containers: + - name: db-container + resources: + requests: + cpu: 100m + memory: 100M \ No newline at end of file diff --git a/charts/model-registry/overlays/argocd/patch-model-registry-deployment.yaml b/charts/model-registry/overlays/argocd/patch-model-registry-deployment.yaml new file mode 100644 index 0000000..f3ee677 --- /dev/null +++ b/charts/model-registry/overlays/argocd/patch-model-registry-deployment.yaml @@ -0,0 +1,24 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: model-registry-deployment +spec: + template: + spec: + containers: + - name: rest-container + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + - name: grpc-container + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi \ No newline at end of file diff --git a/charts/model-registry/overlays/db/kustomization.yaml b/charts/model-registry/overlays/db/kustomization.yaml new file mode 100644 index 0000000..e3e2ec8 --- /dev/null +++ b/charts/model-registry/overlays/db/kustomization.yaml @@ -0,0 +1,69 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- model-registry-db-pvc.yaml +- model-registry-db-deployment.yaml +- model-registry-db-service.yaml +- ../../base + + +configMapGenerator: +- envs: + - params.env + name: model-registry-db-parameters +secretGenerator: +- envs: + - secrets.env + name: model-registry-db-secrets +generatorOptions: + disableNameSuffixHash: true + + +images: +- name: mysql + newName: mysql + newTag: 8.3.0 + +patches: +- path: patches/model-registry-deployment.yaml +replacements: +- source: + fieldPath: metadata.name + kind: Service + name: model-registry-db + version: v1 + targets: + - fieldPaths: + - spec.template.spec.containers.1.args.1 + options: + delimiter: = + index: 1 + select: + group: apps + kind: Deployment + name: model-registry-deployment + version: v1 +- source: + fieldPath: data.MYSQL_PORT + kind: ConfigMap + name: model-registry-db-parameters + version: v1 + targets: + - fieldPaths: + - spec.template.spec.containers.1.args.3 + options: + delimiter: = + index: 1 + select: + group: apps + kind: Deployment + name: model-registry-deployment + version: v1 + - fieldPaths: + - spec.template.metadata.annotations.[traffic.sidecar.istio.io/excludeOutboundPorts] + select: + group: apps + kind: Deployment + name: model-registry-deployment + version: v1 diff --git a/charts/model-registry/overlays/db/model-registry-db-deployment.yaml b/charts/model-registry/overlays/db/model-registry-db-deployment.yaml new file mode 100644 index 0000000..f19ce5f --- /dev/null +++ b/charts/model-registry/overlays/db/model-registry-db-deployment.yaml @@ -0,0 +1,62 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: model-registry-db + labels: + component: db +spec: + selector: + matchLabels: + component: db + replicas: 1 + strategy: + type: Recreate + template: + metadata: + name: db + labels: + component: db + sidecar.istio.io/inject: "false" + spec: + securityContext: + seccompProfile: + type: RuntimeDefault + runAsNonRoot: true + containers: + - name: db-container + image: mysql:8.3.0 + args: + - --datadir + - /var/lib/mysql/datadir + - --default-authentication-plugin=mysql_native_password + envFrom: + - configMapRef: + name: model-registry-db-parameters + - secretRef: + name: model-registry-db-secrets + ports: + - name: dbapi + containerPort: 3306 + readinessProbe: + exec: + command: + - "/bin/bash" + - "-c" + - "mysql -D $$MYSQL_DATABASE -u$$MYSQL_USER_NAME -p$$MYSQL_ROOT_PASSWORD -e 'SELECT 1'" + initialDelaySeconds: 5 + periodSeconds: 2 + timeoutSeconds: 1 + volumeMounts: + - name: metadata-mysql + mountPath: /var/lib/mysql + securityContext: + runAsUser: 999 + runAsGroup: 999 + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + volumes: + - name: metadata-mysql + persistentVolumeClaim: + claimName: metadata-mysql diff --git a/charts/model-registry/overlays/db/model-registry-db-pvc.yaml b/charts/model-registry/overlays/db/model-registry-db-pvc.yaml new file mode 100644 index 0000000..b1c083d --- /dev/null +++ b/charts/model-registry/overlays/db/model-registry-db-pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: metadata-mysql +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi diff --git a/charts/model-registry/overlays/db/model-registry-db-service.yaml b/charts/model-registry/overlays/db/model-registry-db-service.yaml new file mode 100644 index 0000000..f27c8c7 --- /dev/null +++ b/charts/model-registry/overlays/db/model-registry-db-service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: model-registry-db + labels: + component: db +spec: + type: ClusterIP + ports: + - port: 3306 + protocol: TCP + name: dbapi + selector: + component: db diff --git a/charts/model-registry/overlays/db/params.env b/charts/model-registry/overlays/db/params.env new file mode 100644 index 0000000..5ab2adb --- /dev/null +++ b/charts/model-registry/overlays/db/params.env @@ -0,0 +1,3 @@ +MYSQL_DATABASE=metadb +MYSQL_PORT=3306 +MYSQL_ALLOW_EMPTY_PASSWORD=true \ No newline at end of file diff --git a/charts/model-registry/overlays/db/patches/model-registry-deployment.yaml b/charts/model-registry/overlays/db/patches/model-registry-deployment.yaml new file mode 100644 index 0000000..0d61bf3 --- /dev/null +++ b/charts/model-registry/overlays/db/patches/model-registry-deployment.yaml @@ -0,0 +1,42 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: model-registry-deployment +spec: + template: + metadata: + annotations: + # db doesn't use istio + traffic.sidecar.istio.io/excludeOutboundPorts: MYSQL_PORT_PLACEHOLDER + spec: + containers: + - name: rest-container + # Remove existing environment variables + env: + - $patch: replace + envFrom: + - configMapRef: + name: model-registry-configmap + args: + - --hostname=0.0.0.0 + - --port=$(MODEL_REGISTRY_REST_SERVICE_PORT) + - --mlmd-hostname=localhost + - --mlmd-port=$(MODEL_REGISTRY_GRPC_SERVICE_PORT) + - --datastore-type=$(MODEL_REGISTRY_DATA_STORE_TYPE) + - name: grpc-container + # Remove existing environment variables + env: + - $patch: replace + envFrom: + - configMapRef: + name: model-registry-db-parameters + - secretRef: + name: model-registry-db-secrets + - configMapRef: + name: model-registry-configmap + args: ["--grpc_port=$(MODEL_REGISTRY_GRPC_SERVICE_PORT)", + "--mysql_config_host=MLMD_DB_HOST_PLACEHOLDER", + "--mysql_config_database=$(MYSQL_DATABASE)", + "--mysql_config_port=MYSQL_PORT_PLACEHOLDER", + "--mysql_config_user=$(MYSQL_USER_NAME)", + "--mysql_config_password=$(MYSQL_ROOT_PASSWORD)"] diff --git a/charts/model-registry/overlays/db/secrets.env b/charts/model-registry/overlays/db/secrets.env new file mode 100644 index 0000000..44ac2ee --- /dev/null +++ b/charts/model-registry/overlays/db/secrets.env @@ -0,0 +1,2 @@ +MYSQL_USER_NAME=root +MYSQL_ROOT_PASSWORD=test \ No newline at end of file diff --git a/charts/model-registry/overlays/postgres/kustomization.yaml b/charts/model-registry/overlays/postgres/kustomization.yaml new file mode 100644 index 0000000..0f81c89 --- /dev/null +++ b/charts/model-registry/overlays/postgres/kustomization.yaml @@ -0,0 +1,68 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- model-registry-db-pvc.yaml +- model-registry-db-deployment.yaml +- model-registry-db-service.yaml +- ../../base + + +configMapGenerator: +- envs: + - params.env + name: metadata-registry-db-parameters +secretGenerator: +- envs: + - secrets.env + name: metadata-registry-db-secrets +generatorOptions: + disableNameSuffixHash: true + +images: +- name: postgres + newName: postgres + newTag: 14.7-alpine3.17 + +patches: +- path: patches/model-registry-deployment.yaml +replacements: +- source: + fieldPath: metadata.name + kind: Service + name: metadata-postgres-db + version: v1 + targets: + - fieldPaths: + - spec.template.spec.containers.0.args.2 + options: + delimiter: = + index: 1 + select: + group: apps + kind: Deployment + name: model-registry-deployment + version: v1 +- source: + fieldPath: data.POSTGRES_PORT + kind: ConfigMap + name: metadata-registry-db-parameters + version: v1 + targets: + - fieldPaths: + - spec.template.metadata.annotations.[traffic.sidecar.istio.io/excludeOutboundPorts] + select: + group: apps + kind: Deployment + name: model-registry-deployment + version: v1 + - fieldPaths: + - spec.template.spec.containers.0.args.3 + options: + delimiter: = + index: 1 + select: + group: apps + kind: Deployment + name: model-registry-deployment + version: v1 diff --git a/charts/model-registry/overlays/postgres/model-registry-db-deployment.yaml b/charts/model-registry/overlays/postgres/model-registry-db-deployment.yaml new file mode 100644 index 0000000..7128631 --- /dev/null +++ b/charts/model-registry/overlays/postgres/model-registry-db-deployment.yaml @@ -0,0 +1,52 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: metadata-postgres-db + labels: + component: db +spec: + selector: + matchLabels: + component: db + replicas: 1 + strategy: + type: Recreate + template: + metadata: + name: db + labels: + component: db + sidecar.istio.io/inject: "false" + spec: + securityContext: + seccompProfile: + type: RuntimeDefault + runAsNonRoot: true + containers: + - name: db-container + image: postgres + env: + - name: PGDATA + value: /var/lib/postgresql/data/pgdata + envFrom: + - configMapRef: + name: metadata-registry-db-parameters + - secretRef: + name: metadata-registry-db-secrets + ports: + - name: postgres + containerPort: 5432 + volumeMounts: + - name: metadata-postgres + mountPath: /var/lib/postgresql/data + securityContext: + runAsUser: 70 + runAsGroup: 70 + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + volumes: + - name: metadata-postgres + persistentVolumeClaim: + claimName: metadata-postgres diff --git a/charts/model-registry/overlays/postgres/model-registry-db-pvc.yaml b/charts/model-registry/overlays/postgres/model-registry-db-pvc.yaml new file mode 100644 index 0000000..1379048 --- /dev/null +++ b/charts/model-registry/overlays/postgres/model-registry-db-pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: metadata-postgres +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Gi diff --git a/charts/model-registry/overlays/postgres/model-registry-db-service.yaml b/charts/model-registry/overlays/postgres/model-registry-db-service.yaml new file mode 100644 index 0000000..63902a6 --- /dev/null +++ b/charts/model-registry/overlays/postgres/model-registry-db-service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: metadata-postgres-db + labels: + component: db +spec: + type: ClusterIP + ports: + - port: 5432 + protocol: TCP + name: postgres + selector: + component: db diff --git a/charts/model-registry/overlays/postgres/params.env b/charts/model-registry/overlays/postgres/params.env new file mode 100644 index 0000000..fce7e26 --- /dev/null +++ b/charts/model-registry/overlays/postgres/params.env @@ -0,0 +1,2 @@ +POSTGRES_PORT=5432 +POSTGRES_DBNAME=mlmdpostgres \ No newline at end of file diff --git a/charts/model-registry/overlays/postgres/patches/model-registry-deployment.yaml b/charts/model-registry/overlays/postgres/patches/model-registry-deployment.yaml new file mode 100644 index 0000000..1dec4cd --- /dev/null +++ b/charts/model-registry/overlays/postgres/patches/model-registry-deployment.yaml @@ -0,0 +1,32 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: model-registry-deployment +spec: + template: + metadata: + annotations: + # db doesn't use istio + traffic.sidecar.istio.io/excludeOutboundPorts: POSTGRES_PORT_PLACEHOLDER + spec: + containers: + - name: grpc-container + # Remove existing environment variables + env: + - $patch: replace + envFrom: + - configMapRef: + name: metadata-registry-db-parameters + - secretRef: + name: metadata-registry-db-secrets + - configMapRef: + name: model-registry-configmap + args: ["--grpc_port=$(MODEL_REGISTRY_GRPC_SERVICE_PORT)", + "--metadata_source_config_type=postgresql", + "--postgres_config_host=MLMD_DB_HOST_PLACEHOLDER", + "--postgres_config_port=POSTGRES_PORT_PLACEHOLDER", + "--postgres_config_dbname=$(POSTGRES_DBNAME)", + "--postgres_config_user=$(POSTGRES_USER)", + "--postgres_config_password=$(POSTGRES_PASSWORD)", + # "--postgres_config_skip_db_creation=true", + "--enable_database_upgrade=true"] diff --git a/charts/model-registry/overlays/postgres/secrets.env b/charts/model-registry/overlays/postgres/secrets.env new file mode 100644 index 0000000..973d158 --- /dev/null +++ b/charts/model-registry/overlays/postgres/secrets.env @@ -0,0 +1,2 @@ +POSTGRES_USER=root +POSTGRES_PASSWORD=password \ No newline at end of file