kubernetesistio

Istio VirtualService and DestinationRule ignored when calling a service from inside the mesh


I am trying to implement blue/green deployment using Istio virtual services and destination rules. Seems like I can make it work when calling from outside the cluster, but when a pod calls another pod the requests are balanced on both blue and green instances. All the pods involved have the Envoy sidecar.

Istio ingress gateway has been installed with the default istioctl install.

The other relevant manifests are the following:

apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: bg-gateway
  namespace: bluegreen-playground
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 8080
      name: http
      protocol: HTTP
    hosts:
    - bluegreen.myexample.com
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: bg-route
  namespace: bluegreen-playground
spec:
  gateways:
    - bg-gateway
  hosts:
  - bluegreen.myexample.com
  - core-svc.bluegreen-playground.svc.cluster.local
  - front-svc.bluegreen-playground.svc.cluster.local
  http:
  - name: core
    match: 
    - uri:
        prefix: "/core"
    route:
    - destination:
        host: core-svc.bluegreen-playground.svc.cluster.local
        subset: blue
  - name: front
    match: 
    - uri: 
        prefix: "/"
    route:
    - destination:
        host: front-svc.bluegreen-playground.svc.cluster.local
        subset: blue
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: core-destination
  namespace: bluegreen-playground
spec:
  host: core-svc.bluegreen-playground.svc.cluster.local
  subsets:
  - name: blue
    labels:
      version: v1
  - name: green
    labels:
      version: v2
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: front-destination
  namespace: bluegreen-playground
spec:
  host: front-svc.bluegreen-playground.svc.cluster.local
  subsets:
  - name: blue
    labels:
      version: v1
  - name: green
    labels:
      version: v2

All the pods are correctly labeled with version: v1 or version: v2. The microservices call each other by using the standard Kubernetes service FQDN (e.g. front-svc.bluegreen-playground.svc.cluster.local).

Am I missing anything?


Solution

  • As discussed, you need to add mesh to gateway selector in VirtualService to apply the same rules inside mesh. https://istio.io/latest/docs/reference/config/networking/virtual-service/#VirtualService-gateways.

    The names of gateways and sidecars that should apply these routes. Gateways in other namespaces may be referred to by /; specifying a gateway with no namespace qualifier is the same as specifying the VirtualService’s namespace. A single VirtualService is used for sidecars inside the mesh as well as for one or more gateways. The selection condition imposed by this field can be overridden using the source field in the match conditions of protocol-specific routes. The reserved word mesh is used to imply all the sidecars in the mesh. When this field is omitted, the default gateway (mesh) will be used, which would apply the rule to all sidecars in the mesh. If a list of gateway names is provided, the rules will apply only to the gateways. To apply the rules to both gateways and sidecars, specify mesh as one of the gateway names.

    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
      name: bg-route
      namespace: bluegreen-playground
    spec:
      gateways:
        - bg-gateway
        - mesh # applies to all the sidecars in the mesh
      hosts:
      - bluegreen.myexample.com
      - core-svc.bluegreen-playground.svc.cluster.local
      - front-svc.bluegreen-playground.svc.cluster.local
      http:
      - name: core
        match: 
        - uri:
            prefix: "/core"
        route:
        - destination:
            host: core-svc.bluegreen-playground.svc.cluster.local
            subset: blue
      - name: front
        match: 
        - uri: 
            prefix: "/"
        route:
        - destination:
            host: front-svc.bluegreen-playground.svc.cluster.local
            subset: blue