I am using istio 1.9.0.
Only during an issue did I discover that Service Entries are applied at a cluster level even if the namespace is specified in the manifest. This becomes particularly thorny if you have multiple Service Entries in different namespaces for the same hostnames.
I later found the docs that mention the following:
exportTo
:
A list of namespaces to which this service is exported. Exporting a service allows it to be used by sidecars, gateways and virtual services defined in other namespaces. This feature provides a mechanism for service owners and mesh administrators to control the visibility of services across namespace boundaries.
If no namespaces are specified then the service is exported to all namespaces by default.
The value “.” is reserved and defines an export to the same namespace that the service is declared in. Similarly the value “*” is reserved and defines an export to all namespaces.
From here.
Q1. The docs however explicitly fails to clarify if adding the exportTo=’.’ ensures that a Service Entry in my namespace will always take priority. Is this implied? particularly interested to find some documentation that calls out the expected behaviour.
Q2. Also how do you go about checking which Service Entry has been applied for the same hostname if multiple exist? How does istio handle this?
The problem is related to ServiceEntry concept design and it's quite complex.
My understanding of the current situation is that one should have an explicitly defined ServiceEntry in the certain namespace to prevent Istio from searching other ServiceEntries in another namespaces for the same host endpoint.
More information about the problem you can find in the issue #13008 :
The changes was made in the PR #13631 :
See the design doc for more details. I'd recommend to read the whole document to see a full picture.
The main point of the change is to implement the following:
Proposed Behavior
- Pilot will internally be modified to key Services by a hostname and namespace pair, rather than just hostname. When determining which Services to use for a hostname we will follow this resolution:
- If the hostname exists in the client's namespace, use only that namespace's service.
- If the hostname exists only in one namespace imported by the Sidecar, use that namespace's service. Otherwise, if there are multiple namespaces with services, an arbitrary one can be chosen (based on creation timestamp, like other configs).
The end result of this is that while hostnames are not distinct at a global level, any given proxy will have a single unique hostname -> service mapping.
Additionally, a ServiceEntry for an internal service will be rejected if it is created in different namespace. For example, if foo.ns1.svc.cluster.local was defined in namespace ns2, it would be rejected. This prevents the case of a user importing [ns1/, ns2/] and having their requests to foo.ns1.svc.cluster.local hijacked.
Unfortunately I wasn't able to find the final state of the implemented changes for the recent Istio version.
Not having a minimal reproducible example from you doesn't allow me to check if you were facing the implementation flaw or your configuration is a corner case that the change wasn't suppose to solve.
It's sad that current Istio documentation doesn't explain this aspect well enough.