Add model registry v0.2.19

This commit is contained in:
wbsong111
2025-07-01 14:28:17 +09:00
parent f8d6965288
commit 6e83726fb3
68 changed files with 2018 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
approvers:
- tarilabs
- rareddy
- Tomcli
reviewers:
- tarilabs
- rareddy
- Tomcli
+136
View File
@@ -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=<your-profile>
```
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=<your-profile>
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
```
@@ -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
@@ -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"
@@ -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
@@ -0,0 +1,4 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: model-registry-server
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,2 @@
resources:
- 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
@@ -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
@@ -0,0 +1,2 @@
resources:
- allow-metrics-traffic.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
@@ -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
@@ -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
@@ -0,0 +1,2 @@
resources:
- 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,9 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: metrics-reader
rules:
- nonResourceURLs:
- "/metrics"
verbs:
- get
@@ -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
@@ -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
@@ -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
@@ -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://
@@ -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
@@ -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
@@ -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:
- {}
@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- istio-authorization-policy.yaml
- destination-rule.yaml
- 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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,5 @@
---
kind: ServiceAccount
apiVersion: v1
metadata:
name: model-registry-ui
@@ -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
@@ -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
@@ -0,0 +1,5 @@
- op: add
path: /spec/template/spec/containers/0/args
value:
- "--standalone-mode=false"
- "--port=8080"
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,3 @@
- op: replace
path: /spec/ports/0/port
value: 80
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,5 @@
- op: add
path: /spec/template/spec/containers/0/args
value:
- "--standalone-mode=true"
- "--port=8080"
@@ -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 # 서버 배포 패치 (리소스 제한)
```
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,10 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: metadata-mysql
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
@@ -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
@@ -0,0 +1,3 @@
MYSQL_DATABASE=metadb
MYSQL_PORT=3306
MYSQL_ALLOW_EMPTY_PASSWORD=true
@@ -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)"]
@@ -0,0 +1,2 @@
MYSQL_USER_NAME=root
MYSQL_ROOT_PASSWORD=test
@@ -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
@@ -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
@@ -0,0 +1,10 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: metadata-postgres
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
@@ -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
@@ -0,0 +1,2 @@
POSTGRES_PORT=5432
POSTGRES_DBNAME=mlmdpostgres
@@ -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"]
@@ -0,0 +1,2 @@
POSTGRES_USER=root
POSTGRES_PASSWORD=password