Skip to content

Commit 40fb76a

Browse files
authored
updated abn sdk tutorial (#95)
* updated abn sdk tutorial Signed-off-by: Michael Kalantar <[email protected]> * fix spelling Signed-off-by: Michael Kalantar <[email protected]> * modify generate_load Signed-off-by: Michael Kalantar <[email protected]> * abn updates Signed-off-by: Michael Kalantar <[email protected]> * fix spelling, links Signed-off-by: Michael Kalantar <[email protected]> * reviwer comments, kustomize, python Signed-off-by: Michael Kalantar <[email protected]> * add dashboard image Signed-off-by: Michael Kalantar <[email protected]> * update documentation Signed-off-by: Michael Kalantar <[email protected]> --------- Signed-off-by: Michael Kalantar <[email protected]>
1 parent fbe4766 commit 40fb76a

32 files changed

+3139
-2148
lines changed

.github/wordlist.txt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ frontend
2323
GitOps
2424
gRPC
2525
GitHub
26+
Grafana
2627
GVR
2728
Homebrew
2829
http
@@ -87,7 +88,6 @@ warmupNumRequests
8788
webhook
8889
webhooks
8990
yaml
90-
abnmetrics
9191
auth
9292
argoproj
9393
custommetrics
@@ -124,10 +124,18 @@ rollout
124124
rollouts
125125
setName
126126
setUser
127-
trackToRoute
127+
versionNumberToRoute
128+
GetVersionNumber
129+
getVersionnumber
130+
versionNumber
131+
versionRecommendation
128132
toJson
129133
versionname
130134
WriteMetric
135+
MetricValue
136+
setApplication
137+
setValue
138+
toString
131139
contentType
132140
numRequests
133141
payloadStr
@@ -159,4 +167,4 @@ wget
159167
gz
160168
xvf
161169
IMG
162-
mv
170+
mv

.github/workflows/linkcheck.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121

2222
- name: Link checker
2323
id: lychee
24-
uses: lycheeverse/lychee-action@v1.6.1
24+
uses: lycheeverse/lychee-action@v1.8.0
2525
env:
2626
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
2727
with:

.lycheeignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,8 @@ https://twitter.com/Iter8Tools
55

66
https://raw.githubusercontent.com/*
77
https://kserve.github.io/*
8-
https://docs.litmuschaos.io/docs/*
8+
https://docs.litmuschaos.io/docs/*
9+
10+
http://localhost:3000
11+
http://localhost:3000/dashboards
12+
http://localhost:3000/connections/datasources/marcusolsson-json-datasource

docs/tutorials/abn/abn.md

Lines changed: 92 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -2,173 +2,183 @@
22
template: main.html
33
---
44

5-
# A/B Experiments
5+
# A/B Testing with the Iter8 SDK
66

7-
This tutorial describes an [A/B testing](../../user-guide/topics/ab_testing.md) experiment for a backend component.
7+
This tutorial describes how to do A/B testing of a backend component using the [Iter8 SDK](../../user-guide/topics/ab_testing.md).
88

99
![A/B/n experiment](images/abn.png)
1010

1111
***
1212

1313
???+ warning "Before you begin"
1414
1. Try [your first experiment](../../getting-started/your-first-experiment.md). Understand the main [concepts](../../getting-started/concepts.md) behind Iter8 experiments.
15+
2. Have Grafana available. For example, Grafana can be installed on your cluster as follows:
16+
```shell
17+
kubectl create deploy grafana --image=grafana/grafana
18+
kubectl expose deploy grafana --port=3000
19+
```
1520

16-
## Launch Iter8 A/B/n service
17-
18-
Deploy the Iter8 A/B/n service. When deploying the service, specify which Kubernetes resource types to watch for each application. To watch for versions of the *backend* application in the *default* namespace, configure the service to watch for Kubernetes service and deployment resources:
19-
20-
```shell
21-
helm install --repo https://iter8-tools.github.io/iter8 iter8-abn abn \
22-
--set "apps.default.backend.resources={service,deployment}"
23-
```
21+
## Launch the Iter8 A/B/n service
2422

25-
??? warn "Assumptions"
26-
To simplify specification, Iter8 assumes certain conventions:
27-
28-
- The baseline track identifier is the application name
29-
- Track identifiers associated with candidate versions are of the form `<application_name>-candidate-<index>`
30-
- All resource objects for all versions are deployed in the same namespace
31-
- There is only 1 resource object of a given type in each version
32-
- The name of each object in the version associated with the baseline track is the application name
33-
- The name of each object in the version associated with a candidate track is of the form `<application_name>-candidate-<index>` where index is 1, 2, etc.
23+
Deploy the Iter8 A/B/n service using either `helm` or `kustomize`:
3424

25+
--8<-- "docs/tutorials/installiter8controller.md"
3526

3627
## Deploy the sample application
3728

38-
Deploy both the frontend and backend components of the application as described in each tab:
29+
A sample application using the Iter8 SDK is provided. Deploy both the frontend and backend components of this application as described in each tab:
3930

4031
=== "frontend"
4132
Install the frontend component using an implementation in the language of your choice:
4233

4334
=== "node"
4435
```shell
45-
kubectl create deployment frontend --image=iter8/abn-sample-frontend-node:0.13
36+
kubectl create deployment frontend --image=iter8/abn-sample-frontend-node:0.15.0
4637
kubectl expose deployment frontend --name=frontend --port=8090
4738
```
39+
<!-- kubectl create deployment frontend --image=kalantar/frontend-node:20230717-1552 -->
4840

4941
=== "Go"
5042
```shell
51-
kubectl create deployment frontend --image=iter8/abn-sample-frontend-go:0.13
43+
kubectl create deployment frontend --image=iter8/abn-sample-frontend-go:0.15.0
5244
kubectl expose deployment frontend --name=frontend --port=8090
5345
```
46+
<!-- kubectl create deployment frontend --image=kalantar/frontend-go:20230717-1339 -->
5447

55-
The frontend component is implemented to call *Lookup()* before each call to the backend component. The frontend componet uses the returned track identifier to route the request to a version of the backend component.
48+
The frontend component is implemented to call `Lookup()` before each call to the backend component. The frontend component uses the returned version number to route the request to the recommended version of the backend component.
5649

5750
=== "backend"
58-
Deploy version *v1* of the *backend* component, associating it with the track identifier *backend*.
51+
Deploy an initial version of the *backend* component:
5952

6053
```shell
6154
kubectl create deployment backend --image=iter8/abn-sample-backend:0.13-v1
62-
kubectl label deployment backend app.kubernetes.io/version=v1
55+
kubectl label deployment backend iter8.tools/watch="true"
6356

6457
kubectl expose deployment backend --name=backend --port=8091
6558
```
6659

60+
## Describe the Application
61+
62+
In order to support `Lookup()`, Iter8 needs to know what the application component versions look like. A `ConfigMap` is used to describe the make up of possible versions:
63+
64+
```shell
65+
cat <<EOF | kubectl apply -f -
66+
apiVersion: v1
67+
kind: ConfigMap
68+
metadata:
69+
name: backend
70+
labels:
71+
app.kubernetes.io/managed-by: iter8
72+
iter8.tools/kind: routemap
73+
iter8.tools/version: "v0.15"
74+
immutable: true
75+
data:
76+
strSpec: |
77+
versions:
78+
- resources:
79+
- gvrShort: svc
80+
name: backend
81+
namespace: default
82+
- gvrShort: deploy
83+
name: backend
84+
namespace: default
85+
- resources:
86+
- gvrShort: svc
87+
name: backend-candidate-1
88+
namespace: default
89+
- gvrShort: deploy
90+
name: backend-candidate-1
91+
namespace: default
92+
EOF
93+
```
94+
95+
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.
96+
6797
## Generate load
6898

69-
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:
99+
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:
70100
```shell
71101
kubectl port-forward service/frontend 8090:8090
72102
```
73103
```shell
74-
curl -s https://raw.githubusercontent.com/iter8-tools/docs/main/samples/abn-sample/generate_load.sh | sh -s --
104+
curl -s https://raw.githubusercontent.com/iter8-tools/docs/v0.15.0/samples/abn-sample/generate_load.sh | sh -s --
75105
```
106+
<!-- # source /Users/kalantar/projects/go.workspace/src/github.com/iter8-tools/docs/samples/abn-sample/generate_load.sh -->
76107

77108
## Deploy a candidate version
78109

79-
Deploy version *v2* of the *backend* component, associating it with the track identifier *backend-candidate-1*.
110+
Deploy the candidate version of the *backend* component, naming it `backend-candidate-1`.
80111

81112
```shell
82113
kubectl create deployment backend-candidate-1 --image=iter8/abn-sample-backend:0.13-v2
83-
kubectl label deployment backend-candidate-1 app.kubernetes.io/version=v2
114+
kubectl label deployment backend-candidate-1 iter8.tools/watch="true"
84115

85116
kubectl expose deployment backend-candidate-1 --name=backend-candidate-1 --port=8091
86117
```
87118

88-
Until the candidate version is ready; that is, until all expected resources are deployed and available, calls to *Lookup()* will return only the *backend* track identifier.
89-
Once the candidate version is ready, *Lookup()* will return both track identifiers so that requests will be distributed between versions.
119+
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.
120+
Once the candidate version is ready, `Lookup()` will return both indices (0 and 1) so that requests can be distributed across versions.
121+
122+
## Compare versions using Grafana
90123

91-
## Launch experiment
124+
Inspect the metrics using Grafana. If Grafana is deployed to your cluster, port-forward requests as follows:
92125

93126
```shell
94-
iter8 k launch \
95-
--set abnmetrics.application=default/backend \
96-
--set "tasks={abnmetrics}" \
97-
--set runner=cronjob \
98-
--set cronjobSchedule="*/1 * * * *"
127+
kubectl port-forward service/grafana 3000:3000
99128
```
100129

101-
??? note "About this experiment"
102-
This experiment periodically (in this case, once a minute) reads the `abn` metrics associated with the *backend* application component in the *default* namespace. These metrics are written by the frontend component using the *WriteMetric()* interface as a part of processing user requests.
103-
104-
## Inspect experiment report
105-
106-
Inspect the metrics:
130+
Open Grafana in a browser:
107131

108132
```shell
109-
iter8 k report
133+
http://localhost:3000/
110134
```
111135

112-
??? note "Sample output from report"
113-
```
114-
Experiment summary:
115-
*******************
116-
117-
Experiment completed: true
118-
No task failures: true
119-
Total number of tasks: 1
120-
Number of completed tasks: 1
121-
Number of completed loops: 3
122-
123-
Latest observed values for metrics:
124-
***********************************
125-
126-
Metric | backend (v1) | backend-candidate-1 (v2)
127-
------- | ----- | -----
128-
abn/sample_metric/count | 35.00 | 28.00
129-
abn/sample_metric/max | 99.00 | 100.00
130-
abn/sample_metric/mean | 56.31 | 52.79
131-
abn/sample_metric/min | 0.00 | 1.00
132-
abn/sample_metric/stddev | 28.52 | 31.91
133-
```
134-
The output allows you to compare the versions against each other and select a winner. Since the experiment runs periodically, the values in the report will change over time.
136+
[Add a JSON API data source](http://localhost:3000/connections/datasources/marcusolsson-json-datasource) `Iter8` with:
135137

136-
Once a winner is identified, the experiment can be terminated, the winner can be promoted, and the candidate version(s) can be deleted.
138+
- URL `http://iter8.default:8080/metrics` and
139+
- query string `application=default%2Fbackend`
137140

138-
To delete the experiment:
141+
[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.
139142

140-
```shell
141-
iter8 k delete
142-
```
143+
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:
144+
145+
![A/B dashboard](images/dashboard.png)
146+
147+
Once a winner is identified, the winner can be promoted, and the candidate version deleted.
143148

144149
## Promote candidate version
145150

146-
Delete the candidate version:
151+
To promote the candidate version (`backend-candidate-1`), first update the primary version, `backend`, using the new image. You can also overwrite any metadata describing the version.
147152

148153
```shell
149-
kubectl delete deployment backend-candidate-1
150-
kubectl delete service backend-candidate-1
154+
kubectl set image deployment/backend abn-sample-backend=iter8/abn-sample-backend:0.13-v2
151155
```
152156

153-
Update the version associated with the baseline track identifier *backend*:
157+
Finally, delete the candidate version:
154158

155159
```shell
156-
kubectl set image deployment/backend abn-sample-backend=iter8/abn-sample-backend:0.13-v2
157-
kubectl label --overwrite deployment/backend app.kubernetes.io/version=v2
160+
kubectl delete svc/backend-candidate-1 deploy/backend-candidate-1
158161
```
159162

163+
Calls to `Lookup()` will now recommend that all traffic be sent to the primary version `backend` (currently serving the promoted version of the code).
164+
160165
## Cleanup
161166

162167
### Delete sample application
163168

164169
```shell
165170
kubectl delete \
166-
deploy/frontend deploy/backend deploy/backend-candidate-1 \
167-
service/frontend service/backend service/backend-candidate-1
171+
svc/frontend deploy/frontend \
172+
svc/backend deploy/backend \
173+
svc/backend-candidate-1 deploy/backend-candidate-1
168174
```
169175

170-
### Uninstall the A/B/n service
176+
### Delete the application description
171177

172178
```shell
173-
helm delete iter8-abn
179+
kubectl delete cm/backend
174180
```
181+
182+
### Uninstall the A/B/n service
183+
184+
--8<-- "docs/tutorials/deleteiter8controller.md"

docs/tutorials/abn/images/abn.png

-71.8 KB
Loading
275 KB
Loading
-248 KB
Binary file not shown.

0 commit comments

Comments
 (0)