Back to skills
SKILL.md
Linkerd
CSecurityExpert 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
Works with
Security analysis
63/100- Pipes output to a shell interpreter
- Exfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study
- Downloads and executes remote scripts — classic supply chain attack
Pro scans all 2 files and shows the line behind each finding
npx -y skills add chrishuffman5/domain-expert --skill linkerd --agent claude-codeAre you the author of Linkerd?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/chrishuffman5-linkerd)---
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.md
- references/architecture.md
Attribution
Comments
Loading comments…