Mesh Week: Traffic Management (# 2)
I tried the mock exam provided by Mesh Week at the following link:
Question: Traffic Management
Two versions of a workload are running inside the cluster - orders-v1
and orders-v2
. A Kubernetes Service resource also uses “app: orders” in its label selector; both deployments use the version label either set to v1
or v2
.
You’ve been asked to configure a 30-70 traffic split where 30%
of the traffic goes to orders-v1
and 70%
goes to orders-v2
.
Create the VirtualService and DestinationRule resources.
Answer
default
namespace
Step 1: Enable Istio sidecar injection for the First, enable Istio's sidecar injection.
$ kubectl label ns default istio-injection=enabled
orders-v1.yaml
and orders-v2.yaml
Step 2: Create Deployment YAML files for Next, create the deployment files for orders-v1
and orders-v2
.
$ kubectl create deploy orders --image=nginx:alpine --dry-run=client -o yaml > orders-v1.yaml
$ kubectl create deploy orders --image=nginx:alpine --dry-run=client -o yaml > orders-v2.yaml
orders-v1.yaml
Step 3: Edit Edit orders-v1.yaml
as follows to add the version v1
.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: orders
name: orders-v1
spec:
replicas: 1
selector:
matchLabels:
app: orders
template:
metadata:
labels:
app: orders
version: v1 # added
spec:
containers:
- image: nginx:alpine
name: nginx
orders-v2.yaml
Step 4: Edit Next, edit orders-v2.yaml
to add the version v2
.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: orders
name: orders-v2
spec:
replicas: 1
selector:
matchLabels:
app: orders
template:
metadata:
labels:
app: orders
version: v2 # added
spec:
containers:
- image: nginx:alpine
name: nginx
Step 5: Apply the Deployments
Apply both deployments to Kubernetes.
$ kubectl apply -f orders-v1.yaml
$ kubectl apply -f orders-v2.yaml
Step 6: Create a Test Pod
Create a test pod to check our services.
$ kubectl run tester --image=nginx:alpine
orders-v1
Step 7: Create a ClusterIP Service for Expose orders-v1
via a ClusterIP service.
$ kubectl expose deployment orders-v1 --name=orders --port=80 --type=ClusterIP
orders-v1
and orders-v2
Step 8: Update HTML content for Next, update the HTML content for both orders-v1
and orders-v2
.
$ kubectl exec -it $(kubectl get pod -l version=v1 -o jsonpath='{.items[0].metadata.name}') -- sh
cd /usr/share/nginx/html
echo "orders-v1" > index.html
$ kubectl exec -it $(kubectl get pod -l version=v2 -o jsonpath='{.items[0].metadata.name}') -- sh
cd /usr/share/nginx/html
echo "orders-v2" > index.html
DestinationRule
Step 9: Create the Now, create a DestinationRule
for routing between orders-v1
and orders-v2
.
# orders-dr.yaml
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: orders
spec:
host: orders
subsets:
- name: orders-v1
labels:
version: v1
- name: orders-v2
labels:
version: v2
$ kubectl apply -f orders-dr.yaml
VirtualService
Step 10: Create the Then, create a VirtualService
that distributes traffic 70% to orders-v1
and 30% to orders-v2
.
# orders-vs.yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: orders
spec:
hosts:
- orders
http:
- route:
- destination:
host: orders
subset: orders-v1
weight: 70
- destination:
host: orders
subset: orders-v2
weight: 30
$ kubectl apply -f orders-vs.yaml
curl
Step 11: Validate Load Balancing using Finally, verify the traffic distribution using curl
.
$ kubectl exec tester -- /bin/sh -c 'for i in $(seq 1 1000); do curl -s http://order | grep "order"; echo; done' | grep order-v2 | wc -l
287
$ kubectl exec tester -- /bin/sh -c 'for i in $(seq 1 1000); do curl -s http://order | grep "order"; echo; done' | grep order-v1 | wc -l
706
This confirms that 70% of the traffic is routed to orders-v1
and 30% to orders-v2
.