From 16fd84fc432086c38b563b100092c908ad16e9ff Mon Sep 17 00:00:00 2001 From: Rafal Skolasinski Date: Tue, 5 Jan 2021 21:47:07 +0000 Subject: [PATCH 1/2] extend init containers documentation --- doc/source/servers/overview.md | 81 +++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 5 deletions(-) diff --git a/doc/source/servers/overview.md b/doc/source/servers/overview.md index b1152c9e70..fda44760f1 100644 --- a/doc/source/servers/overview.md +++ b/doc/source/servers/overview.md @@ -36,9 +36,80 @@ The `modelUri` specifies the bucket containing the saved model, in this case `gs - Minio-compatible (using `s3://`) - Azure Blob storage (using `https://(.+?).blob.core.windows.net/(.+)`) -The download is handled by an initContainer that runs before your predictor loads. This initContainer image uses our [Storage.py library](https://github.com/SeldonIO/seldon-core/blob/master/python/seldon_core/storage.py) to download the files. However it is also possible for you to override the initContainer with your own custom container to download any files from custom resources. -## Further Customisation for Pre-packaged Model Servers +## Init Containers + +Seldon Core uses [Init Containers](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/) to download model binaries for the prepackaged model servers. We use [kfserving's storage.py library](https://github.com/kubeflow/kfserving/blob/master/python/kfserving/kfserving/storage.py +) for our `Init Containers` by defining +```yaml +storageInitializer: + image: gcr.io/kfserving/storage-initializer:v0.4.0 +``` +in our default [helm values](../charts/seldon-core-operator.html#values). +See the [Dockerfile](https://github.com/kubeflow/kfserving/blob/master/python/storage-initializer.Dockerfile +) and its [entrypoint](https://github.com/kubeflow/kfserving/blob/master/python/storage-initializer/scripts/initializer-entrypoint +) for a detailed reference. + + +### Customizing Init Containers + +One can specify a custom `Init Container` globally by overwriting the `storageInitializer.image` helm value as metnioned above. +The `entrypoint` of the `container` must take two arguments: +- first representing the models URI +- second the desired path where binary should be downloaded to + +To illustrate how `initContainers` are used by the prepackaged model servers, following effective `SeldonDeployment` with defualt `initContainer` details updated by the mutating webhook is provided: + +```yaml +apiVersion: machinelearning.seldon.io/v1 +kind: SeldonDeployment +metadata: + name: example +spec: + name: iris + predictors: + - componentSpecs: + - spec: + containers: + - name: classifier + volumeMounts: + - mountPath: /mnt/models + name: classifier-provision-location + readOnly: true + initContainers: + - name: classifier-model-initializer + image: gcr.io/kfserving/storage-initializer:v0.4.0 + imagePullPolicy: IfNotPresent + args: + - s3://sklearn/iris + - /mnt/models + envFrom: + - secretRef: + name: seldon-init-container-secret + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /mnt/models + name: classifier-provision-location + volumes: + - emptyDir: {} + name: classifier-provision-location + graph: + children: [] + implementation: SKLEARN_SERVER + modelUri: s3://sklearn/iris + name: classifier + name: defaul +``` + +Key observations: +- our prepackaged model will expect model binaries to be saved into `/mnt/models` path +- default `initContainers` name is constructed from `{predictiveUnitName}-model-initializer` + +Currently image used for `initContainers` can only be specified globally via helm values. +The per deployment customisation is explored in this [GitHub issue #2611](https://github.com/SeldonIO/seldon-core/issues/2611). + +## Further Customisation for Prepackaged Model Servers If you want to customize the resources for the server you can add a skeleton `Container` with the same name to your podSpecs, e.g. @@ -81,13 +152,13 @@ Next steps: - [SKLearn Server with MinIO](../examples/minio-sklearn.html) You can also build and add your own [custom inference servers](./custom.md), -which can then be used in a similar way as the pre-packaged ones. +which can then be used in a similar way as the prepackaged ones. If your use case does not fit for a reusable standard server then you can create your own component using our wrappers. ## Handling Credentials -In order to handle credentials you must make available a secret with the environment variables that will be added into the initContainer. For this you need to perform the following actions: +In order to handle credentials you must make available a secret with the environment variables that will be added into the `Init Containers`. For this you need to perform the following actions: 1. Understand which environment variables you need to set 2. Create a secret containing the environment variables @@ -95,7 +166,7 @@ In order to handle credentials you must make available a secret with the environ ### 1. Understand which Environment Variables you need to set -In order to understand what are the environment variables required, you can have a look directly into our [Storage.py library](https://github.com/SeldonIO/seldon-core/blob/master/python/seldon_core/storage.py) that we use in our initContainer. +In order to understand what are the environment variables required, you can have a look directly into our [Storage.py library](https://github.com/SeldonIO/seldon-core/blob/master/python/seldon_core/storage.py) that we use in our `Init Containers`. #### AWS Required Variables From ee85ce3acbe9c4edcee2e0e22dc6fe0032877fc7 Mon Sep 17 00:00:00 2001 From: Rafal Skolasinski Date: Thu, 7 Jan 2021 18:56:15 +0000 Subject: [PATCH 2/2] add rclone-based custom init container example --- .../examples/custom_init_container.nblink | 3 + doc/source/servers/overview.md | 7 + examples/init_containers/Dockerfile | 2 + examples/init_containers/Makefile | 14 + .../custom_init_container.ipynb | 563 ++++++++++++++++++ .../explicit-init-definition.yaml | 66 ++ .../init_containers/rclone-default-init.yaml | 15 + .../seldon-reclone-secret.yaml | 13 + 8 files changed, 683 insertions(+) create mode 100644 doc/source/examples/custom_init_container.nblink create mode 100644 examples/init_containers/Dockerfile create mode 100644 examples/init_containers/Makefile create mode 100644 examples/init_containers/custom_init_container.ipynb create mode 100644 examples/init_containers/explicit-init-definition.yaml create mode 100644 examples/init_containers/rclone-default-init.yaml create mode 100644 examples/init_containers/seldon-reclone-secret.yaml diff --git a/doc/source/examples/custom_init_container.nblink b/doc/source/examples/custom_init_container.nblink new file mode 100644 index 0000000000..bf04f5d579 --- /dev/null +++ b/doc/source/examples/custom_init_container.nblink @@ -0,0 +1,3 @@ +{ + "path": "../../../examples/init_containers/custom_init_container.ipynb" +} diff --git a/doc/source/servers/overview.md b/doc/source/servers/overview.md index fda44760f1..47eadb79fe 100644 --- a/doc/source/servers/overview.md +++ b/doc/source/servers/overview.md @@ -76,6 +76,7 @@ spec: - mountPath: /mnt/models name: classifier-provision-location readOnly: true + initContainers: - name: classifier-model-initializer image: gcr.io/kfserving/storage-initializer:v0.4.0 @@ -83,14 +84,18 @@ spec: args: - s3://sklearn/iris - /mnt/models + envFrom: - secretRef: name: seldon-init-container-secret + terminationMessagePath: /dev/termination-log terminationMessagePolicy: File + volumeMounts: - mountPath: /mnt/models name: classifier-provision-location + volumes: - emptyDir: {} name: classifier-provision-location @@ -109,6 +114,8 @@ Key observations: Currently image used for `initContainers` can only be specified globally via helm values. The per deployment customisation is explored in this [GitHub issue #2611](https://github.com/SeldonIO/seldon-core/issues/2611). +See our [example](../examples/custom_init_container.html) to learn how to write a custom container that uses [rclone](https://rclone.org/) for cloud storage operations. + ## Further Customisation for Prepackaged Model Servers If you want to customize the resources for the server you can add a skeleton `Container` with the same name to your podSpecs, e.g. diff --git a/examples/init_containers/Dockerfile b/examples/init_containers/Dockerfile new file mode 100644 index 0000000000..bfbca540cf --- /dev/null +++ b/examples/init_containers/Dockerfile @@ -0,0 +1,2 @@ +FROM rclone/rclone:latest +ENTRYPOINT ["rclone", "copy"] diff --git a/examples/init_containers/Makefile b/examples/init_containers/Makefile new file mode 100644 index 0000000000..a80fa19450 --- /dev/null +++ b/examples/init_containers/Makefile @@ -0,0 +1,14 @@ +IMAGE_NAME=seldonio/rclone-init-container +IMAGE_VERSION := $(shell cat ../../version.txt) + +KIND_NAME ?= kind + + +build: + docker build . -t ${IMAGE_NAME}:${IMAGE_VERSION} + +push: build + docker push ${IMAGE_NAME}:${IMAGE_VERSION} + +kind_load: build + kind load -v 3 docker-image ${IMAGE_NAME}:${IMAGE_VERSION} --name ${KIND_NAME} diff --git a/examples/init_containers/custom_init_container.ipynb b/examples/init_containers/custom_init_container.ipynb new file mode 100644 index 0000000000..373ad79380 --- /dev/null +++ b/examples/init_containers/custom_init_container.ipynb @@ -0,0 +1,563 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Custom Init Containers with rclone and MinIO\n", + "\n", + "In this tutorial we will deep dive into some of the interals of how Storage Initilizers are used by Prepackaged Model Servers.\n", + "\n", + "We will also write a custom Init Container that will use `rclone` to download model artifacts from the `in-cluster` MinIO storage.\n", + "\n", + "\n", + "## Prerequisites\n", + "\n", + " * A kubernetes cluster with kubectl configured\n", + " * curl\n", + "\n", + "## Setup Seldon Core\n", + "\n", + "Use the setup notebook to [Setup Cluster](https://docs.seldon.io/projects/seldon-core/en/latest/examples/seldon_core_setup.html#Setup-Cluster) with [Ambassador Ingress](https://docs.seldon.io/projects/seldon-core/en/latest/examples/seldon_core_setup.html#Ambassador) and [Install Seldon Core](https://docs.seldon.io/projects/seldon-core/en/latest/examples/seldon_core_setup.html#Install-Seldon-Core). Instructions [also online](https://docs.seldon.io/projects/seldon-core/en/latest/examples/seldon_core_setup.html).\n", + "\n", + "## Setup MinIO\n", + "\n", + "Use the provided [notebook](https://docs.seldon.io/projects/seldon-core/en/latest/examples/minio_setup.html) to install Minio in your cluster and configure `mc` CLI tool. \n", + "Instructions [also online](https://docs.seldon.io/projects/seldon-core/en/latest/examples/minio_setup.html)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Copy iris model into local MinIO" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Added `gcs` successfully.\n", + "Bucket created successfully `minio-seldon/iris`.\n", + "`gcs/seldon-models/sklearn/iris/model.joblib` -> `minio-seldon/iris/model.joblib`\n", + "Total: 0 B, Transferred: 1.06 KiB, Speed: 8.57 KiB/s\n", + "`gcs/seldon-models/sklearn/iris/metadata.yaml` -> `minio-seldon/iris/metadata.yaml`\n", + "Total: 0 B, Transferred: 162 B, Speed: 1.23 KiB/s\n" + ] + } + ], + "source": [ + "%%bash\n", + "mc config host add gcs https://storage.googleapis.com \"\" \"\" \n", + "\n", + "mc mb minio-seldon/iris -p\n", + "mc cp gcs/seldon-models/sklearn/iris/model.joblib minio-seldon/iris/\n", + "mc cp gcs/seldon-models/sklearn/iris/metadata.yaml minio-seldon/iris/" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2021-01-07 18:45:12 GMT] 162B metadata.yaml\n", + "[2021-01-07 18:45:11 GMT] 1.1KiB model.joblib\n" + ] + } + ], + "source": [ + "%%bash\n", + "mc ls minio-seldon/iris/" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Init Containers Deep Dive" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Usually, when using in example SKLearn Prepackaged Model server one defines Seldon Deployment as follows\n", + "```yaml\n", + "apiVersion: machinelearning.seldon.io/v1\n", + "kind: SeldonDeployment\n", + "metadata:\n", + " name: sklearn-default-init-container\n", + "spec:\n", + " name: iris\n", + " predictors:\n", + " - graph:\n", + " implementation: SKLEARN_SERVER\n", + " modelUri: gs://seldon-models/sklearn/iris\n", + " envSecretRefName: seldon-init-container-secret \n", + " name: classifier\n", + " name: default\n", + " replicas: 1\n", + "```\n", + "\n", + "This uses the default storage initilizer defined in the helm values, e.g.:\n", + "```yaml\n", + "storageInitializer:\n", + " image: gcr.io/kfserving/storage-initializer:v0.4.0\n", + "```\n", + "\n", + "There are few things that effectively happens here:\n", + "- `emptyDir: {}` volume is created and mounted into the model `classifier` and init containers `classifier-storage-initializer`\n", + "- the `seldon-init-container-secret` secrets are exposed inside the init container via environmental variables\n", + "- init container is called with two arguments: source `seldon-init-container-secret` and destination `/mnt/models` of artifacts to download\n", + "\n", + "This is well illustrated by the following effective resource definition:\n", + "```yaml\n", + "apiVersion: machinelearning.seldon.io/v1\n", + "kind: SeldonDeployment\n", + "metadata:\n", + " name: custom-init-container\n", + "spec:\n", + " name: iris\n", + " predictors:\n", + " - componentSpecs:\n", + " - spec:\n", + " containers:\n", + " - name: classifier\n", + " volumeMounts:\n", + " - mountPath: /mnt/models\n", + " name: classifier-provision-location\n", + " readOnly: true\n", + "\n", + " initContainers:\n", + " - name: classifier-model-initializer\n", + " image: rafalskolasinski/storage-initializer:v0.4.0\n", + " imagePullPolicy: IfNotPresent\n", + " args:\n", + " - gs://seldon-models/sklearn/iris\n", + " - /mnt/models\n", + "\n", + " envFrom:\n", + " - secretRef:\n", + " name: seldon-init-container-secret\n", + "\n", + " terminationMessagePath: /dev/termination-log\n", + " terminationMessagePolicy: File\n", + "\n", + " volumeMounts:\n", + " - mountPath: /mnt/models\n", + " name: classifier-provision-location\n", + "\n", + " volumes:\n", + " - emptyDir: {}\n", + " name: classifier-provision-location\n", + "\n", + " graph:\n", + " children: []\n", + " implementation: SKLEARN_SERVER\n", + " modelUri: gs://seldon-models/sklearn/iris\n", + " name: classifier\n", + " name: default\n", + " replicas: 1\n", + "```\n", + "\n", + "**Note**:: \n", + "- init container name is constructed from the `${predictiveUnitContainerName}-model-initializer` pattern. \n", + "- If the init container is provided explicitly with name matching the pattern SC won't create one automatically." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Custom Init Container (full inline definition)\n", + "\n", + "We will now define an init container that will use `rclone/rclone:latest` image with a very explicit definition.\n", + "\n", + "**Note**: currently if init container of a matching name is provided manually it will be used as it is." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting explicit-init-definition.yaml\n" + ] + } + ], + "source": [ + "%%writefile explicit-init-definition.yaml\n", + "apiVersion: v1\n", + "kind: Secret\n", + "metadata:\n", + " name: mysecret\n", + "type: Opaque\n", + "stringData:\n", + " rclone.conf: |\n", + " [cluster-minio]\n", + " type = s3\n", + " provider = minio\n", + " env_auth = false\n", + " access_key_id = minioadmin\n", + " secret_access_key = minioadmin\n", + " endpoint = http://minio.minio-system.svc.cluster.local:9000\n", + "\n", + "\n", + "---\n", + "\n", + "apiVersion: machinelearning.seldon.io/v1\n", + "kind: SeldonDeployment\n", + "metadata:\n", + " name: explicit-init-definition\n", + "spec:\n", + " name: iris\n", + " predictors:\n", + " - componentSpecs:\n", + " - spec:\n", + " containers:\n", + " - name: classifier\n", + " volumeMounts:\n", + " - mountPath: /mnt/models\n", + " name: classifier-provision-location\n", + " readOnly: true\n", + "\n", + " initContainers:\n", + " - name: classifier-model-initializer\n", + " image: rclone/rclone:latest\n", + " imagePullPolicy: IfNotPresent\n", + "\n", + " args:\n", + " - \"copy\"\n", + " - \"cluster-minio:sklearn/iris\"\n", + " - \"/mnt/models\"\n", + "\n", + " volumeMounts:\n", + " - mountPath: /mnt/models\n", + " name: classifier-provision-location\n", + "\n", + " - name: config\n", + " mountPath: \"/config/rclone\"\n", + " readOnly: true\n", + "\n", + " volumes:\n", + " - name: classifier-provision-location\n", + " emptyDir: {}\n", + "\n", + " - name: config\n", + " secret:\n", + " secretName: mysecret\n", + "\n", + " graph:\n", + " implementation: SKLEARN_SERVER\n", + " modelUri: \"dummy value\"\n", + " name: classifier\n", + " name: default\n", + " replicas: 1" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "secret/mysecret created\n", + "seldondeployment.machinelearning.seldon.io/explicit-init-definition created\n" + ] + } + ], + "source": [ + "!kubectl apply -f explicit-init-definition.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Waiting for deployment \"explicit-init-definition-default-0-classifier\" rollout to finish: 0 of 1 updated replicas are available...\n", + "deployment \"explicit-init-definition-default-0-classifier\" successfully rolled out\n" + ] + } + ], + "source": [ + "!kubectl rollout status deploy/$(kubectl get deploy -l seldon-deployment-id=explicit-init-definition -o jsonpath='{.items[0].metadata.name}')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "%%bash\n", + "curl -s -X POST -H 'Content-Type: application/json' \\\n", + " -d '{\"data\":{\"ndarray\":[[5.964, 4.006, 2.081, 1.031]]}}' \\\n", + " http://localhost:8003/seldon/seldon/explicit-init-definition/api/v1.0/predictions | jq ." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Custom Init Container (as default container)\n", + "\n", + "It is also possible to prepare a custom init container image and set it as default one. \n", + "For this purpose we need to build a docker image which entrypoint will accept two arguments:\n", + "- source\n", + "- destination\n", + "\n", + "Because copying artifacts with `rclone` between two location is done with\n", + "```\n", + "rclone copy source destination\n", + "```\n", + "we prepare following Dockerfile" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting Dockerfile\n" + ] + } + ], + "source": [ + "%%writefile Dockerfile\n", + "FROM rclone/rclone:latest\n", + "ENTRYPOINT [\"rclone\", \"copy\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This image is build and published as `seldonio/rclone-init-container`.\n", + "\n", + "`rclone` tool can be configured using both `rclone.conf` config file (as above) and environmental variables.\n", + "Note the remote name `mys3` in the name of environmental variables defined in the following secret:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting seldon-reclone-secret.yaml\n" + ] + } + ], + "source": [ + "%%writefile seldon-reclone-secret.yaml\n", + "\n", + "apiVersion: v1\n", + "kind: Secret\n", + "metadata:\n", + " name: seldon-rclone-secret\n", + "type: Opaque\n", + "stringData:\n", + " RCLONE_CONFIG_MYS3_TYPE: s3\n", + " RCLONE_CONFIG_MYS3_PROVIDER: minio\n", + " RCLONE_CONFIG_MYS3_ENV_AUTH: \"false\"\n", + " RCLONE_CONFIG_MYS3_ACCESS_KEY_ID: minioadmin\n", + " RCLONE_CONFIG_MYS3_SECRET_ACCESS_KEY: minioadmin\n", + " RCLONE_CONFIG_MYS3_ENDPOINT: http://minio.minio-system.svc.cluster.local:9000" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "secret/seldon-rclone-secret configured\n" + ] + } + ], + "source": [ + "!kubectl apply -f seldon-reclone-secret.yaml" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**IMPORTANT** For the following example to work Seldon Core need to be installed with following helm values\n", + "```yaml\n", + "storageInitializer:\n", + " image: seldonio/rclone-init-container:latest\n", + "\n", + "predictiveUnit:\n", + " defaultEnvSecretRefName: seldon-rclone-secret\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With above defined we can easily define our sklear server using `modelUri: mys3:sklearn/iris`:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting rclone-default-init.yaml\n" + ] + } + ], + "source": [ + "%%writefile rclone-default-init.yaml\n", + "\n", + "apiVersion: machinelearning.seldon.io/v1\n", + "kind: SeldonDeployment\n", + "metadata:\n", + " name: rclone-as-default-init-container\n", + "spec:\n", + " name: iris\n", + " predictors:\n", + " - graph:\n", + " children: []\n", + " implementation: SKLEARN_SERVER\n", + " modelUri: mys3:sklearn/iris\n", + " name: classifier\n", + " name: default\n", + " replicas: 1" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "seldondeployment.machinelearning.seldon.io/rclone-as-default-init-container created\n" + ] + } + ], + "source": [ + "!kubectl apply -f rclone-default-init.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Waiting for deployment \"rclone-as-default-init-container-default-0-classifier\" rollout to finish: 0 of 1 updated replicas are available...\n", + "deployment \"rclone-as-default-init-container-default-0-classifier\" successfully rolled out\n" + ] + } + ], + "source": [ + "!kubectl rollout status deploy/$(kubectl get deploy -l seldon-deployment-id=rclone-as-default-init-container -o jsonpath='{.items[0].metadata.name}')" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "%%bash\n", + "curl -s -X POST -H 'Content-Type: application/json' \\\n", + " -d '{\"data\":{\"ndarray\":[[5.964, 4.006, 2.081, 1.031]]}}' \\\n", + " http://localhost:8003/seldon/seldon/rclone-as-default-init-container/api/v1.0/predictions | jq ." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Cleanup" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "secret \"mysecret\" deleted\n", + "seldondeployment.machinelearning.seldon.io \"explicit-init-definition\" deleted\n", + "seldondeployment.machinelearning.seldon.io \"rclone-as-default-init-container\" deleted\n" + ] + } + ], + "source": [ + "%%bash\n", + "kubectl delete -f explicit-init-definition.yaml\n", + "kubectl delete -f rclone-default-init.yaml" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/init_containers/explicit-init-definition.yaml b/examples/init_containers/explicit-init-definition.yaml new file mode 100644 index 0000000000..4ec0cf941c --- /dev/null +++ b/examples/init_containers/explicit-init-definition.yaml @@ -0,0 +1,66 @@ +apiVersion: v1 +kind: Secret +metadata: + name: mysecret +type: Opaque +stringData: + rclone.conf: | + [cluster-minio] + type = s3 + provider = minio + env_auth = false + access_key_id = minioadmin + secret_access_key = minioadmin + endpoint = http://minio.minio-system.svc.cluster.local:9000 + + +--- + +apiVersion: machinelearning.seldon.io/v1 +kind: SeldonDeployment +metadata: + name: explicit-init-definition +spec: + name: iris + predictors: + - componentSpecs: + - spec: + containers: + - name: classifier + volumeMounts: + - mountPath: /mnt/models + name: classifier-provision-location + readOnly: true + + initContainers: + - name: classifier-model-initializer + image: rclone/rclone:latest + imagePullPolicy: IfNotPresent + + args: + - "copy" + - "cluster-minio:sklearn/iris" + - "/mnt/models" + + volumeMounts: + - mountPath: /mnt/models + name: classifier-provision-location + + - name: config + mountPath: "/config/rclone" + readOnly: true + + volumes: + - name: classifier-provision-location + emptyDir: {} + + - name: config + secret: + secretName: mysecret + + graph: + implementation: SKLEARN_SERVER + modelUri: "dummy value" + name: classifier + name: default + replicas: 1 diff --git a/examples/init_containers/rclone-default-init.yaml b/examples/init_containers/rclone-default-init.yaml new file mode 100644 index 0000000000..172dcc2cf9 --- /dev/null +++ b/examples/init_containers/rclone-default-init.yaml @@ -0,0 +1,15 @@ + +apiVersion: machinelearning.seldon.io/v1 +kind: SeldonDeployment +metadata: + name: rclone-as-default-init-container +spec: + name: iris + predictors: + - graph: + children: [] + implementation: SKLEARN_SERVER + modelUri: mys3:sklearn/iris + name: classifier + name: default + replicas: 1 diff --git a/examples/init_containers/seldon-reclone-secret.yaml b/examples/init_containers/seldon-reclone-secret.yaml new file mode 100644 index 0000000000..386ad3a8ac --- /dev/null +++ b/examples/init_containers/seldon-reclone-secret.yaml @@ -0,0 +1,13 @@ + +apiVersion: v1 +kind: Secret +metadata: + name: seldon-rclone-secret +type: Opaque +stringData: + RCLONE_CONFIG_MYS3_TYPE: s3 + RCLONE_CONFIG_MYS3_PROVIDER: minio + RCLONE_CONFIG_MYS3_ENV_AUTH: "false" + RCLONE_CONFIG_MYS3_ACCESS_KEY_ID: minioadmin + RCLONE_CONFIG_MYS3_SECRET_ACCESS_KEY: minioadmin + RCLONE_CONFIG_MYS3_ENDPOINT: http://minio.minio-system.svc.cluster.local:9000