Service Mesh — Istio & Linkerd›02 · Istio architecture

Lesson 02 of 7 · Modules

Istio architecture

How Istio works: istiod as the control plane, Envoy sidecars and how they're injected, ambient mode with per-node ztunnel for L4 and optional waypoint proxies for L7, installing with istioctl or Helm, and the core resources you'll configure.

Advanced
Key wordsIstioistiodEnvoysidecar injectionambient modeztunnelwaypoint proxyHBONEistioctlprofilesGateway APICRDs
Sidecar mode pod A app container + Envoy sidecar pod B app container + Envoy sidecar mTLS, L7 a proxy in every pod: full L7, more resources Ambient mode (Istio) pod A no sidecar pod B no sidecar ztunnel per node: L4 + mTLS ztunnel node B waypoint (L7) shared node proxies; L7 only where needed
Sidecar mode vs ambient mode data planes.

The pieces

                 istiod (control plane)
         config (xDS) │    certificates (SDS)
      ┌───────────────┼──────────────────┐
sidecar mode:   pod [app + Envoy]  ⇄  pod [app + Envoy]
ambient mode:   pod ─► ztunnel (node A) ══HBONE mTLS══► ztunnel (node B) ─► pod
                           └──► waypoint (Envoy, optional L7) ──┘
  • istiod: service discovery, configuration translation and distribution (xDS), certificate authority for workload identities.
  • Envoy: the data-plane proxy (in sidecars, gateways and waypoints).
  • Ingress/egress gateways: Envoy deployments at the mesh edge (Istio's own Gateway resource or Kubernetes Gateway API, which Istio supports and recommends for new setups).

Sidecar mode gives every house its own doorman (an Envoy next to each app). Ambient mode puts one security guard per street (ztunnel per node) who seals and checks every letter, and you only hire a specialist receptionist (waypoint) for buildings that need fancy rules like "send 10% of visitors to the new office". Fewer staff, less cost, but a different set of trade-offs.

Sidecar mode

  • A mutating webhook injects an Envoy sidecar (and init/CNI setup to redirect traffic) into new pods in labelled namespaces (istio-injection=enabled, or a revision label, lesson 07).
  • Every pod gets full L7 features; the cost is a proxy per pod.
  • Watch-outs: startup ordering (app starts before the proxy is ready: use holdApplicationUntilProxyStarts or native sidecar support in recent versions), Jobs that never finish because the sidecar keeps running (native sidecars also help), and resource requests for proxies.

Ambient mode

Generally available since Istio 1.24:

  • ztunnel (a per-node proxy written in Rust) provides mTLS, identity, L4 authorization and telemetry for all ambient pods on its node, using HBONE (HTTP-based overlay) tunnels.
  • Waypoint proxies (Envoy, deployed per namespace or per service with Gateway API) add L7: HTTP routing, retries, L7 authorization.
  • Pods need no restart and no sidecar to join the mesh; you add a namespace with a label.
  • Trade-offs: newer model, some features differ from sidecar mode, and ztunnel is shared per node (its upgrades and failures affect every ambient pod on the node).

Installing

$ istioctl x precheck
$ istioctl install --set profile=default -y        # sidecar mode with an ingress gateway
$ # or: istioctl install --set profile=ambient -y   # istiod + CNI node agent + ztunnel
$ kubectl label namespace shop istio-injection=enabled
$ kubectl -n shop rollout restart deploy
$ istioctl analyze -n shop

Production installs often use the Helm charts (base, istiod, cni, ztunnel, gateway) for GitOps. Pin versions and follow the supported Kubernetes versions table.

Resources you'll use

Resource Purpose
PeerAuthentication mTLS mode (PERMISSIVE/STRICT)
AuthorizationPolicy Allow/deny by identity, namespace, path, method
RequestAuthentication Validate end-user JWTs
VirtualService, DestinationRule Routing, retries, timeouts, subsets, connection pools, outlier detection
Gateway API HTTPRoute Standard routing (required for ambient waypoints)
ServiceEntry Register external services
Sidecar Limit which services each proxy learns about (scale)
Telemetry Metrics, logs, tracing settings

Debugging

$ istioctl proxy-status                       # every proxy SYNCED with istiod?
$ istioctl proxy-config listeners deploy/cart -n shop
$ istioctl proxy-config routes deploy/cart -n shop --name 8080 -o json
$ kubectl logs deploy/cart -n shop -c istio-proxy

Try it: Istio two ways

  1. On a kind cluster, install Istio with the default profile, label a namespace, deploy the Bookinfo sample (from the Istio release), and restart it to inject sidecars.
  2. Run istioctl analyze and istioctl proxy-status; inspect one proxy's routes.
  3. On a second cluster, install the ambient profile, deploy Bookinfo, and label the namespace for ambient: no restarts needed.
  4. Add a waypoint for the namespace and apply an HTTPRoute that sends all traffic to one version of a service.
  5. Compare per-pod containers and node-level resource use between the two clusters.

Going deeper: Istio at scale

  • Use Sidecar resources (or ambient) to limit configuration size; large meshes push a lot of config to every proxy.
  • Separate gateways per team or traffic class; run them as their own Deployments with HPA and PDBs.
  • Keep istiod highly available (replicas, PDB, resources) and monitor xDS push times and errors.

Recap

  • istiod configures proxies (xDS) and issues certificates; traffic flows through Envoy proxies.
  • Sidecar mode: Envoy per pod via injection (restart pods); full L7 everywhere.
  • Ambient mode: per-node ztunnel for L4/mTLS, optional waypoints for L7; no sidecars.
  • Install with istioctl or Helm; configure with PeerAuthentication, AuthorizationPolicy, routing resources/Gateway API; debug with analyze, proxy-status, proxy-config.

This site is a public version of my personal engineering knowledge hub. It intentionally excludes confidential company information and internal operational details.