9.3 Service Mesh, mTLS & Zero-Trust Service Identity

Key Takeaways

  • A service mesh splits into a data plane of proxies that carry every request and a control plane that configures those proxies from the Kubernetes API.
  • Envoy is the CNCF graduated proxy used as the data plane by Istio and several other meshes; Linkerd is a CNCF graduated mesh with its own lightweight Rust proxy.
  • Automatic mutual TLS gives every workload a cryptographic identity and encrypts service-to-service traffic without changing application code.
  • A mesh enforces layer 7 authorization such as allowing GET on one path while denying POST on another, which standard NetworkPolicy cannot express.
  • Sidecar meshes add a proxy container to every Pod; ambient or node-level modes move that proxy out of the Pod to reduce per-Pod resource cost.
Last updated: August 2026

9.3 Service Mesh, mTLS & Zero-Trust Service Identity

Quick Answer: A service mesh is a dedicated infrastructure layer for service-to-service communication. Its data plane is a fleet of proxies — typically Envoy, a CNCF graduated project — that intercept every request in and out of a workload. Its control plane watches the Kubernetes API and programs those proxies. The result is automatic mutual TLS, L7 traffic control, and uniform telemetry, all without touching application code. "Service mesh" is named explicitly in the CNCF cloud native definition, so KCNA expects you to know what it is and what problem it solves.


1. The Problem a Mesh Solves

Once a monolith becomes forty microservices, every service needs the same non-business capabilities: retries with backoff, timeouts, circuit breaking, mTLS, request tracing, and per-route authorisation. Implementing those in each service means:

  • writing them once per language (Go, Java, Python, Node),
  • upgrading them in lockstep across forty repositories,
  • and accepting that the behaviour will drift anyway.

A mesh moves that logic out of the application and into the platform. The application makes a plain HTTP call to payments; the proxy beside it handles TLS, retries, timeouts, load balancing, and telemetry.


2. Data Plane and Control Plane

┌─────────────────── CONTROL PLANE ───────────────────┐
│  watches the Kubernetes API (Services, Endpoints,    │
│  routing CRDs, policies) and issues workload         │
│  certificates; pushes config to every proxy          │
└──────────────┬──────────────────────┬────────────────┘
               │ config + certs       │
     ┌─────────▼─────────┐  ┌─────────▼─────────┐
     │ Pod: orders       │  │ Pod: payments     │
     │ ┌──────┐ ┌──────┐ │  │ ┌──────┐ ┌──────┐ │
     │ │ app  │─│proxy │─┼──┼─│proxy │─│ app  │ │
     │ └──────┘ └──────┘ │  │ └──────┘ └──────┘ │
     └───────────────────┘  └───────────────────┘
                 └────── mTLS on the wire ──────┘
PlaneJobExamples
Data planeCarries every byte of application traffic; applies routing, retries, timeouts, mTLS, and emits metrics/tracesEnvoy (CNCF graduated), linkerd2-proxy (Rust)
Control planeTranslates intent into proxy configuration; acts as a certificate authorityIstio istiod, Linkerd control plane, Consul, Kuma

The application container is unaware any of it exists. Injection is done by a mutating admission webhook — the mechanism from section 5.3 — which appends the proxy container to the Pod spec at creation time.


3. Mutual TLS and Workload Identity

The headline security feature. In a plain cluster, Pod-to-Pod traffic is unencrypted and a receiving service has no cryptographic proof of who is calling — it sees only an IP address that may belong to a different workload a minute later.

A mesh gives every workload a short-lived X.509 certificate whose identity is derived from its ServiceAccount, and both proxies present certificates on every connection:

  • Encryption in transit for all service-to-service traffic, automatically.
  • Authentication of both ends — the caller is cryptographically identified, not merely IP-inferred.
  • Automatic rotation, typically every 24 hours or less, with no application involvement.
  • Identity-based authorization — policies reference serviceAccount: orders, not a CIDR.

This is what "zero trust" means concretely: the network is assumed hostile, and every request is authenticated and authorised regardless of where it originated. SPIFFE/SPIRE is the CNCF project that standardises this workload-identity format, and meshes commonly emit SPIFFE-compatible identities.

Enforcement modes usually run PERMISSIVE first — accepting both plaintext and mTLS during migration — before switching to STRICT.


4. Layer 7 Traffic Control

Because the proxy parses HTTP and gRPC, it can act on request semantics that layer 3/4 controls cannot see:

CapabilityExample
Weighted traffic splitting95% to v1, 5% to v2 — canary independent of replica counts
Header/identity routingSend requests with x-beta: true to v2
Retries and timeoutsRetry idempotent calls twice with a 2-second per-attempt timeout
Circuit breaking / outlier detectionEject an endpoint returning consecutive 5xx responses
Fault injectionDeliberately inject 500s or 3-second delays to test resilience
L7 authorizationAllow GET /api/orders from serviceAccount: web, deny POST /api/admin from everything

That last row is the crisp distinction from section 7.3: NetworkPolicy operates at L3/L4 and can only allow or deny a port. Method- and path-level authorisation requires a mesh (or a CNI-specific L7 policy such as CiliumNetworkPolicy).


5. Observability for Free

Because every request crosses a proxy, the mesh emits golden signals — request rate, error rate, latency distribution, and saturation — for every service pair, without instrumenting anything. It also propagates trace headers automatically, so a distributed trace shows the full call graph as long as applications forward the incoming headers.

The honest caveat: the mesh can propagate context but cannot create spans inside your application. Meaningful traces still require application-level instrumentation, typically with OpenTelemetry.


6. Sidecar vs Ambient

ModelHow it worksTrade-off
SidecarOne proxy container in every PodStrongest isolation and full L7 features per workload; costs CPU and memory per Pod and adds a container to every restart and upgrade
Ambient / node-levelA shared per-node proxy handles L4 and mTLS; an optional per-namespace L7 proxy is added only where neededMuch lower overhead and no Pod restarts to enrol; weaker per-Pod isolation
eBPF / sidecarlessKernel-level dataplane (Cilium) performs L4 and identity in the kernelLowest overhead; L7 features vary by implementation

Sidecar meshes also historically suffered a lifecycle problem — the proxy could start after the app or die before it finished draining. The restartable sidecar container from section 3.5 (an initContainers entry with restartPolicy: Always) is the Kubernetes-native fix.


7. The Main Implementations

ProjectCNCF statusCharacter
IstioGraduatedThe most feature-complete; Envoy data plane; supports sidecar and ambient modes
LinkerdGraduatedDeliberately minimal; purpose-built Rust micro-proxy; prized for low overhead and simple operation
Cilium Service MeshGraduated (Cilium)eBPF-based, sidecarless; merges CNI and mesh
ConsulHashiCorpMulti-platform, extends beyond Kubernetes to VMs
KumaSandboxEnvoy-based, multi-zone and multi-cluster focus

Do you need one? A mesh is real operational weight: another control plane, another certificate authority, another upgrade cycle, and a new class of failure. For a handful of services, application libraries and NetworkPolicy are usually enough. The mesh earns its cost at scale, under a compliance requirement for encryption in transit, or when progressive delivery needs precise traffic control.

Test Your Knowledge

How does a service mesh normally add its proxy to an application Pod?

A
B
C
D
Test Your Knowledge

Which requirement can a service mesh satisfy that a standard Kubernetes NetworkPolicy cannot?

A
B
C
D
Test Your Knowledge

What does automatic mutual TLS in a service mesh provide beyond encrypting traffic?

A
B
C
D