Skip to content

Service mesh

yuriy edited this page Oct 19, 2026 · 1 revision

Service mesh: Istio and Linkerd

Sextant reads the configuration objects of Istio and Linkerd and explains them in plain words: where a request goes, who may call a workload, which mTLS mode applies, whether a pod is in the mesh, and what is misconfigured.

Everything here is read-only. Mesh objects have the usual Edit and Delete actions; nothing else on this page changes the cluster or talks to istiod, a proxy or linkerd-viz. The answers come from the objects you wrote, not from what the proxies currently enforce.

Contents: The sections · Request routing · Who may call this workload? · mTLS · In the mesh or not · Problems · Assumptions and limits

The sections

The Istio and Linkerd sections appear in the sidebar only when the cluster serves their kinds (CRDs installed after you connected show up without reconnecting), and list only the kinds the cluster serves:

Section Entries
Istio Virtual Services, Destination Rules, Gateways, Service Entries, Sidecars, Workload Entries, Peer Authentications, Request Authentications, Authorization Policies, Telemetry, and the Request routing page
Linkerd Service Profiles, Servers, HTTP Routes, Authorization Policies, Server Authorizations, Mesh TLS Authentications, Network Authentications

Each table has columns for what matters in that kind (hosts, gateways and routes of a VirtualService; host, subsets and TLS mode of a DestinationRule; action and rules of an AuthorizationPolicy; mode of a PeerAuthentication…). The details explain each object: routes in the order they are tried ("the first one that matches takes the request"), where a policy applies (a workload, a namespace, the whole mesh, or a Gateway by targetRef), what each mTLS mode means.

A VirtualService's details have Check a request…, which opens Request routing filled in for it. A Linkerd Server's details list the Server Authorizations and Authorization Policies that name it.

Request routing

Istio → Request routing answers "where does this request go?". Enter:

  • URL (http://reviews.shop:9080/api/items) and Method, optionally Headers (x-user: alice, one per line);
  • Sent from: A workload in the mesh (its namespace and labels, for routes that match sourceLabels or sourceNamespace) or An Istio gateway (pick one).

Press Check. The answer goes step by step: the gateway server that accepts the host (for a gateway), the VirtualService that wins (bound to that gateway or to mesh, visible to the caller through exportTo, the most specific host), the first route that matches (with the routes skipped before it and why), and the weighted destinations with their Service or ServiceEntry, DestinationRule, subset and the pods behind them (3 of 3 ready).

Possible answers: Routed, Sent to the service as is (no VirtualService covers the host), Redirected, Answered by the proxy (a direct response), No route: 404, Not served by the gateway: 404, Unknown host, Delegate not found: 404, TCP or TLS routes only, Not evaluated. A missing DestinationRule subset is shown as a problem, because the proxy answers 503.

How Sextant decides where Istio leaves a choice to the implementation, shown as notes under the answer:

  • Regular expressions in routes are RE2 in Envoy; Sextant reads them as JavaScript regular expressions. A route whose expression JavaScript cannot read is Not evaluated, and so are the routes after it.
  • On a gateway, the routes of all VirtualServices for the same host are merged, the oldest first; for sidecars only the oldest VirtualService counts.
  • Sidecar objects (which hosts a workload may see) and TCP/TLS routes are not followed.

Who may call this workload?

The Service mesh section of a Pod or workload has Who may call this workload?. Describe the caller — namespace, service account, method, path, port, caller IP, remote IP behind a proxy — and Sextant goes through the AuthorizationPolicies that apply (the workload's namespace and the root namespace, by selector) the way Istio does: CUSTOM, then DENY, then ALLOW.

The answer is Allowed, Denied, Up to the external authorizer (a CUSTOM policy matches), or Cannot tell, with the rule that decided. Sextant never answers "allowed" when it is not sure:

  • What you leave empty is unknown, and a policy that depends on it is shown as Not evaluated.
  • JWT principals (requestPrincipals), path templates ({*}) and when keys Sextant does not model are not evaluated.
  • A DENY or CUSTOM policy attached by targetRef to a Gateway or waypoint is listed but not evaluated, so it turns "allowed" into Cannot tell.
  • A policy whose action Istio does not accept is rejected by Istio, so the answer is Cannot tell.
  • A policy annotated istio.io/dry-run: "true" is shown with what it would do ("DENY (dry run, not enforced)") and is not counted, as Istio only logs its decisions.

The caller is taken to be in the mesh with mTLS, so its principal is cluster.local/ns/<namespace>/sa/<service account>.

Linkerd's authorization is listed, not evaluated: a Server's details show the authorizations that name it.

mTLS

The Istio mTLS block of a Pod or workload says which mode applies — STRICT, PERMISSIVE or DISABLE — and which PeerAuthentication sets it: the one that selects the workload, else the namespace's, else the mesh-wide one in istio-system, else Istio's default PERMISSIVE. UNSET inherits. Port-level modes are listed per port.

In the mesh or not

The Service mesh section of Pods, Deployments, StatefulSets, DaemonSets and ReplicaSets says:

  • Istio: a sidecar, a native sidecar (an init container), ambient mode (istio.io/dataplane-mode=ambient, ztunnel carries the traffic) or not in the mesh; the revision; whether injection is on and where it is set (sidecar.istio.io/inject on the pod, istio-injection or istio.io/rev on the namespace).
  • Linkerd: whether linkerd-proxy runs, its version and control plane, and linkerd.io/inject on the pod or namespace.
  • Restart needed when injection is on but the running pod has no proxy (it was created before injection was turned on, or the injector failed).

For a workload, the pod template is read as what its pods will get.

When linkerd-viz is installed the section says so; Sextant does not read its success rate, request rate and latency — use linkerd viz stat or the linkerd-viz dashboard.

Problems

The Istio section shows a red counter of configuration problems, Only problems filters Virtual Services and Destination Rules, and the Problems page lists them under Service mesh:

  • a host that no Service or ServiceEntry has;
  • a destination without the DestinationRule its subset needs, or a subset the DestinationRule does not define;
  • a VirtualService bound to a Gateway that does not exist;
  • a DestinationRule TLS mode other than ISTIO_MUTUAL toward a namespace or mesh in STRICT mTLS;
  • two VirtualServices for the same host on the mesh (only the oldest counts), or an older catch-all on a gateway;
  • a VirtualService bound to mesh with host *, which Istio rejects.

Assumptions and limits

  • The cluster domain is taken as cluster.local and Istio's root namespace as istio-system; the mesh configuration (meshConfig) is not read.
  • Hosts are judged missing only in up to 40 namespaces that the Istio objects name.
  • The answers are from objects; an object Istio rejected or has not pushed yet still counts.
  • Linkerd golden metrics and Kiali-style traffic graphs are not part of Sextant.

Clone this wiki locally