How can I append DestinationRules without knowing the values?

7/10/2018

We are running an application divided in microservices thru Istio, running on k8s, packed with helm and builded in a GitLab CI/CD environment. What I would like to do is to implement kind of 'Review App' functionality GitLab provides. The idea is that the whole service is not touched and only the reviewable service is added to the mesh and callable by adding a header (or something) in the original request, x-request-version: [git sha] (for example).

Now the problem I stumble upon is that I can't spin up an extra VirtualService on the same host. I know I can use the Match-directive and DestinationRules for this. But from the CI/CD perspective I don't know which rules are already active. It should be possible to have multiple review apps online at the same time, because there are multiple developers working on the same services at the same time.

So I would like to know if there is a way to append (and remove) Istio VirtualServices and DestinationRules dynamically (without knowing the currently applied rules)?

Thanks in advance!


Maybe a code example would clarify somethings somehow:

Main VirtualService

kind: VirtualService
metadata:
  name: catalog
spec:
  gateways:
  - staging-gateway
  hosts:
  - catalog
  - "catalog.staging.services.example.com"
  http:
  - route:
    - destination:
        host: catalog
        subset: e3b0c442
    retries:
      attempts: 3
      perTryTimeout: 2s
  ## REVIEW 01 ##
  - match:                     # <---- Dynamic (Review 01)
    - headers:                 # <---- Dynamic (Review 01)
        x-request-version:     # <---- Dynamic (Review 01)
          exact: 9489bcb3      # <---- Dynamic (Review 01)
      route:                   # <---- Dynamic (Review 01)
      - destination:           # <---- Dynamic (Review 01)
          host: catalog        # <---- Dynamic (Review 01)
          subset: 9489bcb3     # <---- Dynamic (Review 01)
      retries:                 # <---- Dynamic (Review 01)
        attempts: 3            # <---- Dynamic (Review 01)
        perTryTimeout: 2s      # <---- Dynamic (Review 01)

DestinationRule

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: catalog
spec:
  host: catalog
  subsets:
  - name: e3b0c442      # <---- main service
    labels:             # <---- main service
      sha: e3b0c442     # <---- main service
      app: catalog      # <---- main service

  - name: 9489bcb3      # <---- Dynamic (Review 01)
    labels:             # <---- Dynamic (Review 01)
      sha: 9489bcb3     # <---- Dynamic (Review 01)
      app: catalog      # <---- Dynamic (Review 01)

Added after 2 days

I tried to visualize te setup. As you can see only two deployments (in this case) are edge services and accessible from the outside. The rest of services (MS) are only accessible by other services. The two yellow deployments are a branch (merge request) of MS10 accessible if the appropriate header is set. This way I can target the 'review' version of a deployment without altering hostnames.

So for example:

  1. I request: https://ms1.services.example.com
  2. MS1 will request: MS6 -> MS11 -> MS10 (by hostname: http://ms6, http://ms11, http://ms10)

If I want to target a specific (review) version of ms10 I will need to alter my code for ms11 and I will mesh up my... - indeed - mesh. So when I am using a header and sent this thru all requests I can use Istio to target a specific release. Gitlab's Environments are not sufficient in this case.

Service Mesh Example

-- user3776824
istio
kubernetes
kubernetes-helm

0 Answers