Service dependencies

Before you begin

To illustrate these concepts, we will assume that:

Be sure to review the assumptions and satisfy the pre-requisites from the Guides top-level document.

Declaring Service Dependencies

Motivation

Istio's default behavior is to configure all sidecar proxies in the mesh with all necessary information required to send traffic to any destination in the mesh. While useful for day one operations, this comes with a performance tradeoff that scales with the number of workloads and destinations— proxies may be maintaining unnecessary information in memory, which in aggregate may lead to a large memory footprint for the entire data plane.

If the operator of a service mesh has a priori knowledge of which destinations a particular workload needs to reach, this information can be provided to Istio as a way to prune away unneeded information, thereby alleviating memory consumption of the data plane.

ServiceDependency CRD

The ServiceDependency CRD facilitates management of workload-to-destination dependencies, which translate to Istio Sidecar CRs.

The ServiceDependency CR affects workload's egress traffic dependencies, i.e. it declares which destinations a given workload needs to send traffic to.

Consider the following example:

apiVersion: networking.enterprise.mesh.gloo.solo.io/v1beta1
kind: ServiceDependency
metadata:
  name: productpage-deps
  namespace: gloo-mesh
spec:
  sourceSelectors:
  - kubeWorkloadMatcher:
      labels:
        app: productpage
      namespaces:
      - bookinfo
  destinationSelectors:
  - kubeServiceRefs:
      services:
      - name: reviews
        namespace: bookinfo
        clusterName: cluster-2
      - name: reviews
        namespace: bookinfo
        clusterName: cluster-1

Semantically, this object declares that Kubernetes workloads with label app: productpage in the bookinfo namespace, on any cluster, depend on the Kubernetes service with name reviews in namespace bookinfo on both cluster-1 and cluster-2.

Assuming that the environment has a productpage-v1 workload deployed to cluster-1, Gloo Mesh will translate this object into the following Istio Sidecar object on cluster-1:

apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
  name: productpage-v1
  namespace: bookinfo
spec:
  egress:
  - hosts:
    - '*/reviews.bookinfo.svc.cluster.local' # the local reviews service
    - '*/reviews.bookinfo.svc.cluster-2.soloio' # the federated remote reviews service
  workloadSelector:
    labels:
      app: productpage
      version: v1

Declaring Dependencies to External Services

The ServiceDependency API also allows for selecting ExternalService Destinations, which represent Destinations external to any managed service mesh. For more details, see the ExternalService guide.

Consider the following ExternalService:

apiVersion: discovery.mesh.gloo.solo.io/v1
kind: Destination
metadata:
  name: my-ext-service
  namespace: gloo-mesh
spec:
  externalService:
    endpoints:
    - address: solo.io
      ports:
        http: 80
    hosts:
    - foo.bar.global
    - foo2.bar.global
    name: my-external-service
    ports:
    - name: http
      number: 80
      protocol: HTTP

You can declare a dependency to this ExternalService with the following ServiceDependency CR:

apiVersion: networking.enterprise.mesh.gloo.solo.io/v1beta1
kind: ServiceDependency
metadata:
  name: productpage-to-ext-service
  namespace: gloo-mesh
spec:
  sourceSelectors:
  - kubeWorkloadMatcher:
      labels:
        app: productpage
      namespaces:
      - bookinfo
  destinationSelectors:
  - externalServiceRefs:
      externalServices:
      - name: my-ext-service
        namespace: gloo-mesh

This should generate the following Sidecar CR:

apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
  name: productpage-v1
  namespace: bookinfo
spec:
  egress:
  - hosts:
    - '*/foo.bar.global' # the hostnames declared on the ExternalService
    - '*/foo2.bar.global'
  workloadSelector:
    labels:
      app: productpage
      version: v1

Semantics

  1. An important property to note about the ServiceDependency API is that objects are additive. If multiple ServiceDependencies target the same workload, that workload's egress dependencies will consist of the set union of all destinations declared on ServiceDependencies.

  2. Depending on the underlying mesh (such as Istio), declaring a ServiceDependency for a workload may prevent that workload from sending traffic to any destination other than those explicitly declared. Keep this in mind as you create these objects.

  3. The ServiceDependency API does not provide security guarantees. Even if a destination is not declared as a dependency for a given workload, dependending on the behavior of the underyling service mesh, that workload might still be able to communicate with that destination. This holds for Istio if global.outboundTrafficPolicy.mode is set to ALLOW_ANY.