From b655845003e6f538f53f97f907ee48aad7bd453d Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Mon, 17 Jul 2023 16:54:37 -0400 Subject: [PATCH 01/13] abn updates Signed-off-by: Michael Kalantar --- docs/tutorials/abn/abn.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/abn/abn.md b/docs/tutorials/abn/abn.md index c251ee98..48802f18 100644 --- a/docs/tutorials/abn/abn.md +++ b/docs/tutorials/abn/abn.md @@ -102,12 +102,13 @@ In separate shells, port-forward requests to the frontend component and generate ``` ```shell curl -s https://raw.githubusercontent.com/iter8-tools/docs/v0.15.0/samples/abn-sample/generate_load.sh | sh -s -- + # source /Users/kalantar/projects/go.workspace/src/github.com/iter8-tools/docs/samples/abn-sample/generate_load.sh ``` ## Deploy a candidate version -Deploy the candidate version of the *backend* component, naming it `backend-candidate-1`. +Deploy a candidate version of the *backend* component, naming it *backend-candidate-1*. ```shell kubectl create deployment backend-candidate-1 --image=iter8/abn-sample-backend:0.13-v2 From d115d3eab076210631dc85b8b7e0e2fef7ed5325 Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Tue, 18 Jul 2023 16:26:50 -0400 Subject: [PATCH 02/13] reviwer comments, kustomize, python Signed-off-by: Michael Kalantar --- docs/tutorials/abn/abn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/abn/abn.md b/docs/tutorials/abn/abn.md index 48802f18..42062a4e 100644 --- a/docs/tutorials/abn/abn.md +++ b/docs/tutorials/abn/abn.md @@ -108,7 +108,7 @@ In separate shells, port-forward requests to the frontend component and generate ## Deploy a candidate version -Deploy a candidate version of the *backend* component, naming it *backend-candidate-1*. +Deploy the candidate version of the *backend* component, naming it `backend-candidate-1`. ```shell kubectl create deployment backend-candidate-1 --image=iter8/abn-sample-backend:0.13-v2 From be4a66301d788cc8dfc3c43d0cecfc02564bb869 Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Fri, 21 Jul 2023 11:33:21 -0400 Subject: [PATCH 03/13] bg and canary for kserve Signed-off-by: Michael Kalantar --- .../integrations/kserve-mm/blue-green.md | 6 +- .../integrations/kserve-mm/canary.md | 7 +- .../integrations/kserve/blue-green.md | 262 ++ .../integrations/kserve/canary-testing.md | 2 +- docs/tutorials/integrations/kserve/canary.md | 252 ++ .../integrations/kserve/images/blue-green.png | Bin 0 -> 77059 bytes .../integrations/kserve/images/canary.png | Bin 0 -> 66733 bytes .../kserve/images/src/blue-green.excalidraw | 2499 +++++++++++++++++ mkdocs.yml | 4 +- samples/kserve-serving/sleep.sh | 62 + 10 files changed, 3087 insertions(+), 7 deletions(-) create mode 100644 docs/tutorials/integrations/kserve/blue-green.md create mode 100644 docs/tutorials/integrations/kserve/canary.md create mode 100644 docs/tutorials/integrations/kserve/images/blue-green.png create mode 100644 docs/tutorials/integrations/kserve/images/canary.png create mode 100644 docs/tutorials/integrations/kserve/images/src/blue-green.excalidraw diff --git a/docs/tutorials/integrations/kserve-mm/blue-green.md b/docs/tutorials/integrations/kserve-mm/blue-green.md index aa563b1f..f92cc76e 100644 --- a/docs/tutorials/integrations/kserve-mm/blue-green.md +++ b/docs/tutorials/integrations/kserve-mm/blue-green.md @@ -123,7 +123,7 @@ To send inference requests to the model: localhost:8080 inference.GRPCInferenceService.ModelInfer ``` -Note that the model version responding to each inference request can be determined from the `modelName` field of the response. +Note that the model version responding to each inference request is noted in the response header `mm-vmodel-id`. In the requests above, we display only the response code and this header. ## Deploy a candidate model @@ -164,7 +164,7 @@ The deployment of the candidate model triggers an automatic reconfiguration by I kubectl get virtualservice wisdom -o yaml ``` -Send additional inference requests as described above. +Further, you can send additional inference requests as described above. They will be handled by both versions of the model. ## Modify weights (optional) @@ -219,6 +219,8 @@ EOF ### Delete the candidate `InferenceService` +Once the primary `InferenceService` has been redeployed, delete the candidate: + ```shell kubectl delete inferenceservice wisdom-1 ``` diff --git a/docs/tutorials/integrations/kserve-mm/canary.md b/docs/tutorials/integrations/kserve-mm/canary.md index 403ab10a..53f09b62 100644 --- a/docs/tutorials/integrations/kserve-mm/canary.md +++ b/docs/tutorials/integrations/kserve-mm/canary.md @@ -101,7 +101,6 @@ To send inference requests to the model: cd demo cat wisdom.sh . wisdom.sh - . wisdom-test.sh ``` or, to send a request with header `traffic: test`: ```shell @@ -137,7 +136,7 @@ To send inference requests to the model: localhost:8080 inference.GRPCInferenceService.ModelInfer ``` -Note that the model version responding to each inference request can be determined from the `modelName` field of the response. +Note that the model version responding to each inference request is noted in the response header `mm-vmodel-id`. In the requests above, we display only the response code and this header. ## Deploy a candidate model @@ -178,7 +177,7 @@ The deployment of the candidate model triggers an automatic reconfiguration by I kubectl get virtualservice wisdom -o yaml ``` -Send additional inference requests as described above. +Further, you can send additional inference requests as described above. They will be handled by both versions of the model. ## Promote the candidate model @@ -213,6 +212,8 @@ EOF ### Delete the candidate `InferenceService` +Once the primary `InferenceService` has been redeployed, delete the candidate: + ```shell kubectl delete inferenceservice wisdom-1 ``` diff --git a/docs/tutorials/integrations/kserve/blue-green.md b/docs/tutorials/integrations/kserve/blue-green.md new file mode 100644 index 00000000..d3ffed1e --- /dev/null +++ b/docs/tutorials/integrations/kserve/blue-green.md @@ -0,0 +1,262 @@ +--- +template: main.html +--- + +# Blue-Green Rollout of a KServe ML Model + +This tutorial shows how Iter8 can be used to implement a blue-green rollout of ML models hosted in a KServe environment. In a blue-green rollout, a percentage of inference requests are directed to a candidate version of the model. The remaining requests go to the primary, or initial, version of the model. Iter8 enables a blue-green rollout by automatically configuring routing resources to distribute inference requests. + +After a one time initialization step, the end user merely deploys candidate models, evaluates them, and either promotes or deletes them. Optionally, the end user can modify the percentage of inference requests being sent to the candidate model. Iter8 automatically handles all underlying network configuration. + +![Blue-Green rollout](images/blue-green.png) + +???+ "Before you begin" + 1. Ensure that you have the [kubectl CLI](https://kubernetes.io/docs/reference/kubectl/). + 2. Have access to a cluster running [KServe](https://kserve.github.io/website). You can create a [KServe Quickstart](https://kserve.github.io/website/0.10/get_started/#before-you-begin) environment as follows: + ```shell + curl -s "https://raw.githubusercontent.com/kserve/kserve/release-0.10/hack/quick_install.sh" | bash + ``` + + +## Install the Iter8 controller + +--8<-- "docs/tutorials/installiter8controller.md" + +## Deploy a primary model + +Deploy the primary version of a model using an `InferenceService`: + +```shell +cat < + +## Install the Iter8 controller + +--8<-- "docs/tutorials/installiter8controller.md" + +## Deploy a primary model + +Deploy the primary version of a model using an `InferenceService`: + +```shell +cat <uj%;5Un9ckXKVdm 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 literal 0 HcmV?d00001 diff --git a/docs/tutorials/integrations/kserve/images/canary.png b/docs/tutorials/integrations/kserve/images/canary.png new file mode 100644 index 0000000000000000000000000000000000000000..94d6e180eaab42ec9e8eefd007c22b0fff895fdd GIT binary patch literal 66733 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
VEnCbV5H4#G84K_Ua!TRkLth{2YK&YtcZJ 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 Date: Tue, 25 Jul 2023 16:38:07 -0400 Subject: [PATCH 04/13] wording changes Signed-off-by: Michael Kalantar --- .github/wordlist.txt | 6 +++++ docs/tutorials/abn/abn.md | 22 ++++++++----------- .../integrations/kserve/blue-green.md | 4 ++-- docs/tutorials/integrations/kserve/canary.md | 2 +- docs/user-guide/topics/ab_testing.md | 2 +- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/.github/wordlist.txt b/.github/wordlist.txt index a6627faf..96bd8226 100644 --- a/.github/wordlist.txt +++ b/.github/wordlist.txt @@ -168,3 +168,9 @@ gz xvf IMG mv +modelName +src +targetEnv +templateName +trafficStrategy +modelVersions \ No newline at end of file diff --git a/docs/tutorials/abn/abn.md b/docs/tutorials/abn/abn.md index 42062a4e..1b4af2fc 100644 --- a/docs/tutorials/abn/abn.md +++ b/docs/tutorials/abn/abn.md @@ -92,11 +92,11 @@ data: EOF ``` -In this definition, each version of the application is composed of a `Service` and a `Deployment`. In the primary version, both are named `backend`. In any candidate version they are named `backend-candidate-1`. Iter8 uses this definition to identify when any of the versions of the application are available. It can then respond appropriate to `Lookup()` requests. +In this definition, each version of the application is composed of a `Service` and a `Deployment`. In the primary version, both are named `backend`. In any candidate version they are named `backend-candidate-1`. Iter8 uses this definition to identify when any of the versions of the application are available. It can then respond appropriately to `Lookup()` requests. ## Generate load -In separate shells, port-forward requests to the frontend component and generate load for multiple users. A [script](https://raw.githubusercontent.com/iter8-tools/docs/main/samples/abn-sample/generate_load.sh) is provided to do this. To use it: +In separate shells, port-forward requests to the frontend component and generate load for multiple users. A [script](https://raw.githubusercontent.com/iter8-tools/docs/main/samples/abn-sample/generate_load.sh) is provided for the latter. ```shell kubectl port-forward service/frontend 8090:8090 ``` @@ -117,8 +117,8 @@ kubectl label deployment backend-candidate-1 iter8.tools/watch="true" kubectl expose deployment backend-candidate-1 --name=backend-candidate-1 --port=8091 ``` -Until the candidate version is ready; that is, until all expected resources are deployed and available, calls to `Lookup()` will return only the index 0; the existing version. -Once the candidate version is ready, `Lookup()` will return both indices (0 and 1) so that requests can be distributed across versions. +Until the candidate version is ready; that is, until all expected resources are deployed and available, calls to `Lookup()` will return only the version number `0`; the existing version. +Once the candidate version is ready, `Lookup()` will return both version numbers (`0` and `1`) so that requests can be distributed across versions. ## Compare versions using Grafana @@ -128,24 +128,20 @@ Inspect the metrics using Grafana. If Grafana is deployed to your cluster, port- kubectl port-forward service/grafana 3000:3000 ``` -Open Grafana in a browser: - -```shell -http://localhost:3000/ -``` +Open Grafana in a browser by going to http://localhost:3000/ [Add a JSON API data source](http://localhost:3000/connections/datasources/marcusolsson-json-datasource) `Iter8` with: -- URL `http://iter8.default:8080/metrics` and -- query string `application=default%2Fbackend` +- URL: `http://iter8.default:8080/metrics` +- Query string: `application=default%2Fbackend` -[Create a new dashboard](http://localhost:3000/dashboards) by *import*. Do so by pasting the contents of this [JSON definition](https://gist.githubusercontent.com/Alan-Cha/aa4ba259cc4631aafe9b43500502c60f/raw/034249f24e2c524ee4e326e860c06149ae7b2677/gistfile1.txt) into the box and *load* it. Associate it with the JSON API data source defined above. +[Create a new dashboard](http://localhost:3000/dashboards) by *import*. Copy and paste the contents of this [JSON definition](https://gist.githubusercontent.com/Alan-Cha/aa4ba259cc4631aafe9b43500502c60f/raw/034249f24e2c524ee4e326e860c06149ae7b2677/gistfile1.txt) into the text box and *load* it. Associate it with the JSON API data source above. The Iter8 dashboard allows you to compare the behavior of the two versions of the backend component against each other and select a winner. Since user requests are being sent by the load generation script, the values in the report may change over time. The Iter8 dashboard may look like the following: ![A/B dashboard](images/dashboard.png) -Once a winner is identified, the winner can be promoted, and the candidate version deleted. +Once you identify a winner, it can be promoted, and the candidate version deleted. ## Promote candidate version diff --git a/docs/tutorials/integrations/kserve/blue-green.md b/docs/tutorials/integrations/kserve/blue-green.md index d3ffed1e..2fcba181 100644 --- a/docs/tutorials/integrations/kserve/blue-green.md +++ b/docs/tutorials/integrations/kserve/blue-green.md @@ -6,7 +6,7 @@ template: main.html This tutorial shows how Iter8 can be used to implement a blue-green rollout of ML models hosted in a KServe environment. In a blue-green rollout, a percentage of inference requests are directed to a candidate version of the model. The remaining requests go to the primary, or initial, version of the model. Iter8 enables a blue-green rollout by automatically configuring routing resources to distribute inference requests. -After a one time initialization step, the end user merely deploys candidate models, evaluates them, and either promotes or deletes them. Optionally, the end user can modify the percentage of inference requests being sent to the candidate model. Iter8 automatically handles all underlying network configuration. +After a one-time initialization step, the end user merely deploys candidate models, evaluates them, and either promotes or deletes them. Optionally, the end user can modify the percentage of inference requests being sent to the candidate model. Iter8 automatically handles all underlying network configuration. ![Blue-Green rollout](images/blue-green.png) @@ -79,7 +79,7 @@ modelName: wisdom EOF ``` -The `initialize-rollout` template (with `trafficStrategy: blue-green`) configures the Istio service mesh to route all requests to the primary version of the model (`wisdom-0`). Further, it defines the routing policy that will be used by Iter8 when it observes changes in the models. By default, this routing policy splits inference requests 50-50 between the primary and candidate versions. For detailed configuration options, see the Helm chart. +The `initialize-rollout` template (with `trafficStrategy: blue-green`) configures the Istio service mesh to route all requests to the primary version of the model (`wisdom-0`). Further, it defines the routing policy that will be used by Iter8 when it observes changes in the models. By default, this routing policy splits inference requests 50-50 between the primary and candidate versions. For detailed configuration options, see the [Helm chart](https://github.com/kalantar/iter8/blob/v0.15/charts/traffic/values.yaml). ## Verify network configuration diff --git a/docs/tutorials/integrations/kserve/canary.md b/docs/tutorials/integrations/kserve/canary.md index 5a2924bd..e4e36a27 100644 --- a/docs/tutorials/integrations/kserve/canary.md +++ b/docs/tutorials/integrations/kserve/canary.md @@ -6,7 +6,7 @@ template: main.html This tutorial shows how Iter8 can be used to implement a canary rollout of ML models hosted in a KServe environment. In a canary rollout, inference requests that match a particular pattern, for example those that have a particular header, are directed to the candidate version of the model. The remaining requests go to the primary, or initial, version of the model. Iter8 enables a canary rollout by automatically configuring the network to distribute inference requests. -After a one time initialization step, the end user merely deploys candidate models, evaluates them, and either promotes or deletes them. Iter8 automatically handles the underlying network configuration. +After a one-time initialization step, the end user merely deploys candidate models, evaluates them, and either promotes or deletes them. Iter8 automatically handles the underlying network configuration. ![Canary rollout](images/canary.png) diff --git a/docs/user-guide/topics/ab_testing.md b/docs/user-guide/topics/ab_testing.md index 3df278d0..213cecf0 100644 --- a/docs/user-guide/topics/ab_testing.md +++ b/docs/user-guide/topics/ab_testing.md @@ -11,7 +11,7 @@ A/B/n testing relies on business metrics typically computed by a frontend, user- Metric values often depend on one or more interactions with backend (not user-facing) application components. To run an A/B/n test on a backend component, it is necessary to be able to associate a metric value (computed by the frontend component) to the version of the backend component that contributed to its computation. The challenge is that the frontend component often does not know which version of the backend component processed a given request. To address this challenge, Iter8 introduces an A/B/n SDK. -The Iter8 SDK uses a fixed set of versions numbers 0, 1, ... as a way to refer to the current set of versions of a Kubernetes application or ML model. The version of the application associated with a given version number changes over time as new versions are developed, deployed for testing, and either promoted or deleted. Since the set of version numbers is fixed, they can be used to configure routing to the application. +The Iter8 SDK uses a fixed set of versions numbers (`0`, `1`, etc.) as a way to refer to the current set of versions of a Kubernetes application or ML model. The version of the application associated with a given version number changes over time as new versions are developed, deployed for testing, and either promoted or deleted. Since the set of version numbers is fixed, they can be used to configure routing to the application. The Iter8 SDK provides two APIs to frontend application components: From 3f813b47c3f4220a71c8c3a48db76b6b5fcb5436 Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Thu, 3 Aug 2023 14:52:33 -0400 Subject: [PATCH 05/13] update kserve docs Signed-off-by: Michael Kalantar --- .../integrations/kserve/blue-green.md | 125 +++++++++--------- docs/tutorials/integrations/kserve/canary.md | 105 +++++++-------- samples/kserve-serving/sleep.sh | 29 +++- 3 files changed, 136 insertions(+), 123 deletions(-) diff --git a/docs/tutorials/integrations/kserve/blue-green.md b/docs/tutorials/integrations/kserve/blue-green.md index 2fcba181..025a4179 100644 --- a/docs/tutorials/integrations/kserve/blue-green.md +++ b/docs/tutorials/integrations/kserve/blue-green.md @@ -6,7 +6,7 @@ template: main.html This tutorial shows how Iter8 can be used to implement a blue-green rollout of ML models hosted in a KServe environment. In a blue-green rollout, a percentage of inference requests are directed to a candidate version of the model. The remaining requests go to the primary, or initial, version of the model. Iter8 enables a blue-green rollout by automatically configuring routing resources to distribute inference requests. -After a one-time initialization step, the end user merely deploys candidate models, evaluates them, and either promotes or deletes them. Optionally, the end user can modify the percentage of inference requests being sent to the candidate model. Iter8 automatically handles all underlying network configuration. +After a one-time initialization step, the end user merely deploys candidate models, evaluates them, and either promotes or deletes them. Optionally, the end user can modify the percentage of inference requests being sent to the candidate model. Iter8 automatically handles all underlying routing configuration. ![Blue-Green rollout](images/blue-green.png) @@ -16,20 +16,17 @@ After a one-time initialization step, the end user merely deploys candidate mode ```shell curl -s "https://raw.githubusercontent.com/kserve/kserve/release-0.10/hack/quick_install.sh" | bash ``` - + -## Install the Iter8 controller +## Install Iter8 --8<-- "docs/tutorials/installiter8controller.md" -## Deploy a primary model +## Initialize primary + +### Application -Deploy the primary version of a model using an `InferenceService`: +Deploy the primary version of the application. In this tutorial, the application is a KServe model. Initialize the resources for the primary version of the model (`v0`) by deploying an `InferenceService` as follows: ```shell cat < + -## Install the Iter8 controller +## Install Iter8 --8<-- "docs/tutorials/installiter8controller.md" -## Deploy a primary model +## Initialize primary + +### Application -Deploy the primary version of a model using an `InferenceService`: +Deploy the primary version of the application. In this tutorial, the application is a KServe model. Initialize the resources for the primary version of the model (`v0`) by deploying an `InferenceService` as follows: ```shell cat < $MANIFEST apiVersion: apps/v1 kind: Deployment metadata: @@ -13,7 +22,18 @@ spec: metadata: labels: app: sleep +EOF +if [ "${SERVICE_MESH}" = "istio" ]; then +cat <> $MANIFEST + sidecar.istio.io/inject: "true" +EOF +elif [ "${SERVICE_MESH}" = "servicemesh" ]; then +cat <> $MANIFEST + annotations: sidecar.istio.io/inject: "true" +EOF +fi +cat <> $MANIFEST spec: containers: - name: sleep @@ -54,9 +74,12 @@ data: } wisdom.sh: | curl -H 'Content-Type: application/json' http://wisdom.default -d @input.json -s -D - \ - | grep -e HTTP -e mm-vmodel-id + | grep -e HTTP -e app-version wisdom-test.sh: | curl -H 'Content-Type: application/json' http://wisdom.default -d @input.json -s -D - \ -H 'traffic: test' \ - | grep -e HTTP -e mm-vmodel-id + | grep -e HTTP -e app-version EOF + +kubectl apply -f $MANIFEST +rm -f $MANIFEST From 80f77d4a88d7a8400751da4b2a66e1a7814e8e22 Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Thu, 3 Aug 2023 17:04:11 -0400 Subject: [PATCH 06/13] update kserver-modelmesh use cases Signed-off-by: Michael Kalantar --- docs/tutorials/deleteiter8controller.md | 4 - docs/tutorials/installiter8controller.md | 4 - .../integrations/kserve-mm/blue-green.md | 120 ++--- .../integrations/kserve-mm/canary.md | 110 ++--- .../integrations/kserve/blue-green.md | 10 +- docs/tutorials/integrations/kserve/canary.md | 10 +- samples/modelmesh-serving/sleep.sh | 426 ++++++++++++++++++ 7 files changed, 559 insertions(+), 125 deletions(-) diff --git a/docs/tutorials/deleteiter8controller.md b/docs/tutorials/deleteiter8controller.md index ef94a7d4..527b53bb 100644 --- a/docs/tutorials/deleteiter8controller.md +++ b/docs/tutorials/deleteiter8controller.md @@ -1,13 +1,9 @@ === "Helm" - Delete the Iter8 controller using `helm` as follows. - ```shell helm delete iter8 ``` === "Kustomize" - Delete the Iter8 controller using `kustomize` as follows. - === "namespace scoped" ```shell kubectl delete -k 'https://github.com/iter8-tools/iter8.git/kustomize/iter8/namespaceScoped?ref=v0.15.3' diff --git a/docs/tutorials/installiter8controller.md b/docs/tutorials/installiter8controller.md index 5e1915af..158403b4 100644 --- a/docs/tutorials/installiter8controller.md +++ b/docs/tutorials/installiter8controller.md @@ -1,6 +1,4 @@ === "Helm" - Install the Iter8 controller using `helm` as follows. - === "namespace scoped" ```shell helm install --repo https://iter8-tools.github.io/iter8 iter8 traffic @@ -13,8 +11,6 @@ ``` === "Kustomize" - Install the Iter8 controller using `kustomize` as follows. - === "namespace scoped" ```shell kubectl apply -k 'https://github.com/iter8-tools/iter8.git/kustomize/iter8/namespaceScoped?ref=v0.15.3' diff --git a/docs/tutorials/integrations/kserve-mm/blue-green.md b/docs/tutorials/integrations/kserve-mm/blue-green.md index f92cc76e..c2dc8234 100644 --- a/docs/tutorials/integrations/kserve-mm/blue-green.md +++ b/docs/tutorials/integrations/kserve-mm/blue-green.md @@ -4,9 +4,9 @@ template: main.html # Blue-Green Rollout of a ML Model -This tutorial shows how Iter8 can be used to implement a blue-green rollout of ML models hosted in a KServe modelmesh serving environment. In a blue-green rollout, a percentage of inference requests are directed to a candidate version of the model. The remaining requests go to the primary, or initial, version of the model. Iter8 enables a blue-green rollout by automatically configuring the network to distribute inference requests. +This tutorial shows how Iter8 can be used to implement a blue-green rollout of ML models hosted in a KServe modelmesh serving environment. In a blue-green rollout, a percentage of inference requests are directed to a candidate version of the model. The remaining requests go to the primary, or initial, version of the model. Iter8 enables a blue-green rollout by automatically configuring routing resources to distribute inference requests. -After a one time initialization step, the end user merely deploys candidate models, evaluates them, and either promotes or deletes them. Optionally, the end user can modify the percentage of inference requests being sent to the candidate model. Iter8 automatically handles all underlying network configuration. +After a one time initialization step, the end user merely deploys candidate models, evaluates them, and either promotes or deletes them. Optionally, the end user can modify the percentage of inference requests being sent to the candidate model. Iter8 automatically handles all underlying routing configuration. ![Blue-Green rollout](images/blue-green.png) @@ -14,16 +14,21 @@ In this tutorial, we use the Istio service mesh to distribute inference requests ???+ "Before you begin" 1. Ensure that you have the [kubectl CLI](https://kubernetes.io/docs/reference/kubectl/). - 2. Have access to a cluster running [KServe ModelMesh Serving](https://github.com/kserve/modelmesh-serving). For example, you can create a modelmesh-serving [Quickstart](https://github.com/kserve/modelmesh-serving/blob/main/docs/quickstart.md) environment. + 2. Have access to a cluster running [KServe ModelMesh Serving](https://github.com/kserve/modelmesh-serving). For example, you can create a modelmesh-serving [Quickstart](https://github.com/kserve/modelmesh-serving/blob/release-0.11/docs/quickstart.md) environment. If using the Quickstart environment, change your default namespece to `modelmesh-serving`: + ```shell + kubectl config set-context --current --namespace=modelmesh-serving + ``` 3. Install [Istio](https://istio.io). You can install the [demo profile](https://istio.io/latest/docs/setup/getting-started/). -## Install the Iter8 controller +## Install Iter8 --8<-- "docs/tutorials/installiter8controller.md" -## Deploy a primary model +## Initialize primary + +### Application -Deploy the primary version of a model using an `InferenceService`: +Deploy the primary version of the application. In this tutorial, the application is an ML model. Initialize the resources for the primary version of the model (`v0`) by deploying an `InferenceService` as follows: ```shell cat < $MANIFEST +apiVersion: apps/v1 +kind: Deployment +metadata: + name: sleep +spec: + replicas: 1 + selector: + matchLabels: + app: sleep + template: + metadata: + labels: + app: sleep +EOF +if [ "${SERVICE_MESH}" = "istio" ]; then +cat <> $MANIFEST + sidecar.istio.io/inject: "true" +EOF +elif [ "${SERVICE_MESH}" = "servicemesh" ]; then +cat <> $MANIFEST + annotations: + sidecar.istio.io/inject: "true" +EOF +fi +cat <> $MANIFEST + spec: + containers: + - name: sleep + image: fullstorydev/grpcurl:latest-alpine + command: ["/bin/sh", "-c", "sleep 3650d"] + workingDir: /demo + imagePullPolicy: IfNotPresent + volumeMounts: + - name: config-volume + mountPath: /demo + securityContext: + runAsNonRoot: true + runAsUser: 1001040000 + allowPrivilegeEscalation: false + volumes: + - name: config-volume + configMap: + name: demo-input +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: demo-input +data: + kserve.proto: | + syntax = "proto3"; + package inference; + option go_package = "github.com/kserve/modelmesh-serving/fvt/generated;inference"; + + // Inference Server GRPC endpoints. + service GRPCInferenceService + { + // The ServerLive API indicates if the inference server is able to receive + // and respond to metadata and inference requests. + rpc ServerLive(ServerLiveRequest) returns (ServerLiveResponse) {} + + // The ServerReady API indicates if the server is ready for inferencing. + rpc ServerReady(ServerReadyRequest) returns (ServerReadyResponse) {} + + // The ModelReady API indicates if a specific model is ready for inferencing. + rpc ModelReady(ModelReadyRequest) returns (ModelReadyResponse) {} + + // The ServerMetadata API provides information about the server. Errors are + // indicated by the google.rpc.Status returned for the request. The OK code + // indicates success and other codes indicate failure. + rpc ServerMetadata(ServerMetadataRequest) returns (ServerMetadataResponse) {} + + // The per-model metadata API provides information about a model. Errors are + // indicated by the google.rpc.Status returned for the request. The OK code + // indicates success and other codes indicate failure. + rpc ModelMetadata(ModelMetadataRequest) returns (ModelMetadataResponse) {} + + // The ModelInfer API performs inference using the specified model. Errors are + // indicated by the google.rpc.Status returned for the request. The OK code + // indicates success and other codes indicate failure. + rpc ModelInfer(ModelInferRequest) returns (ModelInferResponse) {} + } + + message ServerLiveRequest {} + + message ServerLiveResponse + { + // True if the inference server is live, false if not live. + bool live = 1; + } + + message ServerReadyRequest {} + + message ServerReadyResponse + { + // True if the inference server is ready, false if not ready. + bool ready = 1; + } + + message ModelReadyRequest + { + // The name of the model to check for readiness. + string name = 1; + + // The version of the model to check for readiness. If not given the + // server will choose a version based on the model and internal policy. + string version = 2; + } + + message ModelReadyResponse + { + // True if the model is ready, false if not ready. + bool ready = 1; + } + + message ServerMetadataRequest {} + + message ServerMetadataResponse + { + // The server name. + string name = 1; + + // The server version. + string version = 2; + + // The extensions supported by the server. + repeated string extensions = 3; + } + + message ModelMetadataRequest + { + // The name of the model. + string name = 1; + + // The version of the model to check for readiness. If not given the + // server will choose a version based on the model and internal policy. + string version = 2; + } + + message ModelMetadataResponse + { + // Metadata for a tensor. + message TensorMetadata + { + // The tensor name. + string name = 1; + + // The tensor data type. + string datatype = 2; + + // The tensor shape. A variable-size dimension is represented + // by a -1 value. + repeated int64 shape = 3; + } + + // The model name. + string name = 1; + + // The versions of the model available on the server. + repeated string versions = 2; + + // The model's platform. See Platforms. + string platform = 3; + + // The model's inputs. + repeated TensorMetadata inputs = 4; + + // The model's outputs. + repeated TensorMetadata outputs = 5; + } + + message ModelInferRequest + { + // An input tensor for an inference request. + message InferInputTensor + { + // The tensor name. + string name = 1; + + // The tensor data type. + string datatype = 2; + + // The tensor shape. + repeated int64 shape = 3; + + // Optional inference input tensor parameters. + map parameters = 4; + + // The tensor contents using a data-type format. This field must + // not be specified if "raw" tensor contents are being used for + // the inference request. + InferTensorContents contents = 5; + } + + // An output tensor requested for an inference request. + message InferRequestedOutputTensor + { + // The tensor name. + string name = 1; + + // Optional requested output tensor parameters. + map parameters = 2; + } + + // The name of the model to use for inferencing. + string model_name = 1; + + // The version of the model to use for inference. If not given the + // server will choose a version based on the model and internal policy. + string model_version = 2; + + // Optional identifier for the request. If specified will be + // returned in the response. + string id = 3; + + // Optional inference parameters. + map parameters = 4; + + // The input tensors for the inference. + repeated InferInputTensor inputs = 5; + + // The requested output tensors for the inference. Optional, if not + // specified all outputs produced by the model will be returned. + repeated InferRequestedOutputTensor outputs = 6; + + // The data contained in an input tensor can be represented in "raw" + // bytes form or in the repeated type that matches the tensor's data + // type. To use the raw representation 'raw_input_contents' must be + // initialized with data for each tensor in the same order as + // 'inputs'. For each tensor, the size of this content must match + // what is expected by the tensor's shape and data type. The raw + // data must be the flattened, one-dimensional, row-major order of + // the tensor elements without any stride or padding between the + // elements. Note that the FP16 data type must be represented as raw + // content as there is no specific data type for a 16-bit float + // type. + // + // If this field is specified then InferInputTensor::contents must + // not be specified for any input tensor. + repeated bytes raw_input_contents = 7; + } + + message ModelInferResponse + { + // An output tensor returned for an inference request. + message InferOutputTensor + { + // The tensor name. + string name = 1; + + // The tensor data type. + string datatype = 2; + + // The tensor shape. + repeated int64 shape = 3; + + // Optional output tensor parameters. + map parameters = 4; + + // The tensor contents using a data-type format. This field must + // not be specified if "raw" tensor contents are being used for + // the inference response. + InferTensorContents contents = 5; + } + + // The name of the model used for inference. + string model_name = 1; + + // The version of the model used for inference. + string model_version = 2; + + // The id of the inference request if one was specified. + string id = 3; + + // Optional inference response parameters. + map parameters = 4; + + // The output tensors holding inference results. + repeated InferOutputTensor outputs = 5; + + // The data contained in an output tensor can be represented in + // "raw" bytes form or in the repeated type that matches the + // tensor's data type. To use the raw representation 'raw_output_contents' + // must be initialized with data for each tensor in the same order as + // 'outputs'. For each tensor, the size of this content must match + // what is expected by the tensor's shape and data type. The raw + // data must be the flattened, one-dimensional, row-major order of + // the tensor elements without any stride or padding between the + // elements. Note that the FP16 data type must be represented as raw + // content as there is no specific data type for a 16-bit float + // type. + // + // If this field is specified then InferOutputTensor::contents must + // not be specified for any output tensor. + repeated bytes raw_output_contents = 6; + } + + // An inference parameter value. The Parameters message describes a + // “name”/”value” pair, where the “name” is the name of the parameter + // and the “value” is a boolean, integer, or string corresponding to + // the parameter. + message InferParameter + { + // The parameter value can be a string, an int64, a boolean + // or a message specific to a predefined parameter. + oneof parameter_choice + { + // A boolean parameter value. + bool bool_param = 1; + + // An int64 parameter value. + int64 int64_param = 2; + + // A string parameter value. + string string_param = 3; + } + } + + // The data contained in a tensor represented by the repeated type + // that matches the tensor's data type. Protobuf oneof is not used + // because oneofs cannot contain repeated fields. + message InferTensorContents + { + // Representation for BOOL data type. The size must match what is + // expected by the tensor's shape. The contents must be the flattened, + // one-dimensional, row-major order of the tensor elements. + repeated bool bool_contents = 1; + + // Representation for INT8, INT16, and INT32 data types. The size + // must match what is expected by the tensor's shape. The contents + // must be the flattened, one-dimensional, row-major order of the + // tensor elements. + repeated int32 int_contents = 2; + + // Representation for INT64 data types. The size must match what + // is expected by the tensor's shape. The contents must be the + // flattened, one-dimensional, row-major order of the tensor elements. + repeated int64 int64_contents = 3; + + // Representation for UINT8, UINT16, and UINT32 data types. The size + // must match what is expected by the tensor's shape. The contents + // must be the flattened, one-dimensional, row-major order of the + // tensor elements. + repeated uint32 uint_contents = 4; + + // Representation for UINT64 data types. The size must match what + // is expected by the tensor's shape. The contents must be the + // flattened, one-dimensional, row-major order of the tensor elements. + repeated uint64 uint64_contents = 5; + + // Representation for FP32 data type. The size must match what is + // expected by the tensor's shape. The contents must be the flattened, + // one-dimensional, row-major order of the tensor elements. + repeated float fp32_contents = 6; + + // Representation for FP64 data type. The size must match what is + // expected by the tensor's shape. The contents must be the flattened, + // one-dimensional, row-major order of the tensor elements. + repeated double fp64_contents = 7; + + // Representation for BYTES data type. The size must match what is + // expected by the tensor's shape. The contents must be the flattened, + // one-dimensional, row-major order of the tensor elements. + repeated bytes bytes_contents = 8; + } + grpc_input.json: | + { + "inputs": [ + { + "name": "predict", + "shape": [1, 64], + "datatype": "FP32", + "contents": { + "fp32_contents": [0.0, 0.0, 1.0, 11.0, 14.0, 15.0, 3.0, 0.0, 0.0, 1.0, 13.0, 16.0, 12.0, 16.0, 8.0, 0.0, 0.0, 8.0, 16.0, 4.0, 6.0, 16.0, 5.0, 0.0, 0.0, 5.0, 15.0, 11.0, 13.0, 14.0, 0.0, 0.0, 0.0, 0.0, 2.0, 12.0, 16.0, 13.0, 0.0, 0.0, 0.0, 0.0, 0.0, 13.0, 16.0, 16.0, 6.0, 0.0, 0.0, 0.0, 0.0, 16.0, 16.0, 16.0, 7.0, 0.0, 0.0, 0.0, 0.0, 11.0, 13.0, 12.0, 1.0, 0.0] + } + } + ] + } + wisdom.sh: | + cat grpc_input.json | \ + grpcurl -vv -plaintext -proto kserve.proto -d @ \ + -authority wisdom.modelmesh-serving \ + modelmesh-serving.modelmesh-serving:8033 \ + inference.GRPCInferenceService.ModelInfer \ + | grep -e app-version + wisdom-test.sh: | + cat grpc_input.json | \ + grpcurl -vv -plaintext -proto kserve.proto -d @ \ + -authority wisdom.modelmesh-serving \ + -H 'traffic: test' \ + modelmesh-serving.modelmesh-serving:8033 \ + inference.GRPCInferenceService.ModelInfer \ + | grep -e app-version + lightspeed.sh: | + cat grpc_input.json | \ + grpcurl -vv -plaintext -proto kserve.proto -d @ \ + -authority lightspeed.modelmesh-serving \ + modelmesh-serving.modelmesh-serving:8033 \ + inference.GRPCInferenceService.ModelInfer \ + | grep -e app-version + lightspeed-test.sh: | + cat grpc_input.json | \ + grpcurl -vv -plaintext -proto kserve.proto -d @ \ + -authority lightspeed.modelmesh-serving \ + -H 'traffic: test' \ + modelmesh-serving.modelmesh-serving:8033 \ + inference.GRPCInferenceService.ModelInfer \ + | grep -e app-version +EOF + +kubectl apply -f $MANIFEST +rm -f $MANIFEST +>>>>>>> 0d2649e (update kserver-modelmesh use cases) From 7a2390895b56a85f26e8f9b0df46332ad5977c25 Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Thu, 3 Aug 2023 17:09:01 -0400 Subject: [PATCH 07/13] fix spelling Signed-off-by: Michael Kalantar --- .github/wordlist.txt | 8 +++----- docs/tutorials/integrations/kserve-mm/blue-green.md | 4 ++-- docs/tutorials/integrations/kserve-mm/canary.md | 4 ++-- docs/tutorials/integrations/kserve/blue-green.md | 4 ++-- docs/tutorials/integrations/kserve/canary.md | 2 +- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/.github/wordlist.txt b/.github/wordlist.txt index 96bd8226..0e0123d7 100644 --- a/.github/wordlist.txt +++ b/.github/wordlist.txt @@ -168,9 +168,7 @@ gz xvf IMG mv -modelName +appName src -targetEnv -templateName -trafficStrategy -modelVersions \ No newline at end of file +appType +appVersion diff --git a/docs/tutorials/integrations/kserve-mm/blue-green.md b/docs/tutorials/integrations/kserve-mm/blue-green.md index c2dc8234..a77226b9 100644 --- a/docs/tutorials/integrations/kserve-mm/blue-green.md +++ b/docs/tutorials/integrations/kserve-mm/blue-green.md @@ -14,7 +14,7 @@ In this tutorial, we use the Istio service mesh to distribute inference requests ???+ "Before you begin" 1. Ensure that you have the [kubectl CLI](https://kubernetes.io/docs/reference/kubectl/). - 2. Have access to a cluster running [KServe ModelMesh Serving](https://github.com/kserve/modelmesh-serving). For example, you can create a modelmesh-serving [Quickstart](https://github.com/kserve/modelmesh-serving/blob/release-0.11/docs/quickstart.md) environment. If using the Quickstart environment, change your default namespece to `modelmesh-serving`: + 2. Have access to a cluster running [KServe ModelMesh Serving](https://github.com/kserve/modelmesh-serving). For example, you can create a modelmesh-serving [Quickstart](https://github.com/kserve/modelmesh-serving/blob/release-0.11/docs/quickstart.md) environment. If using the Quickstart environment, change your default namespace to `modelmesh-serving`: ```shell kubectl config set-context --current --namespace=modelmesh-serving ``` @@ -79,7 +79,7 @@ strategy: blue-green EOF ``` -The `initialize` action (with strategy `blue-green`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It futher defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy splits requests 50-50 between the primary and candidate versions. For detailed configuration options, see the [Helm chart](https://github.com/kalantar/iter8/blob/v0.15/charts/routing-actions/values.yaml). +The `initialize` action (with strategy `blue-green`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It further defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy splits requests 50-50 between the primary and candidate versions. For detailed configuration options, see the [Helm chart](https://github.com/kalantar/iter8/blob/v0.15/charts/routing-actions/values.yaml). ## Verify routing diff --git a/docs/tutorials/integrations/kserve-mm/canary.md b/docs/tutorials/integrations/kserve-mm/canary.md index fdf00f3a..8e939159 100644 --- a/docs/tutorials/integrations/kserve-mm/canary.md +++ b/docs/tutorials/integrations/kserve-mm/canary.md @@ -14,7 +14,7 @@ In this tutorial, we use the Istio service mesh to distribute inference requests ???+ "Before you begin" 1. Ensure that you have the [kubectl CLI](https://kubernetes.io/docs/reference/kubectl/). - 2. Have access to a cluster running [KServe ModelMesh Serving](https://github.com/kserve/modelmesh-serving). For example, you can create a modelmesh-serving [Quickstart](https://github.com/kserve/modelmesh-serving/blob/release-0.11/docs/quickstart.md) environment. If using the Quickstart environment, change your default namespece to `modelmesh-serving`: + 2. Have access to a cluster running [KServe ModelMesh Serving](https://github.com/kserve/modelmesh-serving). For example, you can create a modelmesh-serving [Quickstart](https://github.com/kserve/modelmesh-serving/blob/release-0.11/docs/quickstart.md) environment. If using the Quickstart environment, change your default namespace to `modelmesh-serving`: ```shell kubectl config set-context --current --namespace=modelmesh-serving ``` @@ -79,7 +79,7 @@ strategy: canary EOF ``` -The `initialize` action (with strategy `canary`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It futher defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy sends requests with the header `traffic` set to the value `test` to the candidate version and all remaining requests to the primary version. For detailed configuration options, see the [Helm chart](https://github.com/kalantar/iter8/blob/v0.15/charts/routing-actions/values.yaml). +The `initialize` action (with strategy `canary`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It further defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy sends requests with the header `traffic` set to the value `test` to the candidate version and all remaining requests to the primary version. For detailed configuration options, see the [Helm chart](https://github.com/kalantar/iter8/blob/v0.15/charts/routing-actions/values.yaml). ## Verify routing diff --git a/docs/tutorials/integrations/kserve/blue-green.md b/docs/tutorials/integrations/kserve/blue-green.md index 6f6a207b..8c53673d 100644 --- a/docs/tutorials/integrations/kserve/blue-green.md +++ b/docs/tutorials/integrations/kserve/blue-green.md @@ -76,7 +76,7 @@ strategy: blue-green EOF ``` -The `initialize` action (with strategy `blue-green`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It futher defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy splits requests 50-50 between the primary and candidate versions. For detailed configuration options, see the [Helm chart](https://github.com/kalantar/iter8/blob/v0.15/charts/routing-actions/values.yaml). +The `initialize` action (with strategy `blue-green`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It further defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy splits requests 50-50 between the primary and candidate versions. For detailed configuration options, see the [Helm chart](https://github.com/kalantar/iter8/blob/v0.15/charts/routing-actions/values.yaml). ## Verify routing @@ -228,7 +228,7 @@ Inspect the `VirtualService` to see that the it has been automatically reconfigu ## Cleanup -If not alredy deleted, delete the candidate: +If not already deleted, delete the candidate: ```shell kubectl delete isvc/wisdom-1 diff --git a/docs/tutorials/integrations/kserve/canary.md b/docs/tutorials/integrations/kserve/canary.md index 0cefeb65..e39953fb 100644 --- a/docs/tutorials/integrations/kserve/canary.md +++ b/docs/tutorials/integrations/kserve/canary.md @@ -76,7 +76,7 @@ strategy: canary EOF ``` -The `initialize` action (with strategy `canary`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It futher defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy sends requests with the header `traffic` set to the value `test` to the candidate version and all remaining requests to the primary version. For detailed configuration options, see the [Helm chart](https://github.com/kalantar/iter8/blob/v0.15/charts/routing-actions/values.yaml). +The `initialize` action (with strategy `canary`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It further defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy sends requests with the header `traffic` set to the value `test` to the candidate version and all remaining requests to the primary version. For detailed configuration options, see the [Helm chart](https://github.com/kalantar/iter8/blob/v0.15/charts/routing-actions/values.yaml). ## Verify routing From 42f5b3a363846ddb16d88dcb670efd0666f8f287 Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Thu, 3 Aug 2023 17:11:25 -0400 Subject: [PATCH 08/13] fix spelling Signed-off-by: Michael Kalantar --- .github/wordlist.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/wordlist.txt b/.github/wordlist.txt index 0e0123d7..db0f7393 100644 --- a/.github/wordlist.txt +++ b/.github/wordlist.txt @@ -171,4 +171,4 @@ mv appName src appType -appVersion +appVersions From 769e43f04af99f096dc0ede40fcc9f5b12054cf9 Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Fri, 4 Aug 2023 10:21:05 -0400 Subject: [PATCH 09/13] use chart repo Signed-off-by: Michael Kalantar --- docs/tutorials/integrations/kserve-mm/blue-green.md | 9 +++------ docs/tutorials/integrations/kserve-mm/canary.md | 6 ++---- docs/tutorials/integrations/kserve/blue-green.md | 9 +++------ docs/tutorials/integrations/kserve/canary.md | 6 ++---- 4 files changed, 10 insertions(+), 20 deletions(-) diff --git a/docs/tutorials/integrations/kserve-mm/blue-green.md b/docs/tutorials/integrations/kserve-mm/blue-green.md index a77226b9..b8fa9072 100644 --- a/docs/tutorials/integrations/kserve-mm/blue-green.md +++ b/docs/tutorials/integrations/kserve-mm/blue-green.md @@ -70,8 +70,7 @@ kubectl get inferenceservice wisdom-0 Initialize model rollout with a blue-green traffic pattern as follows: ```shell -#cat < Date: Fri, 4 Aug 2023 10:33:58 -0400 Subject: [PATCH 10/13] fix links to values file Signed-off-by: Michael Kalantar --- docs/tutorials/integrations/kserve-mm/blue-green.md | 2 +- docs/tutorials/integrations/kserve-mm/canary.md | 2 +- docs/tutorials/integrations/kserve/blue-green.md | 2 +- docs/tutorials/integrations/kserve/canary.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/integrations/kserve-mm/blue-green.md b/docs/tutorials/integrations/kserve-mm/blue-green.md index b8fa9072..f27c3adb 100644 --- a/docs/tutorials/integrations/kserve-mm/blue-green.md +++ b/docs/tutorials/integrations/kserve-mm/blue-green.md @@ -78,7 +78,7 @@ strategy: blue-green EOF ``` -The `initialize` action (with strategy `blue-green`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It further defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy splits requests 50-50 between the primary and candidate versions. For detailed configuration options, see the [Helm chart](https://github.com/kalantar/iter8/blob/v0.15/charts/routing-actions/values.yaml). +The `initialize` action (with strategy `blue-green`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It further defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy splits requests 50-50 between the primary and candidate versions. For detailed configuration options, see the [Helm chart](https://github.com/iter8-tools/iter8/blob/v0.15.5/charts/routing-actions/values.yaml). ## Verify routing diff --git a/docs/tutorials/integrations/kserve-mm/canary.md b/docs/tutorials/integrations/kserve-mm/canary.md index 84ae79c6..b7b28930 100644 --- a/docs/tutorials/integrations/kserve-mm/canary.md +++ b/docs/tutorials/integrations/kserve-mm/canary.md @@ -78,7 +78,7 @@ strategy: canary EOF ``` -The `initialize` action (with strategy `canary`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It further defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy sends requests with the header `traffic` set to the value `test` to the candidate version and all remaining requests to the primary version. For detailed configuration options, see the [Helm chart](https://github.com/kalantar/iter8/blob/v0.15/charts/routing-actions/values.yaml). +The `initialize` action (with strategy `canary`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It further defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy sends requests with the header `traffic` set to the value `test` to the candidate version and all remaining requests to the primary version. For detailed configuration options, see the [Helm chart](https://github.com/iter8-tools/iter8/blob/v0.15.5/charts/routing-actions/values.yaml). ## Verify routing diff --git a/docs/tutorials/integrations/kserve/blue-green.md b/docs/tutorials/integrations/kserve/blue-green.md index 53b68c66..55b21dd2 100644 --- a/docs/tutorials/integrations/kserve/blue-green.md +++ b/docs/tutorials/integrations/kserve/blue-green.md @@ -75,7 +75,7 @@ strategy: blue-green EOF ``` -The `initialize` action (with strategy `blue-green`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It further defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy splits requests 50-50 between the primary and candidate versions. For detailed configuration options, see the [Helm chart](https://github.com/kalantar/iter8/blob/v0.15/charts/routing-actions/values.yaml). +The `initialize` action (with strategy `blue-green`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It further defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy splits requests 50-50 between the primary and candidate versions. For detailed configuration options, see the [Helm chart](https://github.com/iter8-tools/iter8/blob/v0.15.5/charts/routing-actions/values.yaml). ## Verify routing diff --git a/docs/tutorials/integrations/kserve/canary.md b/docs/tutorials/integrations/kserve/canary.md index 897c289a..86baf6cc 100644 --- a/docs/tutorials/integrations/kserve/canary.md +++ b/docs/tutorials/integrations/kserve/canary.md @@ -75,7 +75,7 @@ strategy: canary EOF ``` -The `initialize` action (with strategy `canary`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It further defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy sends requests with the header `traffic` set to the value `test` to the candidate version and all remaining requests to the primary version. For detailed configuration options, see the [Helm chart](https://github.com/kalantar/iter8/blob/v0.15/charts/routing-actions/values.yaml). +The `initialize` action (with strategy `canary`) configures the (Istio) service mesh to route all requests to the primary version of the application (`wisdom-0`). It further defines the routing policy that will be used when changes are observed in the application resources. By default, this routing policy sends requests with the header `traffic` set to the value `test` to the candidate version and all remaining requests to the primary version. For detailed configuration options, see the [Helm chart](https://github.com/iter8-tools/iter8/blob/v0.15.5/charts/routing-actions/values.yaml). ## Verify routing From b5da3db035138bbfd784d43247d5734cf2227be4 Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Fri, 4 Aug 2023 11:49:45 -0400 Subject: [PATCH 11/13] change version in install commands Signed-off-by: Michael Kalantar --- docs/getting-started/install.md | 2 +- docs/getting-started/installghaction.md | 7 ------- docs/getting-started/installgoinstall.md | 5 ----- docs/tutorials/integrations/ghactions.md | 4 ++-- 4 files changed, 3 insertions(+), 15 deletions(-) delete mode 100644 docs/getting-started/installghaction.md delete mode 100644 docs/getting-started/installgoinstall.md diff --git a/docs/getting-started/install.md b/docs/getting-started/install.md index 1d4fed2a..44e096e0 100644 --- a/docs/getting-started/install.md +++ b/docs/getting-started/install.md @@ -1,5 +1,5 @@ Install the latest stable release of the Iter8 CLI as follows. ```shell -go install github.com/iter8-tools/iter8@v0.14 +go install github.com/iter8-tools/iter8@v0.15 ``` \ No newline at end of file diff --git a/docs/getting-started/installghaction.md b/docs/getting-started/installghaction.md deleted file mode 100644 index 0415da4c..00000000 --- a/docs/getting-started/installghaction.md +++ /dev/null @@ -1,7 +0,0 @@ -=== "GitHub Actions" - Install the latest stable release of the Iter8 CLI in your GitHub Actions workflow as follows. - - ```yaml - - name: Install Iter8 - run: GOBIN=/usr/local/bin go install github.com/iter8-tools/iter8@v0.14 - ``` diff --git a/docs/getting-started/installgoinstall.md b/docs/getting-started/installgoinstall.md deleted file mode 100644 index 2fcaca69..00000000 --- a/docs/getting-started/installgoinstall.md +++ /dev/null @@ -1,5 +0,0 @@ -Install the latest stable release of the Iter8 CLI as follows. - -```yaml -GOBIN=/usr/local/bin go install github.com/iter8-tools/iter8@v0.14 -``` \ No newline at end of file diff --git a/docs/tutorials/integrations/ghactions.md b/docs/tutorials/integrations/ghactions.md index 3ffcaa32..a88e333a 100644 --- a/docs/tutorials/integrations/ghactions.md +++ b/docs/tutorials/integrations/ghactions.md @@ -8,11 +8,11 @@ There are two ways that you can use Iter8 with GitHub Actions. You can [run Iter # Use Iter8 in a GitHub Actions workflow -Install the latest version of the Iter8 CLI using `iter8-tools/iter8@v0.14`. Once installed, the Iter8 CLI can be used as documented in various tutorials. For example: +Install the latest version of the Iter8 CLI using `iter8-tools/iter8@v0.15`. Once installed, the Iter8 CLI can be used as documented in various tutorials. For example: ```yaml linenums="1" - name: Install Iter8 - run: GOBIN=/usr/local/bin go install github.com/iter8-tools/iter8@v0.14 + run: GOBIN=/usr/local/bin go install github.com/iter8-tools/iter8@v0.15 # Launch an experiment inside Kubernetes # This assumes that your Kubernetes cluster is accessible from the GitHub Actions pipeline From ab7db2f7c9adf14ad8f75b3b418b96716c50703c Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Mon, 7 Aug 2023 14:33:59 -0400 Subject: [PATCH 12/13] update links Signed-off-by: Michael Kalantar --- docs/tutorials/integrations/kserve-mm/blue-green.md | 7 +++---- docs/tutorials/integrations/kserve-mm/canary.md | 7 +++---- docs/tutorials/integrations/kserve/blue-green.md | 5 ++--- docs/tutorials/integrations/kserve/canary.md | 5 ++--- samples/modelmesh-serving/sleep.sh | 3 --- 5 files changed, 10 insertions(+), 17 deletions(-) diff --git a/docs/tutorials/integrations/kserve-mm/blue-green.md b/docs/tutorials/integrations/kserve-mm/blue-green.md index f27c3adb..b284e61c 100644 --- a/docs/tutorials/integrations/kserve-mm/blue-green.md +++ b/docs/tutorials/integrations/kserve-mm/blue-green.md @@ -93,8 +93,7 @@ To send inference requests to the model: === "From within the cluster" 1. Create a "sleep" pod in the cluster from which requests can be made: ```shell - # curl -s https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/modelmesh-serving/sleep.sh | sh - - source /Users/kalantar/projects/go.workspace/src/github.com/iter8-tools/docs/samples/modelmesh-serving/sleep.sh + curl -s https://raw.githubusercontent.com/iter8-tools/docs/v0.15.2/samples/modelmesh-serving/sleep.sh | sh - ``` 2. exec into the sleep pod: @@ -117,8 +116,8 @@ To send inference requests to the model: 2. Download the proto file and a sample input: ```shell - curl -sO https://raw.githubusercontent.com/iter8-tools/docs/v0.13.18/samples/modelmesh-serving/kserve.proto - curl -sO https://raw.githubusercontent.com/iter8-tools/docs/v0.13.18/samples/modelmesh-serving/grpc_input.json + curl -sO https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/modelmesh-serving/kserve.proto + curl -sO https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/modelmesh-serving/grpc_input.json ``` 3. Send inference requests: diff --git a/docs/tutorials/integrations/kserve-mm/canary.md b/docs/tutorials/integrations/kserve-mm/canary.md index b7b28930..c483c0e8 100644 --- a/docs/tutorials/integrations/kserve-mm/canary.md +++ b/docs/tutorials/integrations/kserve-mm/canary.md @@ -93,8 +93,7 @@ To send inference requests to the model: === "From within the cluster" 1. Create a "sleep" pod in the cluster from which requests can be made: ```shell - # curl -s https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/modelmesh-serving/sleep.sh | sh - - source /Users/kalantar/projects/go.workspace/src/github.com/iter8-tools/docs/samples/modelmesh-serving/sleep.sh + curl -s https://raw.githubusercontent.com/iter8-tools/docs/v0.15.2/samples/modelmesh-serving/sleep.sh | sh - ``` 2. exec into the sleep pod: @@ -122,8 +121,8 @@ To send inference requests to the model: 2. Download the proto file and a sample input: ```shell - curl -sO https://raw.githubusercontent.com/iter8-tools/docs/v0.13.18/samples/modelmesh-serving/kserve.proto - curl -sO https://raw.githubusercontent.com/iter8-tools/docs/v0.13.18/samples/modelmesh-serving/grpc_input.json + curl -sO https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/modelmesh-serving/kserve.proto + curl -sO https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/modelmesh-serving/grpc_input.json ``` 3. Send inference requests: diff --git a/docs/tutorials/integrations/kserve/blue-green.md b/docs/tutorials/integrations/kserve/blue-green.md index 55b21dd2..24d0488f 100644 --- a/docs/tutorials/integrations/kserve/blue-green.md +++ b/docs/tutorials/integrations/kserve/blue-green.md @@ -90,8 +90,7 @@ To send inference requests to the model: === "From within the cluster" 1. Create a "sleep" pod in the cluster from which requests can be made: ```shell - # curl -s https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/kserve-serving/sleep.sh | sh - - source /Users/kalantar/projects/go.workspace/src/github.com/iter8-tools/docs/samples/kserve-serving/sleep.sh + curl -s https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/kserve-serving/sleep.sh | sh - ``` 2. exec into the sleep pod: @@ -113,7 +112,7 @@ To send inference requests to the model: 2. Download the sample input: ```shell - # curl -sO https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/kserve-serving/input.json + curl -sO https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/kserve-serving/input.json ``` 3. Send inference requests: diff --git a/docs/tutorials/integrations/kserve/canary.md b/docs/tutorials/integrations/kserve/canary.md index 86baf6cc..04c689aa 100644 --- a/docs/tutorials/integrations/kserve/canary.md +++ b/docs/tutorials/integrations/kserve/canary.md @@ -90,8 +90,7 @@ To send inference requests to the model: === "From within the cluster" 1. Create a "sleep" pod in the cluster from which requests can be made: ```shell - # curl -s https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/kserve-serving/sleep.sh | sh - - source /Users/kalantar/projects/go.workspace/src/github.com/iter8-tools/docs/samples/kserve-serving/sleep.sh + curl -s https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/kserve-serving/sleep.sh | sh - ``` 2. exec into the sleep pod: @@ -118,7 +117,7 @@ To send inference requests to the model: 2. Download the sample input: ```shell - # curl -sO https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/kserve-serving/input.json + curl -sO https://raw.githubusercontent.com/iter8-tools/docs/v0.15.1/samples/kserve-serving/input.json ``` 3. Send inference requests: diff --git a/samples/modelmesh-serving/sleep.sh b/samples/modelmesh-serving/sleep.sh index dac7e8c5..c203e792 100644 --- a/samples/modelmesh-serving/sleep.sh +++ b/samples/modelmesh-serving/sleep.sh @@ -1,5 +1,3 @@ -<<<<<<< HEAD -======= #!/bin/sh # To use with RedHat OpenShift Service Mesh, set @@ -423,4 +421,3 @@ EOF kubectl apply -f $MANIFEST rm -f $MANIFEST ->>>>>>> 0d2649e (update kserver-modelmesh use cases) From de23bc6b7214475685cb6aabb7068ca49e795087 Mon Sep 17 00:00:00 2001 From: Michael Kalantar Date: Mon, 7 Aug 2023 16:54:24 -0400 Subject: [PATCH 13/13] make link explicit Signed-off-by: Michael Kalantar --- docs/tutorials/abn/abn.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/abn/abn.md b/docs/tutorials/abn/abn.md index 1b4af2fc..5f31c8e6 100644 --- a/docs/tutorials/abn/abn.md +++ b/docs/tutorials/abn/abn.md @@ -96,13 +96,12 @@ In this definition, each version of the application is composed of a `Service` a ## Generate load -In separate shells, port-forward requests to the frontend component and generate load for multiple users. A [script](https://raw.githubusercontent.com/iter8-tools/docs/main/samples/abn-sample/generate_load.sh) is provided for the latter. +In separate shells, port-forward requests to the frontend component and generate load for multiple users. A [script](https://raw.githubusercontent.com/iter8-tools/docs/main/samples/abn-sample/generate_load.sh) is provided to do this. To use it: ```shell kubectl port-forward service/frontend 8090:8090 ``` ```shell curl -s https://raw.githubusercontent.com/iter8-tools/docs/v0.15.0/samples/abn-sample/generate_load.sh | sh -s -- - # source /Users/kalantar/projects/go.workspace/src/github.com/iter8-tools/docs/samples/abn-sample/generate_load.sh ``` @@ -128,7 +127,7 @@ Inspect the metrics using Grafana. If Grafana is deployed to your cluster, port- kubectl port-forward service/grafana 3000:3000 ``` -Open Grafana in a browser by going to http://localhost:3000/ +Open Grafana in a browser by going to [http://localhost:3000](http://localhost:3000) [Add a JSON API data source](http://localhost:3000/connections/datasources/marcusolsson-json-datasource) `Iter8` with: