Linkerd Service Mesh mTLS Configuration Guide - 夜莺博客

Linkerd Service Mesh mTLS Configuration Guide

Linkerd's selling point is that it does one thing extremely well: it gives every pod-to-pod connection in a Kubernetes cluster mutual TLS and L7 telemetry with no application changes. Where Istio offers a large feature matrix, Linkerd stays small, and that is precisely why it is often the easier mesh to operate. This guide installs Linkerd, proves mTLS is actually on, walks through identity and trust anchors, and adds per-route authorization policies.

Why a mesh at all

Without a mesh: per-service TLS config, certificate rotation, retries and
                timeouts implemented in each application
With a mesh:    a sidecar (or ambient node proxy) injects TLS, retries,
                load balancing, golden metrics — transparently

If you need traffic shifting, fault injection and rich routing rules, Istio is the more complete tool (see Istio mTLS and traffic shifting). If what you actually want is encrypted, observable service-to-service traffic with minimal moving parts, Linkerd wins.

Install

# 1. CLI
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install | sh
export PATH=$PATH:$HOME/.linkerd2/bin

# 2. pre-flight
linkerd check --pre

# 3. generate and apply the control plane (CRDs + control plane)
linkerd install --crds | kubectl apply -f -
linkerd install | kubectl apply -f -

# 4. confirm
linkerd check

linkerd check is genuinely useful — it validates trust anchors, clock skew between nodes, and RBAC, which are the three things that silently break mesh identity.

Inject and verify mTLS

kubectl get deploy -n myapp -o yaml | \
  linkerd inject - | kubectl apply -f -

# or annotate the namespace for automatic injection
kubectl annotate ns myapp linkerd.io/inject=enabled --overwrite

# then roll the workloads so the proxy is added
kubectl rollout restart deploy -n myapp
# is it actually encrypted?
linkerd viz edges deployment -n myapp     # look for the "SECURED" column
linkerd viz tap deploy/web -n myapp       # tls=true on each request
linkerd viz stat deploy -n myapp          # success rate, latency, RPS
linkerd identity -n myapp                 # identity issued to each pod

The SECURED column in linkerd viz edges is mTLS proof: if a row says "not secured", traffic is flowing in plaintext between those two workloads, which usually means one side is not injected.

Identity and trust

Issuer:    linkerd-identity issues a short-lived cert (~24 h) to each proxy
Trust anchor: root CA that signs the issuer; must be shared across clusters
Identity format: ..serviceaccount.identity.linkerd.cluster.local
Workload identity: not tied to pod IP, so it survives restarts and reschedules

For production, replace the self-signed issuer with cert-manager or your own CA and rotate the trust anchor ahead of expiry. A trust anchor that expires breaks every encrypted connection simultaneously — it is the single most important date in a Linkerd deployment.

Authorization policy

apiVersion: policy.linkerd.io/v1alpha1
kind: Server
metadata: { name: api, namespace: myapp }
spec:
  podSelector: { matchLabels: { app: api } }
  port: 9000
  proxyProtocol: HTTP/2
---
apiVersion: policy.linkerd.io/v1alpha1
kind: ServerAuthorization
metadata: { name: api-from-web, namespace: myapp }
spec:
  server: { name: api }
  client:
    meshTLS:
      serviceAccounts:
      - { name: web, namespace: myapp }

Once any authorization policy references a port, that port becomes deny-by-default — the classic trap is adding a policy for one caller and locking out the rest of the mesh.

Operations

linkerd viz dashboard &                # local dashboard
linkerd viz top deploy/web             # live request view
linkerd viz routes deploy/web          # per-route success rate
linkerd diagnostics policy -n myapp    # why is a connection denied?
linkerd upgrade | kubectl apply -f -   # control plane upgrade
Pitfall                                Symptom
Injection skipped on one side          traffic "not secured" in edges
Proxy resource limits too low          elevated latency under load
Trust anchor expiry                    all mesh traffic fails at once
Authorization added for one client     everyone else gets 403
Node clock skew                        identity validation failures

Resource sizing is worth a mention: the Linkerd proxy defaults are modest, but under high RPS you need to raise proxy.resources or you will measure your own proxy as the bottleneck. If CNI-level policy is also part of the design, compare with Calico/Cilium/Flannel and Cilium BGP control plane.

FAQ

Q: Do I need to change my application? No. mTLS and metrics are injected by the sidecar; only the authorization policies are new configuration.
Q: Does it work with non-HTTP protocols? Yes — TCP proxying and mTLS apply, though L7 metrics and per-route policy require HTTP/2 or gRPC.
Q: Linkerd or Istio for 20 services? Linkerd, unless you specifically need Istio's routing or its egress gateway model.

原文链接:https://github.com/linkerd/linkerd2