Istio ServiceEntry for multiple external databases going to the same database

11/20/2019

We have 2 services in our cluster in the same namespace, each using their own database like below: enter image description here

We added 2 ServiceEntry corresponding to each database:

---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: service-1
  namespace: mynamespace
spec:
  exportTo:
    - "."
  hosts:
    - service1-db.xxx.com
  ports:
    - number: 5432
      name: tcp
      protocol: tcp
  resolution: DNS
  location: MESH_EXTERNAL
...

---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: service-2
  namespace: mynamespace
spec:
  exportTo:
    - "."
  hosts:
    - service2-db.xxx.com
  ports:
    - number: 5432
      name: tcp
      protocol: tcp
  resolution: DNS
  location: MESH_EXTERNAL
...

The resulting interaction looks like this, which is not expected:

enter image description here

Any clues on what we are missing?

-- droidbot
amazon-web-services
cloud
istio
kubernetes

1 Answer

11/26/2019

So, at the end, it happens that the ServiceEntry does not work just based on the host names, but it needs addresses too.

Here is what worked:

---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: service-1
  namespace: mynamespace
spec:
  exportTo:
    - "."
  hosts:
    - service1-db.xxx.com
  addresses:
    - xx.xx.xx.xx/32
  ports:
    - number: 5432
      name: tcp
      protocol: tcp
  resolution: NONE
  location: MESH_EXTERNAL
...

---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: service-2
  namespace: mynamespace
spec:
  exportTo:
    - "."
  hosts:
    - service2-db.xxx.com
  addresses:
    - xx.xx.xx.yy/32
  ports:
    - number: 5432
      name: tcp
      protocol: tcp
  resolution: NONE
  location: MESH_EXTERNAL
...

Here are the excerpts from the documentation that led us to this conclusion.

If the Addresses field is empty, traffic will be identified solely based on the destination port. In such scenarios, the port on which the service is being accessed must not be shared by any other service in the mesh.

Note that when resolution is set to type DNS and no endpoints are specified, the host field will be used as the DNS name of the endpoint to route traffic to.

NOTE: While this helped resolve this particular instance, it opens up another different question of working with dynamic ip addresses, like some app trying to access AWS secrets manager. The ip address of such services keep changing and there is no way to tie it down to a service entry. So, we added service entries only for the known external traffic and allowed others to be unknown. In Kiali (visualiser for Istio), these "unknowns" are displayed as PassThroughClusters, which is annoying, but only half the problem.

-- droidbot
Source: StackOverflow