Skip to content

Commit

Permalink
initial istio canary example
Browse files Browse the repository at this point in the history
  • Loading branch information
ukclivecox committed Jun 19, 2018
1 parent ffdd2ca commit af8d087
Show file tree
Hide file tree
Showing 8 changed files with 987 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.TimeUnit;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
Expand Down Expand Up @@ -56,7 +57,7 @@ public class InternalPredictionService {
@Autowired
public InternalPredictionService(AppProperties appProperties){
this.appProperties = appProperties;
connectionManager = new PoolingHttpClientConnectionManager();
connectionManager = new PoolingHttpClientConnectionManager(10,TimeUnit.SECONDS);
connectionManager.setMaxTotal(150);
connectionManager.setDefaultMaxPerRoute(150);

Expand Down
670 changes: 670 additions & 0 deletions examples/istio/canary_update/canary.ipynb

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions examples/istio/canary_update/istio_canary_v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mnist-deployment
namespace: seldon
spec:
hosts:
- mnist-deployment
http:
- route:
- destination:
host: mnist-deployment
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: mnist-deployment
namespace: seldon
spec:
host: mnist-deployment
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---

35 changes: 35 additions & 0 deletions examples/istio/canary_update/istio_canary_v2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mnist-deployment
namespace: seldon
spec:
hosts:
- mnist-deployment
http:
- route:
- destination:
host: mnist-deployment
subset: v1
weight: 90
- destination:
host: mnist-deployment
subset: v2
weight: 10
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: mnist-deployment
namespace: seldon
spec:
host: mnist-deployment
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---

30 changes: 30 additions & 0 deletions examples/istio/canary_update/istio_canary_v3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mnist-deployment
namespace: seldon
spec:
hosts:
- mnist-deployment
http:
- route:
- destination:
host: mnist-deployment
subset: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: mnist-deployment
namespace: seldon
spec:
host: mnist-deployment
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---

52 changes: 52 additions & 0 deletions examples/istio/canary_update/mnist_v1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"apiVersion": "machinelearning.seldon.io/v1alpha2",
"kind": "SeldonDeployment",
"metadata": {
"labels": {
"app": "seldon"
},
"name": "mnist-classifier"
},
"spec": {
"annotations": {
"project_name": "Mnist classification"
},
"name": "mnist-deployment",
"oauth_key": "oauth-key",
"oauth_secret": "oauth-secret",
"predictors": [
{
"componentSpecs": [{
"spec": {
"containers": [
{
"image": "seldonio/r-mnist:0.1",
"imagePullPolicy": "IfNotPresent",
"name": "r-mnist-classifier",
"resources": {
"requests": {
"memory": "1Mi"
}
}
}
],
"terminationGracePeriodSeconds": 20
}
}],
"graph": {
"children": [],
"name": "r-mnist-classifier",
"endpoint": {
"type" : "REST"
},
"type": "MODEL"
},
"name": "r-mnist-predictor",
"replicas": 1,
"labels":{
"version":"v1"
}
}
]
}
}
85 changes: 85 additions & 0 deletions examples/istio/canary_update/mnist_v2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"apiVersion": "machinelearning.seldon.io/v1alpha2",
"kind": "SeldonDeployment",
"metadata": {
"labels": {
"app": "seldon"
},
"name": "mnist-classifier"
},
"spec": {
"annotations": {
"project_name": "Mnist classification"
},
"name": "mnist-deployment",
"oauth_key": "oauth-key",
"oauth_secret": "oauth-secret",
"predictors": [
{
"componentSpecs": [{
"spec": {
"containers": [
{
"image": "seldonio/r-mnist:0.1",
"imagePullPolicy": "IfNotPresent",
"name": "r-mnist-classifier",
"resources": {
"requests": {
"memory": "1Mi"
}
}
}
],
"terminationGracePeriodSeconds": 20
}
}],
"graph": {
"children": [],
"name": "r-mnist-classifier",
"endpoint": {
"type" : "REST"
},
"type": "MODEL"
},
"name": "r-mnist-predictor",
"replicas": 1,
"labels":{
"version":"v1"
}
},
{
"componentSpecs": [{
"spec": {
"containers": [
{
"image": "seldonio/deep-mnist:0.1",
"imagePullPolicy": "IfNotPresent",
"name": "tf-mnist-classifier",
"resources": {
"requests": {
"memory": "1Mi"
}
}
}
],
"terminationGracePeriodSeconds": 20
}
}],
"graph": {
"children": [],
"name": "tf-mnist-classifier",
"endpoint": {
"type" : "REST"
},
"type": "MODEL"
},
"name": "tf-mnist-predictor",
"replicas": 1,
"labels":{
"version":"v2"
}
}

]
}
}
83 changes: 83 additions & 0 deletions examples/istio/canary_update/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import requests
from requests.auth import HTTPBasicAuth
from random import randint,random
import json
from matplotlib import pyplot as plt
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data


AMBASSADOR_API_IP="localhost:8002"
API_HTTP="localhost:8003"

def get_token():
payload = {'grant_type': 'client_credentials'}
response = requests.post(
"http://"+API_HTTP+"/oauth/token",
auth=HTTPBasicAuth('oauth-key', 'oauth-secret'),
data=payload)
print(response.text)
token = response.json()["access_token"]
return token

def rest_request_seldon(request):
token = get_token()
headers = {'Authorization': 'Bearer '+token}
response = requests.post(
"http://"+API_HTTP+"/api/v0.1/predictions",
headers=headers,
json=request)
return response.json()


def rest_request(deploymentName,request):
response = requests.post(
"http://"+AMBASSADOR_API_IP+"/seldon/"+deploymentName+"/api/v0.1/predictions",
json=request)
return response.json()

def rest_request_auth(deploymentName,data,username,password):
payload = {"data":{"ndarray":data.tolist()}}
response = requests.post(
"http://"+AMBASSADOR_API_IP+"/seldon/"+deploymentName+"/api/v0.1/predictions",
json=payload,
auth=HTTPBasicAuth(username, password))
print(response.status_code)
return response.json()

def send_feedback_rest(deploymentName,request,response,reward):
feedback = {
"request": request,
"response": response,
"reward": reward
}
ret = requests.post(
"http://"+AMBASSADOR_API_IP+"/seldon/"+deploymentName+"/api/v0.1/feedback",
json=feedback)
return ret.text

def gen_image(arr):
two_d = (np.reshape(arr, (28, 28)) * 255).astype(np.uint8)
plt.imshow(two_d,cmap=plt.cm.gray_r, interpolation='nearest')
return plt

def download_mnist():
return input_data.read_data_sets("MNIST_data/", one_hot = True)

def predict_rest_mnist(mnist,deployment_name):
batch_xs, batch_ys = mnist.train.next_batch(1)
chosen=0
gen_image(batch_xs[chosen]).show()
data = batch_xs[chosen].reshape((1,784))
features = ["X"+str(i+1) for i in range (0,784)]
request = {"data":{"names":features,"ndarray":data.tolist()}}
predictions = rest_request(deployment_name,request)
#predictions = rest_request_seldon(request)
print("Route:"+json.dumps(predictions["meta"]["routing"],indent=2))
fpreds = [ '%.2f' % elem for elem in predictions["data"]["ndarray"][0] ]
m = dict(zip(predictions["data"]["names"],fpreds))
print(json.dumps(m,indent=2))




0 comments on commit af8d087

Please sign in to comment.