Linkerd Service Mesh Stack
Lightweight service mesh with automatic mTLS, traffic splitting, and observability.
Overview
Linkerd is an ultralight service mesh for Kubernetes and containerized applications, originally developed by Buoyant and now a CNCF graduated project. Built with Rust and Go, Linkerd provides automatic mutual TLS encryption, intelligent load balancing, and comprehensive observability for microservices communication without requiring code changes. This stack demonstrates Linkerd's core functionality using the popular Emojivoto demo application along with full observability infrastructure. The combination of Linkerd's control plane, visualization components, Jaeger for distributed tracing, Prometheus for metrics collection, and Grafana for dashboards creates a complete service mesh observability platform. This setup showcases how Linkerd automatically encrypts service-to-service communication, provides traffic metrics, and integrates with cloud-native observability tools. Platform engineers and SREs looking to understand service mesh concepts, evaluate Linkerd's capabilities, or prototype microservices observability solutions will find this stack invaluable for hands-on learning and proof-of-concept deployments.
Key Features
- Automatic mutual TLS encryption between all meshed services without certificate management
- Linkerd's ultralight Rust-based proxy with minimal latency and resource overhead
- Real-time service topology visualization through Linkerd's web dashboard
- Traffic splitting and canary deployment capabilities via Linkerd's traffic policies
- Distributed tracing integration with Jaeger for request flow analysis
- Prometheus metrics collection for Linkerd proxy and application telemetry
- Pre-configured Grafana dashboards for service mesh observability
- Emojivoto demo application demonstrating real microservices mesh behavior
Common Use Cases
- 1Service mesh proof-of-concept for evaluating Linkerd versus Istio or Consul Connect
- 2Microservices security demonstration showing automatic mTLS encryption capabilities
- 3Developer training environment for learning service mesh concepts and observability
- 4CI/CD pipeline testing for applications destined for Linkerd-enabled Kubernetes clusters
- 5Performance benchmarking of service mesh overhead using realistic demo applications
- 6Distributed tracing workshop setup for understanding microservices request flows
- 7Local development environment mimicking production Linkerd mesh behavior
Prerequisites
- Docker Engine 20.10+ with Docker Compose V2 for multi-container orchestration
- Minimum 4GB available RAM for Linkerd components, Prometheus, Grafana, and demo services
- Available ports 3000, 8080-8085, 9090, 9995, 14268, and 16686 for service access
- Basic understanding of service mesh concepts and microservices architecture
- Familiarity with Prometheus metrics and Grafana dashboard navigation
- Knowledge of distributed tracing concepts for effective Jaeger usage
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 # Simulated Linkerd control plane3 linkerd-controller: 4 image: ghcr.io/linkerd/controller:stable-2.14.05 ports: 6 - "8085:8085"7 - "9995:9995"8 networks: 9 - linkerd_net1011 # Linkerd Viz extension12 linkerd-viz: 13 image: ghcr.io/linkerd/metrics-api:stable-2.14.014 ports: 15 - "8084:8084"16 networks: 17 - linkerd_net1819 # Web dashboard20 linkerd-web: 21 image: ghcr.io/linkerd/web:stable-2.14.022 ports: 23 - "8080:8080"24 environment: 25 - LINKERD_CONTROLLER_API_ADDR=linkerd-controller:808526 depends_on: 27 - linkerd-controller28 networks: 29 - linkerd_net3031 # Sample meshed service32 emojivoto-web: 33 image: docker.l5d.io/buoyantio/emojivoto-web:v1134 ports: 35 - "8081:8080"36 networks: 37 - linkerd_net3839 emojivoto-emoji-svc: 40 image: docker.l5d.io/buoyantio/emojivoto-emoji-svc:v1141 networks: 42 - linkerd_net4344 emojivoto-voting-svc: 45 image: docker.l5d.io/buoyantio/emojivoto-voting-svc:v1146 networks: 47 - linkerd_net4849 # Distributed tracing50 jaeger: 51 image: jaegertracing/all-in-one:latest52 ports: 53 - "16686:16686"54 - "14268:14268"55 networks: 56 - linkerd_net5758 prometheus: 59 image: prom/prometheus:latest60 ports: 61 - "9090:9090"62 volumes: 63 - ./prometheus.yml:/etc/prometheus/prometheus.yml64 - prometheus_data:/prometheus65 networks: 66 - linkerd_net6768 grafana: 69 image: grafana/grafana:latest70 ports: 71 - "3000:3000"72 environment: 73 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}74 volumes: 75 - grafana_data:/var/lib/grafana76 networks: 77 - linkerd_net7879volumes: 80 prometheus_data: 81 grafana_data: 8283networks: 84 linkerd_net: .env Template
.env
1# Linkerd Service Mesh2GRAFANA_PASSWORD=secure_grafana_password34# Dashboard at http://localhost:80805# Emojivoto demo at http://localhost:80816# Jaeger at http://localhost:16686Usage Notes
- 1Dashboard at http://localhost:8080
- 2Emojivoto demo at http://localhost:8081
- 3Automatic mTLS between services
- 4Lightweight Rust-based proxy
- 5Demo setup - use Kubernetes for production
Individual Services(9 services)
Copy individual services to mix and match with your existing compose files.
linkerd-controller
linkerd-controller:
image: ghcr.io/linkerd/controller:stable-2.14.0
ports:
- "8085:8085"
- "9995:9995"
networks:
- linkerd_net
linkerd-viz
linkerd-viz:
image: ghcr.io/linkerd/metrics-api:stable-2.14.0
ports:
- "8084:8084"
networks:
- linkerd_net
linkerd-web
linkerd-web:
image: ghcr.io/linkerd/web:stable-2.14.0
ports:
- "8080:8080"
environment:
- LINKERD_CONTROLLER_API_ADDR=linkerd-controller:8085
depends_on:
- linkerd-controller
networks:
- linkerd_net
emojivoto-web
emojivoto-web:
image: docker.l5d.io/buoyantio/emojivoto-web:v11
ports:
- "8081:8080"
networks:
- linkerd_net
emojivoto-emoji-svc
emojivoto-emoji-svc:
image: docker.l5d.io/buoyantio/emojivoto-emoji-svc:v11
networks:
- linkerd_net
emojivoto-voting-svc
emojivoto-voting-svc:
image: docker.l5d.io/buoyantio/emojivoto-voting-svc:v11
networks:
- linkerd_net
jaeger
jaeger:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686"
- "14268:14268"
networks:
- linkerd_net
prometheus
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
networks:
- linkerd_net
grafana
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
volumes:
- grafana_data:/var/lib/grafana
networks:
- linkerd_net
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 # Simulated Linkerd control plane5 linkerd-controller:6 image: ghcr.io/linkerd/controller:stable-2.14.07 ports:8 - "8085:8085"9 - "9995:9995"10 networks:11 - linkerd_net1213 # Linkerd Viz extension14 linkerd-viz:15 image: ghcr.io/linkerd/metrics-api:stable-2.14.016 ports:17 - "8084:8084"18 networks:19 - linkerd_net2021 # Web dashboard22 linkerd-web:23 image: ghcr.io/linkerd/web:stable-2.14.024 ports:25 - "8080:8080"26 environment:27 - LINKERD_CONTROLLER_API_ADDR=linkerd-controller:808528 depends_on:29 - linkerd-controller30 networks:31 - linkerd_net3233 # Sample meshed service34 emojivoto-web:35 image: docker.l5d.io/buoyantio/emojivoto-web:v1136 ports:37 - "8081:8080"38 networks:39 - linkerd_net4041 emojivoto-emoji-svc:42 image: docker.l5d.io/buoyantio/emojivoto-emoji-svc:v1143 networks:44 - linkerd_net4546 emojivoto-voting-svc:47 image: docker.l5d.io/buoyantio/emojivoto-voting-svc:v1148 networks:49 - linkerd_net5051 # Distributed tracing52 jaeger:53 image: jaegertracing/all-in-one:latest54 ports:55 - "16686:16686"56 - "14268:14268"57 networks:58 - linkerd_net5960 prometheus:61 image: prom/prometheus:latest62 ports:63 - "9090:9090"64 volumes:65 - ./prometheus.yml:/etc/prometheus/prometheus.yml66 - prometheus_data:/prometheus67 networks:68 - linkerd_net6970 grafana:71 image: grafana/grafana:latest72 ports:73 - "3000:3000"74 environment:75 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}76 volumes:77 - grafana_data:/var/lib/grafana78 networks:79 - linkerd_net8081volumes:82 prometheus_data:83 grafana_data:8485networks:86 linkerd_net:87EOF8889# 2. Create the .env file90cat > .env << 'EOF'91# Linkerd Service Mesh92GRAFANA_PASSWORD=secure_grafana_password9394# Dashboard at http://localhost:808095# Emojivoto demo at http://localhost:808196# Jaeger at http://localhost:1668697EOF9899# 3. Start the services100docker compose up -d101102# 4. View logs103docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/linkerd-service-mesh/run | bashTroubleshooting
- Linkerd web dashboard shows 'Controller API unavailable': Verify linkerd-controller container is running and port 8085 is accessible
- Emojivoto services not appearing in topology: Check that emojivoto containers are on the linkerd_net network and controllers are healthy
- Prometheus not scraping Linkerd metrics: Ensure prometheus.yml includes Linkerd endpoints and containers can communicate on linkerd_net
- Jaeger traces not appearing: Verify Linkerd proxy trace sampling configuration and Jaeger collector port 14268 connectivity
- Grafana dashboards showing no data: Confirm Prometheus data source configuration and verify Prometheus is successfully scraping targets
- High memory usage: Linkerd proxy and Prometheus can be memory-intensive; allocate at least 4GB total system memory for stable operation
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Components
linkerdvizjaegerprometheusgrafana
Tags
#linkerd#service-mesh#mtls#cncf#rust
Category
DevOps & CI/CDAd Space
Shortcuts: C CopyF FavoriteD Download