cat << EOF | istioctl kube-inject -f - | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: httpbin-v1
spec:
replicas: 1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:8080", "httpbin:app"]
ports:
- containerPort: 8080
EOF
cat << EOF | istioctl kube-inject -f - | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: httpbin-v2
spec:
replicas: 1
template:
metadata:
labels:
app: httpbin
version: v2
spec:
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:8080", "httpbin:app"]
ports:
- containerPort: 8080
EOF
cat << EOF | kubectl create -f -
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
spec:
ports:
- name: http
port: 8080
selector:
app: httpbin
EOF
Create sleep service (curl to provide load)
cat << EOF | istioctl kube-inject -f - | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: sleep
spec:
replicas: 1
template:
metadata:
labels:
app: sleep
spec:
containers:
- name: sleep
image: tutum/curl
command: ["/bin/sleep","infinity"]
imagePullPolicy: IfNotPresent
EOF
Create default route -> v1
cat << EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- httpbin
http:
- route:
- destination:
host: httpbin
subset: v1
weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
EOF
All traffic should go to v1
export SLEEP_POD=$( kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
kubectl exec -it $SLEEP_POD -c sleep -- sh -c ' curl http://httpbin:8080/headers' | python -m json.tool
{
" headers" : {
" Accept" : " */*" ,
" Content-Length" : " 0" ,
" Host" : " httpbin:8080" ,
" User-Agent" : " curl/7.35.0" ,
" X-B3-Sampled" : " 1" ,
" X-B3-Spanid" : " eca3d7ed8f2e6a0a" ,
" X-B3-Traceid" : " eca3d7ed8f2e6a0a" ,
" X-Ot-Span-Context" : " eca3d7ed8f2e6a0a;eca3d7ed8f2e6a0a;0000000000000000"
}
}` ` `
# Check logs for v1 and v2 pods
# Only traffic for v1 pod
` ` ` bash
export V1_POD=$( kubectl get pod -l app=httpbin,version=v1 -o jsonpath={.items..metadata.name})
kubectl logs -f $V1_POD -c httpbin
127.0.0.1 - - [07/Mar/2018:19:02:43 +0000] " GET /headers HTTP/1.1" 200 321 " -" " curl/7.35.0"
export V2_POD=$( kubectl get pod -l app=httpbin,version=v2 -o jsonpath={.items..metadata.name})
kubectl logs -f $V2_POD -c httpbin
Create route to mirror traffic to v2
cat << EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- httpbin
http:
- route:
- destination:
host: httpbin
subset: v1
weight: 100
mirror:
host: httpbin
subset: v2
EOF
kubectl exec -it $SLEEP_POD -c sleep -- sh -c ' curl http://httpbin:8080/headers' | python -m json.tool
We should see traffic for v1 and v2
kubectl logs -f $V1_POD -c httpbin
127.0.0.1 - - [07/Mar/2018:19:02:43 +0000] " GET /headers HTTP/1.1" 200 321 " -" " curl/7.35.0"
127.0.0.1 - - [07/Mar/2018:19:26:44 +0000] " GET /headers HTTP/1.1" 200 321 " -" " curl/7.35.0"
kubectl logs -f $V2_POD -c httpbin
127.0.0.1 - - [07/Mar/2018:19:26:44 +0000] " GET /headers HTTP/1.1" 200 361 " -" " curl/7.35.0"
kubectl delete virtualservice httpbin
kubectl delete destinationrule httpbin
kubectl delete deploy httpbin-v1 httpbin-v2 sleep
kubectl delete svc httpbin