ServiceEntry - what Services exist and how are their network endpoints found?
VirtualService - to which Service should traffic for a given hostname be sent?
DestinationRule - how do I talk to that Service?
Services in Istio
Services are the destination of Route Rules (the host which a VirtualService matches is an arbitrary string). Services by the Istio definition are morally “units of application behaviour”. They are made of network endpoints: Pods, and external endpoints. Istio has a Service Registry of all the Services it knows about. In some configurations it will refuse to send traffic to Services that aren’t in the Service Registry (in others it’ll assume the Service exists and take some guesses about how to find its endpoints and how to talk to them).
In a Kubernetes environment, the Service Registry is populated from Kubernetes Service instances. Extra Service Registry entries (eg for internet endpoints, VMs) can be added with the ServiceEntry resource. Recall that, in some mesh configurations, such ServiceEntries are necessary for workloads in the mesh to talk to anything outside the cluster. ServiceEntry is a higher-level resource - doesn’t necessarily specify all endpoints in a Service, instead it says where to discover them.
There is no (easy) way to view the contents of the Service Registry; the imported Kubernetes Services, DNS query results, etc aren’t reflected as a read-only resource like Kubernetes’ Endpoint.
VirtualService/
delay-injection.yaml
error-injection.yaml
header-manipulation.yaml
identity.yaml
layer-7-routing.yaml
redirect-rewrite.yaml
retry.yaml
timeout.yaml
traffic-split.yaml
VirtualService
VirtualServices configure routing rules for traffic.
Traffic is identified by the Host it’s addressed to in its layer 7 request header (there must be at most one VirtualService per Host). For a given protocol, Routing Rules are then tried in order until one matches the attributes of the request. The matching routing rule specifies a Service to which to send the request (a Service is effectively a Kubernetes Service, qv). Optionally, a subset of the Service’s Pods can be targeted using Subsets (see DestinationRule)
VirtualServices can be thought of as an “active” bump-on-the-wire through which requests are sent. They can apply various transforms to the traffic passing through them, such as header manipulation, delay injection, etc.
DestinationRule/
load-balance.yaml
sticky-sessions.yaml
subsets.yaml
tls.yaml
DestinationRule
After a destination Service is chosen by a VirtualService (the request is routed), a DestinationRule specifies how that Service should be talked to.
In this directory, “endpoint pool” means the set of endpoints to which traffic has been routed; a Service or a Subset of a Service
It describes how to load balance between the network endpoints of the Service (as found in the Service Registry). It also says how connections should be made to those network endpoints (HTTP version, TLS stance) and how they should be managed (keep-alive times, maximum active connections to load-balance onto any individual endpoint at once).
DestinationRules configure the client sidecars, eg for the flow service-a -> sidecar-a -> sidecar-b -> service-b the DestinationRule for host “service-b” configures each instance of “sidecar-a”. Thus the connection options technically configure how “sidecar-a” talks to “sidecar-b” (if the destination is also in the mesh, or directly to the service or whatever proxies are in front of it if it’s not). The only time to bear in mind that you’re talking to the server’s sidecar rather than the actual “app” is when considering TLS, as the server sidecar will terminate this. There is no way to configure the behaviour from “sidecar-b” to “service-b”; this is basically a passthrough, except the mutual TLS upgrade noted above.
DestinationRules are implemented locally by each sidecar; there is no global coordination between sidecars. For example
circuit-breaker detection and elimination is done per client sidecar; each holds their own state for this which might differ from other sidecars’
DestinationRules configure how one client should talk to the pool of endpoints (a Service or subset of a Service). For example
load-balancer config controls how each individual client should pick one of the n servers (endpoint instances) each time there’s a new outbound connection
circuit-breaking applies across the pool (of servers); it temporarily removes instances from the pool (even if Service Discovery says they’re healthy thus they’re in the service registry)
TLS config applies to all connections from the client to any server (in the pool) The exception is connection-pool settings, which apply to each client-server pair individually. Recall though that they apply to sidecar-a -> sidecar-b, not sidecar-b -> service-b.
It also somewhat confusingly details the Subsets of the Service available as routing targets in VirtualServices. You might think this would be on something like a ServiceEntry resource that obviously manipulates the Service Registry. However, DestinationRule settings can be per-subset (as they’re different workload binaries and might need treating differently).