Skip to content
Back to skills

Linkerd

CSecurity

Expert coverage of Linkerd service mesh across all supported versions: linkerd2-proxy (Rust), zero-config mTLS, ServiceProfile, multi-cluster gateway mirroring, post-quantum cryptography, and minimal operational overhead. Use for \"Linkerd\", \"linkerd2-proxy\", \"Linkerd viz\", \"ServiceProfile\", \"Linkerd multi-cluster\", \"Linkerd mTLS\", \"post-quantum mesh\", \"Linkerd install\", \"TrafficSplit\".

  • 4 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 24, 2026
securityrustgobashapifrontendbackendsecurityperformance

Works with

  • cli
  • api

Security analysis

C63/100
  • criticalPipes output to a shell interpreter
  • criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study
  • criticalDownloads and executes remote scripts — classic supply chain attack

Pro scans all 2 files and shows the line behind each finding

Scanned September 24, 2026

npx -y skills add chrishuffman5/domain-expert --skill linkerd --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Linkerd?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Linkerd
[![Security: C — Skills Directory](https://www.skillsdirectory.com/api/skills/chrishuffman5-linkerd/badge)](https://www.skillsdirectory.com/skills/chrishuffman5-linkerd)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: linkerd
description: "Expert coverage of Linkerd service mesh across all supported versions: linkerd2-proxy (Rust), zero-config mTLS, ServiceProfile, multi-cluster gateway mirroring, post-quantum cryptography, and minimal operational overhead. Use for \"Linkerd\", \"linkerd2-proxy\", \"Linkerd viz\", \"ServiceProfile\", \"Linkerd multi-cluster\", \"Linkerd mTLS\", \"post-quantum mesh\", \"Linkerd install\", \"TrafficSplit\"."
license: MIT
---

# Linkerd

This skill covers Linkerd, the original service mesh (CNCF graduated). Linkerd takes an opinionated, minimal approach: zero-config mTLS, ultra-lightweight Rust proxy, and simplicity over feature richness. Covers:

- linkerd2-proxy (Rust micro-proxy, purpose-built for service mesh)
- Zero-config mTLS with automatic certificate rotation
- ServiceProfile for per-route metrics, retries, and timeouts
- Multi-cluster with gateway mirroring
- Post-quantum cryptography (ML-KEM-768, Linkerd 2.19+)
- Linkerd Viz extension (built-in dashboard and metrics)
- SMI TrafficSplit for canary deployments

## How to Approach Tasks

1. **Classify** the request:
   - **Installation** -- Guide through CLI install, CRDs, control plane, extensions
   - **Traffic management** -- ServiceProfile, TrafficSplit, retries, timeouts
   - **Security** -- mTLS verification, certificate management, post-quantum
   - **Observability** -- Linkerd Viz, tap, golden signals, Prometheus integration
   - **Multi-cluster** -- Gateway mirroring, service export

2. **Identify version** -- Key boundaries: 2.14+ (Gateway API), 2.16+ (policy), 2.19+ (post-quantum crypto). If unclear, use latest stable.

3. **Load context** -- Read `references/architecture.md` for deep architectural knowledge.

4. **Analyze** -- Apply Linkerd-specific reasoning. Linkerd is opinionated -- many features that require configuration in Istio are automatic in Linkerd.

5. **Recommend** -- Provide actionable guidance with CLI commands and YAML manifests.

6. **Verify** -- Suggest validation steps (`linkerd check`, `linkerd viz tap`, `linkerd viz edges`).

## Core Architecture

```
Control Plane:
  destination    -- Service discovery, policy distribution to proxies
  identity       -- Certificate authority, mTLS cert issuance and rotation (24h default)
  proxy-injector -- Mutating webhook, injects linkerd2-proxy sidecar

Data Plane:
  linkerd2-proxy (per pod, Rust sidecar)
  - Ultra-lightweight: ~20-30 MB RAM (vs Envoy's 50 MB+)
  - Purpose-built for service mesh (not a general-purpose proxy)
  - HTTP/1.1, HTTP/2, gRPC, WebSocket, TCP
  - Built-in mTLS, retries, timeouts, circuit breaking, L7 metrics
  - Protocol detection (no manual annotation for HTTP)
```

### Why linkerd2-proxy (Rust)

- **Memory**: ~20-30 MB per pod vs Envoy's ~50 MB+ (saves 2-3x memory per pod)
- **Performance**: Lower p99 latency than Envoy (163ms less at 2,000 RPS in independent benchmarks)
- **Security**: Rust memory safety eliminates buffer overflow vulnerabilities
- **Focus**: Built only for service mesh, not a general-purpose proxy. Smaller codebase, smaller attack surface.
- **Control plane memory**: ~200-300 MB vs Istio's 600 MB - 2 GB

## Installation

```bash
# Install CLI
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install | sh

# Pre-flight check
linkerd check --pre

# Install CRDs
linkerd install --crds | kubectl apply -f -

# Install control plane
linkerd install | kubectl apply -f -

# Verify
linkerd check

# Install extensions
linkerd viz install | kubectl apply -f -          # dashboard + metrics
linkerd multicluster install | kubectl apply -f - # multi-cluster
linkerd jaeger install | kubectl apply -f -       # distributed tracing
```

### Sidecar Injection

```bash
# Enable auto-injection for namespace
kubectl annotate namespace production linkerd.io/inject=enabled

# Manual injection
linkerd inject deployment.yaml | kubectl apply -f -

# Verify proxy is running
linkerd check --proxy -n production

# Check meshed pods
linkerd viz stat deployment -n production
```

## mTLS (Zero Configuration)

Linkerd automatically enables mTLS on every TCP connection between meshed workloads. No configuration required.

### How It Works

1. `identity` component issues X.509 certificates to each proxy at startup
2. Certificates use SPIFFE identity format: `spiffe://root.linkerd.cluster.local/ns/production/sa/myapp`
3. Certificates rotate automatically every 24 hours
4. Both client and server proxies verify certificates -- mutual authentication

### Verify mTLS

```bash
# Check mTLS status for all edges in namespace
linkerd viz edges deployment -n production

# Live traffic stream showing mTLS status
linkerd viz tap deployment/myapp -n production

# Output shows TLS=true for encrypted connections
# req id=0:0 proxy=in  src=10.1.2.3:54321 dst=10.1.2.4:8080 tls=true :method=GET :path=/api/health
```

### Certificate Management

```bash
# Check trust anchor expiry
linkerd check --output json | jq '.categories[] | select(.categoryName == "linkerd-identity")'

# Rotate trust anchor (before expiry)
step certificate create root.linkerd.cluster.local ca.crt ca.key --profile root-ca --no-password --not-after=8760h
linkerd upgrade --identity-trust-anchors-file=ca.crt | kubectl apply -f -
```

**Critical**: Trust anchors have a default lifetime of 1 year. Set a calendar reminder to rotate before expiry, or use cert-manager for automatic rotation.

## Post-Quantum Cryptography (Linkerd 2.19+)

Linkerd 2.19 (October 2025) introduced ML-KEM-768 hybrid key exchange for mTLS, making it the first production service mesh with post-quantum cryptography.

### What This Means

- **ML-KEM-768**: NIST-standardized post-quantum Key Encapsulation Mechanism
- **Hybrid key exchange**: Combines ML-KEM-768 with X25519 (classical). If ML-KEM is broken, X25519 still provides security. If X25519 is broken by quantum computers, ML-KEM provides security.
- **Forward secrecy**: Protects against "harvest now, decrypt later" attacks
- **Transparent**: No application changes required. Enabled by default in 2.19+.

### Performance Impact

- Key exchange size increases by ~1 KB per connection
- Negligible CPU overhead for ML-KEM-768 operations
- Connection establishment takes ~0.5ms longer
- Throughput impact: < 1%

## Traffic Management

### ServiceProfile (Per-Route Policies)

```yaml
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
  name: myapp.production.svc.cluster.local
  namespace: production
spec:
  routes:
  - name: GET /api/users
    condition:
      method: GET
      pathRegex: /api/users(/.*)?
    responseClasses:
    - condition:
        status:
          min: 500
          max: 599
      isFailure: true
    timeout: 5s
    isRetryable: true

  - name: POST /api/orders
    condition:
      method: POST
      pathRegex: /api/orders
    timeout: 10s
    isRetryable: false    # POST is not safe to retry

  retryBudget:
    retryRatio: 0.2          # max 20% additional load from retries
    minRetriesPerSecond: 10  # always allow at least 10 retries/s
    ttl: 10s
```

**Retry budget** prevents retry storms. Unlike Istio's per-attempt retries, Linkerd limits total retry traffic as a percentage of original traffic.

### TrafficSplit (Canary Deployments)

```yaml
# SMI TrafficSplit for canary
apiVersion: split.smi-spec.io/v1alpha1
kind: TrafficSplit
metadata:
  name: myapp-canary
  namespace: production
spec:
  service: myapp              # root service (clients connect to this)
  backends:
  - service: myapp-stable     # stable version
    weight: 90
  - service: myapp-canary     # canary version
    weight: 10
```

**How it works**: The root service (`myapp`) becomes a virtual service. Linkerd's proxy routes traffic to the backend services based on weights. Both backend services must have the same pods labels and ports.

### Gateway API (Linkerd 2.14+)

```yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: myapp-route
  namespace: production
spec:
  parentRefs:
  - name: myapp
    kind: Service
    group: ""
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /api
    backendRefs:
    - name: myapp-v1
      port: 8080
      weight: 90
    - name: myapp-v2
      port: 8080
      weight: 10
```

### Authorization Policy (Linkerd 2.16+)

```yaml
# Server: define what the service accepts
apiVersion: policy.linkerd.io/v1beta3
kind: Server
metadata:
  name: myapp-http
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: myapp
  port: 8080
  proxyProtocol: HTTP/1

---
# AuthorizationPolicy: who can call the server
apiVersion: policy.linkerd.io/v1alpha1
kind: AuthorizationPolicy
metadata:
  name: allow-frontend
  namespace: production
spec:
  targetRef:
    group: policy.linkerd.io
    kind: Server
    name: myapp-http
  requiredAuthenticationRefs:
  - name: frontend-mtls
    kind: MeshTLSAuthentication
    group: policy.linkerd.io

---
# MeshTLSAuthentication: identity of allowed callers
apiVersion: policy.linkerd.io/v1alpha1
kind: MeshTLSAuthentication
metadata:
  name: frontend-mtls
  namespace: production
spec:
  identities:
  - "*.production.serviceaccount.identity.linkerd.cluster.local"
```

## Observability

### Linkerd Viz Dashboard

```bash
# Open dashboard
linkerd viz dashboard

# CLI-based golden signals
linkerd viz stat deployment -n production
# NAME       MESHED   SUCCESS   RPS   LATENCY_P50   LATENCY_P95   LATENCY_P99
# frontend   1/1      100.00%   50    5ms           15ms          25ms
# api        1/1      99.80%    150   3ms           12ms          45ms
# db         1/1      99.99%    200   1ms           5ms           10ms

# Top endpoints by request volume
linkerd viz top deployment/myapp -n production

# Live request stream (tap)
linkerd viz tap deployment/myapp -n production
# Shows: source, destination, method, path, status, latency, TLS status

# Traffic edges (who talks to whom)
linkerd viz edges deployment -n production
```

### Prometheus Metrics

Linkerd automatically exports golden signal metrics:

| Metric | Description |
|---|---|
| `request_total` | Total requests with labels (direction, tls, status, route) |
| `response_total` | Total responses with status code classification |
| `response_latency_ms` | Response latency histogram |
| `tcp_open_total` | TCP connections opened |
| `tcp_close_total` | TCP connections closed |
| `tcp_open_connections` | Currently open TCP connections |

## Multi-Cluster

```bash
# Install multi-cluster extension on both clusters
linkerd multicluster install | kubectl apply -f -

# Link clusters (run on target cluster)
linkerd multicluster link --context=east --cluster-name=east | \
  kubectl --context=west apply -f -

# Export a service for cross-cluster access
kubectl --context=east annotate svc myapp mirror.linkerd.io/exported=true

# In west cluster, service appears as myapp-east
kubectl --context=west get svc myapp-east
```

### How It Works

- A **gateway** component runs in each cluster (Deployment + LoadBalancer Service)
- Cross-cluster traffic flows through gateways with mTLS
- Services are **mirrored**: `myapp` in east appears as `myapp-east` in west
- Traffic splitting between local and remote via TrafficSplit
- No flat network required -- works across cloud providers

## Common Pitfalls

1. **Trust anchor expiry**: Default 1-year lifetime. If trust anchors expire, all mTLS fails. Set calendar reminders or use cert-manager for auto-rotation.
2. **Protocol detection failure**: If Linkerd cannot detect HTTP, it falls back to TCP (no per-route metrics). Use `config.linkerd.io/opaque-ports` annotation for known-TCP ports.
3. **Retry storms**: Without retry budgets, retries can amplify failures. Always configure `retryBudget` in ServiceProfile.
4. **No JWT authentication**: Unlike Istio, Linkerd does not have built-in JWT validation. Use an API gateway or application-level JWT handling.
5. **ServiceProfile naming**: ServiceProfile name must exactly match the fully qualified service DNS name (`myapp.production.svc.cluster.local`).
6. **Multi-cluster DNS**: Mirrored services use `<service>-<cluster>` naming. Applications must be aware of this naming convention for failover.
7. **No ambient mode**: Linkerd uses sidecar injection only. There is no sidecar-less option like Istio's ambient mode.

## Reference Files

Read these for implementation depth:

- `references/architecture.md` -- linkerd2-proxy, control plane components, mTLS, multi-cluster gateway, post-quantum implementation. Read for architecture and internals questions.

Files in this skill

  • SKILL.md12.3 KB
  • references/architecture.md9.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…