Istio Conditional Rules

We can apply some rules to route the specific traffic into a specific destination with conditional rules. Conditional rules work with three difference method:

  • sourceLabels, route the traffic from source into a destination based on labels, if the traffic from client (pod) have specific label defined in sourceLabels,  then route the traffic into a specific destination.
  • header, route the traffic from source into a destination based on the HTTP header
  • URI, route the traffic from source into a destination based on URI path

In this article, we will focus on sourceLabels and header, the first thing is to create the deployment and service for the application, we create 3 deployments with a different version:

apiVersion: v1
kind: Service
metadata:
  name: apache-apps-service
  labels:
    app: apache-apps
    service: apache-apps
spec:
  type: NodePort
  ports:
  - port: 80
    name: http
  selector:
    app: apache-apps
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: apache-apps-v1
  labels:
    app: apache-apps
    version: v1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: apache-apps
        version: v1
    spec:
      containers:
      - name: apache-apps
        image: zufardhiyaulhaq/comet:v1
        ports:
        - containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: apache-apps-v2
  labels:
    app: apache-apps
    version: v2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: apache-apps
        version: v2
    spec:
      containers:
      - name: apache-apps
        image: zufardhiyaulhaq/comet:v2
        ports:
        - containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: apache-apps-v3
  labels:
    app: apache-apps
    version: v3
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: apache-apps
        version: v3
    spec:
      containers:
      - name: apache-apps
        image: zufardhiyaulhaq/comet:v3
        ports:
        - containerPort: 80

After that, create the gateway for external access:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: apache-apps-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "zufardhiyaulhaq.com"

let’s define the VirtualService, we create two virtual services for handling from gateway and handling from the internal mesh.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: apache-apps-vs-out
spec:   
  hosts:
  - "zufardhiyaulhaq.com"
  gateways:
  - apache-apps-gateway
  http: 
  - match:
    - headers:
        version:
          exact: v3
    route:
    - destination:
        host: apache-apps-service
        subset: v3
  - route:
    - destination:
        host: apache-apps-service
        subset: v2
      weight: 10
    - destination:
        host: apache-apps-service
        subset: v1
      weight: 90
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: apache-apps-vs-in
spec:
  hosts:
  - apache-apps-service
  http:
  - match:
    - headers:
        version:
          exact: v3
    route:
    - destination:
        host: apache-apps-service
        subset: v3
  - match:
    - sourceLabels:
        clientapp: v2
    route:
    - destination:
        host: apache-apps-service
        subset: v2
  - route:
    - destination:
        host: apache-apps-service
        subset: v2
      weight: 10
    - destination:
        host: apache-apps-service
        subset: v1
      weight: 90

create destination rule:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: apache-apps-dr
spec:
  host: apache-apps-service
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3

We will test from 3 difference hosts:

  • a Pod (client-1) that has label clientapp: v2
  • a Pod (client-2) without a label
  • From External (we try from the kubernetes node)

let’s create the client first, notice that client-1 need service for working with sourceLabels:

apiVersion: v1
kind: Pod
metadata:
  name: client-1
  labels:
    clientapp: v2
spec:
  containers:
  - name: container 
    image: zufardhiyaulhaq/comet:v3
---
apiVersion: v1
kind: Service
metadata:
  name: client-1-svc
  labels:
    clientapp: v2
spec:
  ports:
  - port: 80
    name: http
  selector:
    clientapp: v2
---
apiVersion: v1
kind: Pod
metadata:
  name: client-2
spec:
  containers:
  - name: container 
    image: zufardhiyaulhaq/comet:v3

Testing

from the kubernetes node:

btech@zu-istio-master1:~/istio-2$ for ((i=1;i<=10;i++));do curl -HHost:zufardhiyaulhaq.com 10.200.200.10:31380; done;
v2
v1
v1
v1
v1
v1
v1
v1
v1
v1
btech@zu-istio-master1:~/istio-2$ for ((i=1;i<=10;i++));do curl -HHost:zufardhiyaulhaq.com -Hversion:v3 10.200.200.10:31380; done;
v3
v3
v3
v3
v3
v3
v3
v3
v3
v3

from client-1

root@client-1:/# for ((i=1;i<=10;i++));do curl -Hversion:v3 apache-apps-service; done;
v3
v3
v3
v3
v3
v3
v3
v3
v3
v3
root@client-1:/# for ((i=1;i<=10;i++));do curl apache-apps-service; done;
v2
v2
v2
v2
v2
v2
v2
v2
v2
v2
root@client-1:/# for ((i=1;i<=10;i++));do curl -HHost:zufardhiyaulhaq.com 10.200.200.10:31380; done;
v2
v1
v2
v1
v1
v1
v1
v1
v1
v1
root@client-1:/# for ((i=1;i<=10;i++));do curl -HHost:zufardhiyaulhaq.com -Hversion:v3 10.200.200.10:31380; done;
v3
v3
v3
v3
v3
v3
v3
v3
v3
v3

from client-2

btech@zu-istio-master1:~/istio-2$ kubectl exec -it client-2 -c container -- bash
root@client-2:/# for ((i=1;i<=10;i++));do curl -Hversion:v3 apache-apps-service; done;
v3
v3
v3
v3
v3
v3
v3
v3
v3
v3
root@client-2:/# for ((i=1;i<=10;i++));do curl apache-apps-service; done;
v1
v2
v1
v1
v1
v1
v1
v1
v1
v2
root@client-2:/# for ((i=1;i<=10;i++));do curl -HHost:zufardhiyaulhaq.com 10.200.200.10:31380; done;
v1
v1
v1
v1
v1
v1
v1
v1
v1
v2
root@client-2:/# for ((i=1;i<=10;i++));do curl -HHost:zufardhiyaulhaq.com -Hversion:v3 10.200.200.10:31380; done;
v3
v3
v3
v3
v3
v3
v3
v3
v3
v3

 

Comments are closed.