# Install CLI
brew install linkerd
# Alternative: download the official installer, inspect it, then execute it
tmpdir="$(mktemp -d)"trap'rm -rf "$tmpdir"' EXIT
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install -o "$tmpdir/linkerd-install.sh"
sed -n '1,160p'"$tmpdir/linkerd-install.sh"
sh "$tmpdir/linkerd-install.sh"# Validate cluster
linkerd check --pre
# Install CRDs
linkerd install --crds | kubectl apply -f -
# Install control plane
linkerd install | kubectl apply -f -
# Verify installation
linkerd check
# Install viz extension (optional)
linkerd viz install | kubectl apply -f -
Template 2: Inject Namespace
# Automatic injection for namespaceapiVersion:v1kind:Namespacemetadata:name:my-appannotations:linkerd.io/inject:enabled---# Or inject specific deploymentapiVersion:apps/v1kind:Deploymentmetadata:name:my-appannotations:linkerd.io/inject:enabledspec:template:metadata:annotations:linkerd.io/inject:enabled
Template 3: Service Profile with Retries
apiVersion:linkerd.io/v1alpha2kind:ServiceProfilemetadata:name:my-service.my-namespace.svc.cluster.localnamespace:my-namespacespec:routes:-name:GET/api/userscondition:method:GETpathRegex:/api/usersresponseClasses:-condition:status:min:500max:599isFailure:trueisRetryable:true-name:POST/api/userscondition:method:POSTpathRegex:/api/users# POST not retryable by defaultisRetryable:false-name:GET/api/users/{id}condition:method:GETpathRegex:/api/users/[^/]+timeout:5sisRetryable:trueretryBudget:retryRatio:0.2minRetriesPerSecond:10ttl:10s
# Define the serverapiVersion:policy.linkerd.io/v1beta1kind:Servermetadata:name:my-service-httpnamespace:my-namespacespec:podSelector:matchLabels:app:my-serviceport:httpproxyProtocol:HTTP/1---# Allow traffic from specific clientsapiVersion:policy.linkerd.io/v1beta1kind:ServerAuthorizationmetadata:name:allow-frontendnamespace:my-namespacespec:server:name:my-service-httpclient:meshTLS:serviceAccounts:-name:frontendnamespace:my-namespace---# Allow unauthenticated traffic (e.g., from ingress)apiVersion:policy.linkerd.io/v1beta1kind:ServerAuthorizationmetadata:name:allow-ingressnamespace:my-namespacespec:server:name:my-service-httpclient:unauthenticated:truenetworks:-cidr:10.0.0.0/8
# On each cluster, install with cluster credentials
linkerd multicluster install | kubectl apply -f -
# Link clusters
linkerd multicluster link --cluster-name west \
--api-server-address https://west.example.com:6443 \
| kubectl apply -f -
# Export a service to other clusters
kubectl label svc/my-service mirror.linkerd.io/exported=true# Verify cross-cluster connectivity
linkerd multicluster check
linkerd multicluster gateways
Monitoring Commands
# Live traffic view
linkerd viz top deploy/my-app
# Per-route metrics
linkerd viz routes deploy/my-app
# Check proxy status
linkerd viz stat deploy -n my-namespace
# View service dependencies
linkerd viz edges deploy -n my-namespace
# Dashboard
linkerd viz dashboard
Debugging
# Check injection status
linkerd check --proxy -n my-namespace
# View proxy logs
kubectl logs deploy/my-app -c linkerd-proxy
# Debug identity/TLS
linkerd identity -n my-namespace
# Tap traffic (live)
linkerd viz tap deploy/my-app --to deploy/my-backend
Best Practices
Do's
Enable mTLS everywhere - It's automatic with Linkerd
Use ServiceProfiles - Get per-route metrics and retries
Set retry budgets - Prevent retry storms
Monitor golden metrics - Success rate, latency, throughput
Don'ts
Don't skip check - Always run linkerd check after changes
Don't over-configure - Linkerd defaults are sensible
Don't ignore ServiceProfiles - They unlock advanced features
Don't forget timeouts - Set appropriate values per route