├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── apps ├── Dockerfile-frontenvoy ├── Dockerfile-service ├── service.py └── start_service.sh ├── assets ├── demo-app-arch.png ├── demo-circuit-breaker.png ├── demo-fault-injection.png ├── demo-httproute-blue-green.png ├── demo-httproute-header-match.png ├── demo-httproute-simple-match.png ├── demo-jaeger-tracing-req-trace.png ├── demo-jaeger-tracing.png ├── demo-timeouts-retries.png ├── demo-zipkin-tracing-req-trace.png ├── demo-zipkin-tracing.png ├── jaeger-ui-servide-blue.png ├── jaeger-ui-servide-green.png ├── jaeger-ui-servide-red.png ├── jaeger-ui.png ├── zipkin-ui-servide-blue.png ├── zipkin-ui-servide-green.png └── zipkin-ui.png ├── circuit-breaker ├── README.md ├── docker-compose.yml ├── front-envoy.yaml ├── service-envoy-circuitbreaker.yaml └── service-envoy.yaml ├── fault-injection ├── README.md ├── docker-compose.yml ├── front-envoy.yaml ├── service-envoy-fault-injection-abort.yaml ├── service-envoy-fault-injection-delay.yaml └── service-envoy.yaml ├── front-proxy └── README.md ├── helpers ├── docker-build-up.sh ├── docker-down-remove.sh ├── docker-down.sh ├── envoyproxy-clusters.sh ├── envoyproxy-config_dump.sh ├── envoyproxy-reset_counters.sh ├── envoyproxy-runtime.sh ├── envoyproxy-stats.sh ├── parallel-requests.sh └── send-requests.sh ├── httproute-blue-green ├── README.md ├── docker-compose.yml ├── front-envoy.yaml └── service-envoy.yaml ├── httproute-header-match ├── README.md ├── docker-compose.yml ├── front-envoy.yaml └── service-envoy.yaml ├── httproute-simple-match ├── README.md ├── docker-compose.yml ├── front-envoy.yaml └── service-envoy.yaml ├── jaeger-tracing ├── README.md ├── docker-compose.yml ├── front-envoy.yaml ├── service-blue-envoy-jaeger.yaml ├── service-green-envoy-jaeger.yaml └── service-red-envoy-jaeger.yaml ├── timeouts-retries ├── README.md ├── docker-compose.yml ├── front-envoy.yaml ├── service-envoy-fault-injection-abort.yaml ├── service-envoy-fault-injection-delay.yaml └── service-envoy.yaml └── zipkin-tracing ├── README.md ├── docker-compose.yml ├── front-envoy.yaml ├── service-blue-envoy-zipkin.yaml ├── service-green-envoy-zipkin.yaml └── service-red-envoy-zipkin.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | /t/* 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG - envoy-proxy-demos 2 | 3 | ## v2.0.0 (envoy api v2 based demo apps) 4 | 5 | Supported Envoy v2 API 6 | 7 | Prominent changes from v1 based demo app are: 8 | 9 | - Changed general port for front proxy from 80 to 8000 10 | - Changed docker compose version from 2 to 3.7 (see [Compose file version 3 reference](https://docs.docker.com/compose/compose-file/)) 11 | - HTTP Connection Manager API Change: 12 | - v1 API: envoy.http_connection_manager in v1 API 13 | - v2 API: [envoy.filters.network.http_connection_manager](https://www.envoyproxy.io/docs/envoy/latest/api-v2/config/filter/network/http_connection_manager/v2/http_connection_manager.proto) 14 | - Tracking config for both Jaeger and Zipkin 15 | - endpoint: /api/v1/spans to /api/v2/spans 16 | - Stopped using `envoy.api.v2.route.RouteMatch.regex`, deprecated option 17 | 18 | ## v1.0.0 (envoy api v1 based demo apps) 19 | 20 | Supported & tested envoy versions: 21 | 22 | - [v1.12.3](https://www.envoyproxy.io/docs/envoy/latest/version_history/v1.12.3) 23 | - [v1.12.0](https://www.envoyproxy.io/docs/envoy/latest/version_history/v1.12.0) 24 | - [v1.9.0](https://www.envoyproxy.io/docs/envoy/latest/version_history/v1.9.0) 25 | - [v1.8.0](https://www.envoyproxy.io/docs/envoy/latest/version_history/v1.8.0) 26 | - [v1.7.0](https://www.envoyproxy.io/docs/envoy/latest/version_history/v1.7.0) 27 | - [v1.6.0](https://www.envoyproxy.io/docs/envoy/latest/version_history/v1.6.0) 28 | 29 | > NOTE: From envoy api [v1.13.0](https://www.envoyproxy.io/docs/envoy/latest/version_history/v1.13.0), v1 envoy api(s) are no longer supported. 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Yoichi Kawasaki 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Envoy Proxy Demos 2 | Set of demos to demonstrate [Envoy Proxy](https://www.envoyproxy.io/) features 3 | 4 | ![](assets/demo-app-arch.png) 5 | 6 | This project is a fork of the [Envoy's example demo sets](https://github.com/envoyproxy/envoy/tree/master/examples) 7 | 8 | ## Pre-requisites 9 | - `docker daemon`: You need to have access to a docker daemon to run the demos 10 | - `cURL` : You need cURL to test the demos 11 | 12 | ## Table of Content 13 | - [HTTP Routing: Simple Match Routing](httproute-simple-match) 14 | - [HTTP Routing: Routing based on Header Condition](httproute-header-match) 15 | - [HTTP Routing: Blue Green Traffic Splitting](httproute-blue-green) 16 | - [Fault Injection](fault-injection) 17 | - [Circuit Breaker](circuit-breaker) 18 | - [Timeouts and Retries (+ Fault Injections)](timeouts-retries) 19 | - [Jaeger Tracing](jaeger-tracing) 20 | - [Zipkin Tracing](zipkin-tracing) 21 | 22 | ## Demo versions and supported envoy versions 23 | - latest: envoy api v2 based demo apps 24 | - [v2.0.0](https://github.com/yokawasa/envoy-proxy-demos/releases/tag/v2.0.0): envoy api v2 based demo apps 25 | - [v1.0.0](https://github.com/yokawasa/envoy-proxy-demos/releases/tag/v1.0.0): envoy api v1 based demo apps 26 | 27 | ## Contributing 28 | 29 | Bug reports and pull requests are welcome on GitHub at https://github.com/yokawasa/envoy-proxy-demos 30 | -------------------------------------------------------------------------------- /apps/Dockerfile-frontenvoy: -------------------------------------------------------------------------------- 1 | FROM envoyproxy/envoy:v1.15.0 2 | 3 | RUN apt-get update && apt-get -q install -y \ 4 | curl 5 | CMD /usr/local/bin/envoy -c /etc/front-envoy.yaml --service-cluster front-proxy 6 | -------------------------------------------------------------------------------- /apps/Dockerfile-service: -------------------------------------------------------------------------------- 1 | FROM envoyproxy/envoy-alpine-dev:latest 2 | 3 | RUN apk update && apk add py3-pip bash curl 4 | RUN python3 --version && pip3 --version 5 | RUN pip3 install -q Flask==0.11.1 requests==2.18.4 6 | RUN mkdir /code 7 | ADD service.py /code 8 | ADD start_service.sh /usr/local/bin/start_service.sh 9 | RUN chmod u+x /usr/local/bin/start_service.sh 10 | ENTRYPOINT /usr/local/bin/start_service.sh 11 | -------------------------------------------------------------------------------- /apps/service.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | from flask import request 3 | import socket 4 | import os 5 | import sys 6 | import requests 7 | 8 | app = Flask(__name__) 9 | 10 | TRACE_HEADERS_TO_PROPAGATE = [ 11 | 'X-Ot-Span-Context', 12 | 'X-Request-Id', 13 | 14 | # Zipkin headers 15 | 'X-B3-TraceId', 16 | 'X-B3-SpanId', 17 | 'X-B3-ParentSpanId', 18 | 'X-B3-Sampled', 19 | 'X-B3-Flags', 20 | 21 | # Jaeger header (for native client) 22 | "uber-trace-id" 23 | ] 24 | 25 | def render_page(): 26 | return ('\n' 27 | 'Hello from {} (hostname: {} resolvedhostname:{})\n\n'.format( 28 | os.environ['SERVICE_NAME'], 29 | os.environ['SERVICE_NAME'], 30 | socket.gethostname(), 31 | socket.gethostbyname(socket.gethostname()))) 32 | 33 | @app.route('/service/') 34 | def service(service_color): 35 | return render_page() 36 | 37 | @app.route('/trace/') 38 | def trace(service_color): 39 | headers = {} 40 | ## For Propagation test ## 41 | # Call service 'green' from service 'blue' 42 | if (os.environ['SERVICE_NAME']) == 'blue': 43 | for header in TRACE_HEADERS_TO_PROPAGATE: 44 | if header in request.headers: 45 | headers[header] = request.headers[header] 46 | ret = requests.get("http://localhost:9000/trace/green", headers=headers) 47 | # Call service 'red' from service 'green' 48 | elif (os.environ['SERVICE_NAME']) == 'green': 49 | for header in TRACE_HEADERS_TO_PROPAGATE: 50 | if header in request.headers: 51 | headers[header] = request.headers[header] 52 | ret = requests.get("http://localhost:9000/trace/red", headers=headers) 53 | return render_page() 54 | 55 | if __name__ == "__main__": 56 | app.run(host='127.0.0.1', port=8080, debug=True) 57 | -------------------------------------------------------------------------------- /apps/start_service.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | python3 /code/service.py & 3 | envoy -c /etc/service-envoy.yaml --service-cluster service${SERVICE_NAME} -------------------------------------------------------------------------------- /assets/demo-app-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/demo-app-arch.png -------------------------------------------------------------------------------- /assets/demo-circuit-breaker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/demo-circuit-breaker.png -------------------------------------------------------------------------------- /assets/demo-fault-injection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/demo-fault-injection.png -------------------------------------------------------------------------------- /assets/demo-httproute-blue-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/demo-httproute-blue-green.png -------------------------------------------------------------------------------- /assets/demo-httproute-header-match.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/demo-httproute-header-match.png -------------------------------------------------------------------------------- /assets/demo-httproute-simple-match.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/demo-httproute-simple-match.png -------------------------------------------------------------------------------- /assets/demo-jaeger-tracing-req-trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/demo-jaeger-tracing-req-trace.png -------------------------------------------------------------------------------- /assets/demo-jaeger-tracing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/demo-jaeger-tracing.png -------------------------------------------------------------------------------- /assets/demo-timeouts-retries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/demo-timeouts-retries.png -------------------------------------------------------------------------------- /assets/demo-zipkin-tracing-req-trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/demo-zipkin-tracing-req-trace.png -------------------------------------------------------------------------------- /assets/demo-zipkin-tracing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/demo-zipkin-tracing.png -------------------------------------------------------------------------------- /assets/jaeger-ui-servide-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/jaeger-ui-servide-blue.png -------------------------------------------------------------------------------- /assets/jaeger-ui-servide-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/jaeger-ui-servide-green.png -------------------------------------------------------------------------------- /assets/jaeger-ui-servide-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/jaeger-ui-servide-red.png -------------------------------------------------------------------------------- /assets/jaeger-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/jaeger-ui.png -------------------------------------------------------------------------------- /assets/zipkin-ui-servide-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/zipkin-ui-servide-blue.png -------------------------------------------------------------------------------- /assets/zipkin-ui-servide-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/zipkin-ui-servide-green.png -------------------------------------------------------------------------------- /assets/zipkin-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yokawasa/envoy-proxy-demos/6aac1443df9d51c9d26b87e19c9c141da2fa470e/assets/zipkin-ui.png -------------------------------------------------------------------------------- /circuit-breaker/README.md: -------------------------------------------------------------------------------- 1 | # Circuit Breaker 2 | 3 | [Circuit Breaking](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/circuit_breaking) lets you configure failure thresholds that ensure safe maximums after which these requests stop. This allows for a more graceful failure, and time to respond to potential issues before they become larger. 4 | 5 | ## Demo Overview 6 | 7 | ![](../assets/demo-circuit-breaker.png) 8 | 9 | - Circuit Breaker is configured in `service_red` such that Circuit Breaker will be triggered with the following conditions: 10 | - Envoy makes more than `max connection#:1` 11 | - Envoy makes more than `max parallel requests#:1` 12 | 13 | Key definition - `clusters` in [service-envoy-circuitbreaker.yaml](service-envoy-circuitbreaker.yaml) 14 | ```yaml 15 | clusters: 16 | - name: local_service 17 | connect_timeout: 0.25s 18 | type: strict_dns 19 | lb_policy: round_robin 20 | circuit_breakers: 21 | thresholds: 22 | max_connections: 1 23 | max_pending_requests: 1 24 | max_requests: 1 25 | hosts: 26 | - socket_address: 27 | address: 127.0.0.1 28 | port_value: 8080 29 | ``` 30 | > For the detail of `circuit_breakers` configuration, see [configuration example](https://www.envoyproxy.io/docs/envoy/latest/configuration/upstream/cluster_manager/cluster_circuit_breakers#config-cluster-manager-cluster-circuit-breakers) and API reference, [cluster.CircuitBreakers](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/cluster/circuit_breaker.proto#envoy-api-msg-cluster-circuitbreakers) 31 | 32 | ## Getting Started 33 | ```sh 34 | git clone https://github.com/yokawasa/envoy-proxy-demos.git 35 | cd envoy-proxy-demos/circuit-breaker 36 | ``` 37 | > [NOTICE] Before you run this demo, make sure that all demo containers in previous demo are stopped! 38 | 39 | ## Run the Demo 40 | 41 | ### Build and Run containers 42 | 43 | ```sh 44 | docker-compose up --build -d 45 | 46 | # check all services are up 47 | docker-compose ps --service 48 | 49 | front-envoy 50 | service_green 51 | service_red 52 | 53 | # List containers 54 | docker-compose ps 55 | Name Command State Ports 56 | ---------------------------------------------------------------------------------------------------------------------------------- 57 | circuit-breaker_front-envoy_1 /usr/bin/dumb-init -- /bin ... Up 10000/tcp, 0.0.0.0:8000->80/tcp, 0.0.0.0:8001->8001/tcp 58 | circuit-breaker_service_green_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 59 | circuit-breaker_service_red_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 60 | ``` 61 | 62 | ### Access and test each services 63 | 64 | Access serivce_blue and check if green background page is displayed. It is expected that nothting special will occur. 65 | 66 | ```sh 67 | curl -s http://localhost:8000/service/green 68 | ``` 69 | 70 | Try paralell access to service_green. It is expected that nothting special will occur. The following helper command allow you to send parallel requests repeatedly (For example, send 5 parallel requests to http://localhost:8000/service/green, each thread make 30 consequent requests). 71 | 72 | ```sh 73 | ../helpers/parallel-requests.sh http://localhost:8000/service/green 5 74 | ``` 75 | 76 | Make at least 5 parallel requests to service_red in order to trigger circit breaker and see a few of requests receive 503 HTTP status code. 77 | 78 | ```sh 79 | ../helpers/parallel-requests.sh http://localhost:8000/service/red 5 80 | ``` 81 | 82 | To make it more conveniently, exclude 200 status code to identify 503 status code easily like this: 83 | 84 | ```sh 85 | ../helpers/parallel-requests.sh http://localhost:8000/service/red 5 | grep -v 200 86 | 87 | Parallel# 1 88 | Sending GET request: http://localhost:8000/service/red 89 | Parallel# 2 90 | Sending GET request: http://localhost:8000/service/red 91 | Sending GET request: http://localhost:8000/service/red 92 | Parallel# 3 93 | Sending GET request: http://localhost:8000/service/red 94 | Sending GET request: http://localhost:8000/service/red 95 | Sending GET request: http://localhost:8000/service/red 96 | Parallel# 4 97 | Sending GET request: http://localhost:8000/service/red 98 | Sending GET request: http://localhost:8000/service/red 99 | Sending GET request: http://localhost:8000/service/red 100 | Sending GET request: http://localhost:8000/service/red 101 | Parallel# 5 102 | Sending GET request: http://localhost:8000/service/red 103 | Sending GET request: http://localhost:8000/service/red 104 | Sending GET request: http://localhost:8000/service/red 105 | Sending GET request: http://localhost:8000/service/red 106 | 503 107 | Sending GET request: http://localhost:8000/service/red 108 | Sending GET request: http://localhost:8000/service/red 109 | Sending GET request: http://localhost:8000/service/red 110 | Sending GET request: http://localhost:8000/service/red 111 | Sending GET request: http://localhost:8000/service/red 112 | 503 113 | Sending GET request: http://localhost:8000/service/red 114 | Sending GET request: http://localhost:8000/service/red 115 | Sending GET request: http://localhost:8000/service/red 116 | Sending GET request: http://localhost:8000/service/red 117 | ``` 118 | 119 | ## Stop & Cleanup 120 | ```sh 121 | docker-compose down --remove-orphans --rmi all 122 | ``` 123 | 124 | --- 125 | [Top](../README.md) 126 | -------------------------------------------------------------------------------- /circuit-breaker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | 4 | front-envoy: 5 | build: 6 | context: ../apps 7 | dockerfile: Dockerfile-frontenvoy 8 | volumes: 9 | - ./front-envoy.yaml:/etc/front-envoy.yaml 10 | networks: 11 | - envoymesh 12 | expose: 13 | # Expose ports 80 (for general traffic) and 8001 (for the admin server) 14 | - "8000" 15 | - "8001" 16 | ports: 17 | # Map the host port 8000 to container port 8000, and the host port 8001 to container port 8001 18 | - "8000:8000" 19 | - "8001:8001" 20 | 21 | service_green: 22 | build: 23 | context: ../apps 24 | dockerfile: Dockerfile-service 25 | volumes: 26 | - ./service-envoy.yaml:/etc/service-envoy.yaml 27 | networks: 28 | envoymesh: 29 | aliases: 30 | - service_green 31 | environment: 32 | - SERVICE_NAME=green 33 | expose: 34 | - "80" 35 | service_red: 36 | build: 37 | context: ../apps 38 | dockerfile: Dockerfile-service 39 | volumes: 40 | - ./service-envoy-circuitbreaker.yaml:/etc/service-envoy.yaml 41 | networks: 42 | envoymesh: 43 | aliases: 44 | - service_red 45 | environment: 46 | - SERVICE_NAME=red 47 | expose: 48 | - "80" 49 | 50 | networks: 51 | envoymesh: {} 52 | -------------------------------------------------------------------------------- /circuit-breaker/front-envoy.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 8000 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | route_config: 15 | name: local_route 16 | virtual_hosts: 17 | - name: backend 18 | domains: 19 | - "*" 20 | routes: 21 | - match: 22 | prefix: "/service/green" 23 | route: 24 | cluster: service_green 25 | - match: 26 | prefix: "/service/red" 27 | route: 28 | cluster: service_red 29 | http_filters: 30 | - name: envoy.filters.http.router 31 | typed_config: {} 32 | clusters: 33 | - name: service_green 34 | connect_timeout: 0.25s 35 | type: strict_dns 36 | lb_policy: round_robin 37 | http2_protocol_options: {} 38 | load_assignment: 39 | cluster_name: service_green 40 | endpoints: 41 | - lb_endpoints: 42 | - endpoint: 43 | address: 44 | socket_address: 45 | address: service_green 46 | port_value: 80 47 | - name: service_red 48 | connect_timeout: 0.25s 49 | type: strict_dns 50 | lb_policy: round_robin 51 | http2_protocol_options: {} 52 | load_assignment: 53 | cluster_name: service_red 54 | endpoints: 55 | - lb_endpoints: 56 | - endpoint: 57 | address: 58 | socket_address: 59 | address: service_red 60 | port_value: 80 61 | admin: 62 | access_log_path: "/dev/null" 63 | address: 64 | socket_address: 65 | address: 0.0.0.0 66 | port_value: 8001 67 | layered_runtime: 68 | layers: 69 | - name: static_layer_0 70 | static_layer: 71 | envoy: 72 | resource_limits: 73 | listener: 74 | example_listener_name: 75 | connection_limit: 10000 76 | -------------------------------------------------------------------------------- /circuit-breaker/service-envoy-circuitbreaker.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | route_config: 15 | name: local_route 16 | virtual_hosts: 17 | - name: service 18 | domains: 19 | - "*" 20 | routes: 21 | - match: 22 | prefix: "/service" 23 | route: 24 | cluster: local_service 25 | http_filters: 26 | - name: envoy.router 27 | config: {} 28 | clusters: 29 | - name: local_service 30 | connect_timeout: 0.25s 31 | type: strict_dns 32 | lb_policy: round_robin 33 | circuit_breakers: 34 | thresholds: 35 | max_connections: 1 36 | max_pending_requests: 1 37 | max_requests: 1 38 | hosts: 39 | - socket_address: 40 | address: 127.0.0.1 41 | port_value: 8080 42 | admin: 43 | access_log_path: "/dev/null" 44 | address: 45 | socket_address: 46 | address: 0.0.0.0 47 | port_value: 8081 48 | -------------------------------------------------------------------------------- /circuit-breaker/service-envoy.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | route_config: 15 | name: local_route 16 | virtual_hosts: 17 | - name: service 18 | domains: 19 | - "*" 20 | routes: 21 | - match: 22 | prefix: "/service" 23 | route: 24 | cluster: local_service 25 | http_filters: 26 | - name: envoy.filters.http.router 27 | typed_config: {} 28 | clusters: 29 | - name: local_service 30 | connect_timeout: 0.25s 31 | type: strict_dns 32 | lb_policy: round_robin 33 | load_assignment: 34 | cluster_name: local_service 35 | endpoints: 36 | - lb_endpoints: 37 | - endpoint: 38 | address: 39 | socket_address: 40 | address: 127.0.0.1 41 | port_value: 8080 42 | admin: 43 | access_log_path: "/dev/null" 44 | address: 45 | socket_address: 46 | address: 0.0.0.0 47 | port_value: 8081 48 | -------------------------------------------------------------------------------- /fault-injection/README.md: -------------------------------------------------------------------------------- 1 | # Fault Injection 2 | 3 | [Fault injection](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/fault_filter) is a technique for improving the coverage of a test by introducing faults to test code paths, in particular error handling code paths, that might otherwise rarely be followed. The `filter` ( [http_filters](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/http_filters) in the demo ) can be used to inject `delays` and `abort` requests with user-specified error codes. 4 | 5 | ## Demo Overview 6 | 7 | ![](../assets/demo-fault-injection.png) 8 | 9 | Front-proxy configurations are the same as the ones in [HTTP Routing: Simple Match Routing](../httproute-simple-match). Differences from [HTTP Routing: Simple Match Routing](../httproute-simple-match) are the following 2 fault injections: 10 | - Fault injection `abort` (50% of requests will be aborted with 503 error code) for the requests to `service_red` 11 | - Fault injection `delay` (50% of requests will be 10 seconds delayed) for the requests to `service_blue` 12 | 13 | Key definition 1 - `http_filters` in [service-envoy-fault-injection-abort.yaml](service-envoy-fault-injection-abort.yaml) 14 | ```yaml 15 | http_filters: 16 | - name: envoy.filters.http.fault 17 | typed_config: 18 | "@type": type.googleapis.com/envoy.config.filter.http.fault.v2.HTTPFault 19 | abort: 20 | http_status: 503 21 | percentage: 22 | numerator: 50 23 | denominator: HUNDRED 24 | ``` 25 | > For `numerator` and `denominator` of `percentage`, see [type.FractionalPercent](https://www.envoyproxy.io/docs/envoy/latest/api-v2/type/percent.proto#envoy-api-msg-type-fractionalpercent) 26 | 27 | Key definition 2 - `http_filters` in [service-envoy-fault-injection-delay.yaml](service-envoy-fault-injection-delay.yaml) 28 | ```yaml 29 | http_filters: 30 | - name: envoy.filters.http.fault 31 | typed_config: 32 | "@type": type.googleapis.com/envoy.config.filter.http.fault.v2.HTTPFault 33 | delay: 34 | fixed_delay: 10s 35 | percentage: 36 | numerator: 50 37 | denominator: HUNDRED 38 | ``` 39 | > For `fixed_delay` and `percentage` of delay injection, see [config.filter.fault.v2.FaultDelay](https://www.envoyproxy.io/docs/envoy/latest/api-v2/config/filter/fault/v2/fault.proto#envoy-api-msg-config-filter-fault-v2-faultdelay) 40 | 41 | ## Getting Started 42 | ```sh 43 | git clone https://github.com/yokawasa/envoy-proxy-demos.git 44 | cd envoy-proxy-demos/fault-injection 45 | ``` 46 | 47 | > [NOTICE] Before you run this demo, make sure that all demo containers in previous demo are stopped! 48 | 49 | ## Run the Demo 50 | 51 | ### Build and Run containers using docker-compose 52 | 53 | ```sh 54 | docker-compose up --build -d 55 | 56 | # check all services are up 57 | docker-compose ps --service 58 | 59 | front-envoy 60 | service_blue 61 | service_green 62 | service_red 63 | 64 | # List containers 65 | docker-compose ps 66 | 67 | Name Command State Ports 68 | ---------------------------------------------------------------------------------------------------------------------------------- 69 | fault-injection_front-envoy_1 /docker-entrypoint.sh /bin ... Up 10000/tcp, 0.0.0.0:8000->8000/tcp, 0.0.0.0:8001->8001/tcp 70 | fault-injection_service_blue_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 71 | fault-injection_service_green_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 72 | fault-injection_service_red_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 73 | ``` 74 | 75 | ### Access and test each services 76 | Access serivce_blue and check if 50% of requests to service_blue are 10 seconds delayed. The following helper command allow you to send requests repeatedly (For example, send 10 requests to http://localhost:8000/service/blue). 77 | 78 | ```sh 79 | ../helpers/send-requests.sh http://localhost:8000/service/blue 10 80 | 81 | Sending GET request: http://localhost:8000/service/blue 82 | 200 83 | Sending GET request: http://localhost:8000/service/blue 84 | 200 85 | .. 86 | ``` 87 | 88 | Access serivce_red and check if 50% of requests to service_red are aborted with 503 HTTP status code. The following helper command allow you to send requests repeatedly (For example, send 10 requests to http://localhost:8000/service/red). 89 | 90 | ```sh 91 | ../helpers/send-requests.sh http://localhost:8000/service/red 10 92 | 93 | Sending GET request: http://localhost:8000/service/red 94 | 503 95 | Sending GET request: http://localhost:8000/service/red 96 | 200 97 | Sending GET request: http://localhost:8000/service/red 98 | 503 99 | ``` 100 | 101 | ## Stop & Cleanup 102 | 103 | ```sh 104 | docker-compose down --remove-orphans --rmi all 105 | ``` 106 | 107 | --- 108 | [Top](../README.md) 109 | -------------------------------------------------------------------------------- /fault-injection/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | 4 | front-envoy: 5 | build: 6 | context: ../apps 7 | dockerfile: Dockerfile-frontenvoy 8 | volumes: 9 | - ./front-envoy.yaml:/etc/front-envoy.yaml 10 | networks: 11 | - envoymesh 12 | expose: 13 | # Expose ports 8000 (for general traffic) and 8001 (for the admin server) 14 | - "8000" 15 | - "8001" 16 | ports: 17 | # Map the host port 8000 to container port 8000, and the host port 8001 to container port 8001 18 | - "8000:8000" 19 | - "8001:8001" 20 | 21 | service_blue: 22 | build: 23 | context: ../apps 24 | dockerfile: Dockerfile-service 25 | volumes: 26 | - ./service-envoy-fault-injection-delay.yaml:/etc/service-envoy.yaml 27 | networks: 28 | envoymesh: 29 | aliases: 30 | - service_blue 31 | environment: 32 | - SERVICE_NAME=blue 33 | expose: 34 | - "80" 35 | service_green: 36 | build: 37 | context: ../apps 38 | dockerfile: Dockerfile-service 39 | volumes: 40 | - ./service-envoy.yaml:/etc/service-envoy.yaml 41 | networks: 42 | envoymesh: 43 | aliases: 44 | - service_green 45 | environment: 46 | - SERVICE_NAME=green 47 | expose: 48 | - "80" 49 | service_red: 50 | build: 51 | context: ../apps 52 | dockerfile: Dockerfile-service 53 | volumes: 54 | - ./service-envoy-fault-injection-abort.yaml:/etc/service-envoy.yaml 55 | networks: 56 | envoymesh: 57 | aliases: 58 | - service_red 59 | environment: 60 | - SERVICE_NAME=red 61 | expose: 62 | - "80" 63 | 64 | networks: 65 | envoymesh: {} 66 | -------------------------------------------------------------------------------- /fault-injection/front-envoy.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 8000 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | route_config: 15 | name: local_route 16 | virtual_hosts: 17 | - name: backend 18 | domains: 19 | - "*" 20 | routes: 21 | - match: 22 | prefix: "/service/blue" 23 | route: 24 | cluster: service_blue 25 | - match: 26 | prefix: "/service/green" 27 | route: 28 | cluster: service_green 29 | - match: 30 | prefix: "/service/red" 31 | route: 32 | cluster: service_red 33 | http_filters: 34 | - name: envoy.filters.http.router 35 | typed_config: {} 36 | clusters: 37 | - name: service_blue 38 | connect_timeout: 0.25s 39 | type: strict_dns 40 | lb_policy: round_robin 41 | http2_protocol_options: {} 42 | load_assignment: 43 | cluster_name: service_blue 44 | endpoints: 45 | - lb_endpoints: 46 | - endpoint: 47 | address: 48 | socket_address: 49 | address: service_blue 50 | port_value: 80 51 | - name: service_green 52 | connect_timeout: 0.25s 53 | type: strict_dns 54 | lb_policy: round_robin 55 | http2_protocol_options: {} 56 | load_assignment: 57 | cluster_name: service_green 58 | endpoints: 59 | - lb_endpoints: 60 | - endpoint: 61 | address: 62 | socket_address: 63 | address: service_green 64 | port_value: 80 65 | - name: service_red 66 | connect_timeout: 0.25s 67 | type: strict_dns 68 | lb_policy: round_robin 69 | http2_protocol_options: {} 70 | load_assignment: 71 | cluster_name: service_red 72 | endpoints: 73 | - lb_endpoints: 74 | - endpoint: 75 | address: 76 | socket_address: 77 | address: service_red 78 | port_value: 80 79 | admin: 80 | access_log_path: "/dev/null" 81 | address: 82 | socket_address: 83 | address: 0.0.0.0 84 | port_value: 8001 85 | layered_runtime: 86 | layers: 87 | - name: static_layer_0 88 | static_layer: 89 | envoy: 90 | resource_limits: 91 | listener: 92 | example_listener_name: 93 | connection_limit: 10000 94 | -------------------------------------------------------------------------------- /fault-injection/service-envoy-fault-injection-abort.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | access_log: 15 | name: envoy.access_loggers.file 16 | typed_config: 17 | "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog 18 | path: /dev/stdout 19 | route_config: 20 | name: local_route 21 | virtual_hosts: 22 | - name: service 23 | domains: 24 | - "*" 25 | routes: 26 | - match: 27 | prefix: "/service" 28 | route: 29 | cluster: local_service 30 | http_filters: 31 | - name: envoy.filters.http.fault 32 | typed_config: 33 | "@type": type.googleapis.com/envoy.config.filter.http.fault.v2.HTTPFault 34 | abort: 35 | http_status: 503 36 | percentage: 37 | numerator: 50 38 | denominator: HUNDRED 39 | - name: envoy.filters.http.router 40 | typed_config: {} 41 | clusters: 42 | - name: local_service 43 | connect_timeout: 0.25s 44 | type: strict_dns 45 | lb_policy: round_robin 46 | load_assignment: 47 | cluster_name: local_service 48 | endpoints: 49 | - lb_endpoints: 50 | - endpoint: 51 | address: 52 | socket_address: 53 | address: 127.0.0.1 54 | port_value: 8080 55 | admin: 56 | access_log_path: /dev/stdout 57 | address: 58 | socket_address: 59 | address: 0.0.0.0 60 | port_value: 8081 61 | #runtime: 62 | # symlink_root: /srv/runtime/current 63 | # subdirectory: envoy 64 | -------------------------------------------------------------------------------- /fault-injection/service-envoy-fault-injection-delay.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | access_log: 15 | name: envoy.access_loggers.file 16 | typed_config: 17 | "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog 18 | path: /dev/stdout 19 | route_config: 20 | name: local_route 21 | virtual_hosts: 22 | - name: service 23 | domains: 24 | - "*" 25 | routes: 26 | - match: 27 | prefix: "/service" 28 | route: 29 | cluster: local_service 30 | http_filters: 31 | - name: envoy.filters.http.fault 32 | typed_config: 33 | "@type": type.googleapis.com/envoy.config.filter.http.fault.v2.HTTPFault 34 | delay: 35 | #type: fixed 36 | fixed_delay: 10s 37 | percentage: 38 | numerator: 50 39 | denominator: HUNDRED 40 | - name: envoy.filters.http.router 41 | typed_config: {} 42 | clusters: 43 | - name: local_service 44 | connect_timeout: 0.25s 45 | type: strict_dns 46 | lb_policy: round_robin 47 | load_assignment: 48 | cluster_name: local_service 49 | endpoints: 50 | - lb_endpoints: 51 | - endpoint: 52 | address: 53 | socket_address: 54 | address: 127.0.0.1 55 | port_value: 8080 56 | admin: 57 | access_log_path: /dev/stdout 58 | address: 59 | socket_address: 60 | address: 0.0.0.0 61 | port_value: 8081 62 | #runtime: 63 | # symlink_root: /srv/runtime/current 64 | # subdirectory: envoy 65 | -------------------------------------------------------------------------------- /fault-injection/service-envoy.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | route_config: 15 | name: local_route 16 | virtual_hosts: 17 | - name: service 18 | domains: 19 | - "*" 20 | routes: 21 | - match: 22 | prefix: "/service" 23 | route: 24 | cluster: local_service 25 | http_filters: 26 | - name: envoy.filters.http.router 27 | typed_config: {} 28 | clusters: 29 | - name: local_service 30 | connect_timeout: 0.25s 31 | type: strict_dns 32 | lb_policy: round_robin 33 | load_assignment: 34 | cluster_name: local_service 35 | endpoints: 36 | - lb_endpoints: 37 | - endpoint: 38 | address: 39 | socket_address: 40 | address: 127.0.0.1 41 | port_value: 8080 42 | admin: 43 | access_log_path: "/dev/null" 44 | address: 45 | socket_address: 46 | address: 0.0.0.0 47 | port_value: 8081 48 | -------------------------------------------------------------------------------- /front-proxy/README.md: -------------------------------------------------------------------------------- 1 | # Envoy Front Proxy Demos 2 | 3 | Sets of Envoy Front Proxy demos 4 | 5 | - [HTTP Routing: Simple Match Routing](../httproute-simple-match) 6 | - [HTTP Routing: Routing based on Header Condition](../httproute-header-match) 7 | - [HTTP Routing: Blue Green Traffic Splitting](../httproute-blue-green) 8 | 9 | --- 10 | [Top](../README.md) -------------------------------------------------------------------------------- /helpers/docker-build-up.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e -x 4 | docker-compose up --build -d 5 | 6 | echo "TEST:" 7 | echo "curl -s -v http://localhost:8000/service/blue" 8 | echo "curl -s -v http://localhost:8000/service/green" 9 | echo "curl -s -v http://localhost:8000/service/red" 10 | -------------------------------------------------------------------------------- /helpers/docker-down-remove.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | docker-compose down --remove-orphans --rmi all 4 | -------------------------------------------------------------------------------- /helpers/docker-down.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | docker-compose down --remove-orphans 4 | -------------------------------------------------------------------------------- /helpers/envoyproxy-clusters.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | curl -s "http://localhost:8001/clusters" 4 | -------------------------------------------------------------------------------- /helpers/envoyproxy-config_dump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | curl -s "http://localhost:8001/config_dump" 4 | -------------------------------------------------------------------------------- /helpers/envoyproxy-reset_counters.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | curl -s "http://localhost:8001/reset_counters" 4 | -------------------------------------------------------------------------------- /helpers/envoyproxy-runtime.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # https://www.envoyproxy.io/docs/envoy/latest/operations/admin#operations-admin-interface-runtime 3 | 4 | curl -s "http://localhost:8001/runtime" 5 | -------------------------------------------------------------------------------- /helpers/envoyproxy-stats.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | curl -s "http://localhost:8001/stats" 4 | -------------------------------------------------------------------------------- /helpers/parallel-requests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cwd=`dirname "$0"` 4 | expr "$0" : "/.*" > /dev/null || cwd=`(cd "${cwd}" && pwd)` 5 | 6 | if [ $# -ne 2 ] 7 | then 8 | echo "USAGE: $0 " 9 | exit 1; 10 | fi 11 | 12 | SEND_REQUESTS_CMD="${cwd}/send-requests.sh" 13 | URL=$1 14 | COUNT=$2 15 | c=1 16 | while [[ ${c} -le ${COUNT} ]]; 17 | do 18 | echo "Parallel# ${c}" 19 | ${SEND_REQUESTS_CMD} ${URL} 30 && echo "Done Parallel# ${c}" & 20 | (( c++ )) 21 | sleep 1 22 | done 23 | 24 | wait 25 | 26 | -------------------------------------------------------------------------------- /helpers/send-requests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $# -ne 2 ] 4 | then 5 | echo "USAGE: $0 " 6 | exit 1; 7 | fi 8 | 9 | URL=$1 10 | COUNT=$2 11 | c=1 12 | while [[ ${c} -le ${COUNT} ]]; 13 | do 14 | echo "Sending GET request: ${URL}" 15 | curl -o /dev/null -w '%{http_code}\n' -s ${URL} 16 | (( c++ )) 17 | sleep 1 18 | done 19 | -------------------------------------------------------------------------------- /httproute-blue-green/README.md: -------------------------------------------------------------------------------- 1 | # HTTP Routing: Blue Green Traffic Splitting 2 | 3 | ## Demo Overview 4 | 5 | ![](../assets/demo-httproute-blue-green.png) 6 | 7 | Key definition 1 - `virtual_hosts` in [front-envoy.yaml](front-envoy.yaml) 8 | ```yaml 9 | virtual_hosts: 10 | - name: backend 11 | domains: 12 | - "*" 13 | routes: 14 | - match: 15 | prefix: "/service/blue" 16 | route: 17 | weighted_clusters: 18 | clusters: 19 | - name: service_green 20 | weight: 10 21 | - name: service_blue 22 | weight: 90 23 | - match: 24 | prefix: "/service/red" 25 | route: 26 | cluster: service_red 27 | ``` 28 | 29 | Key definition 2 - `clusters` in [front-envoy.yaml](front-envoy.yaml) 30 | ```yaml 31 | clusters: 32 | - name: service_blue 33 | connect_timeout: 0.25s 34 | type: strict_dns 35 | lb_policy: round_robin 36 | http2_protocol_options: {} 37 | load_assignment: 38 | cluster_name: service_blue 39 | endpoints: 40 | - lb_endpoints: 41 | - endpoint: 42 | address: 43 | socket_address: 44 | address: service_blue 45 | port_value: 80 46 | - name: service_green 47 | connect_timeout: 0.25s 48 | type: strict_dns 49 | lb_policy: round_robin 50 | http2_protocol_options: {} 51 | load_assignment: 52 | cluster_name: service_green 53 | endpoints: 54 | - lb_endpoints: 55 | - endpoint: 56 | address: 57 | socket_address: 58 | address: service_green 59 | port_value: 80 60 | - name: service_red 61 | connect_timeout: 0.25s 62 | type: strict_dns 63 | lb_policy: round_robin 64 | http2_protocol_options: {} 65 | load_assignment: 66 | cluster_name: service_red 67 | endpoints: 68 | - lb_endpoints: 69 | - endpoint: 70 | address: 71 | socket_address: 72 | address: service_red 73 | port_value: 80 74 | ``` 75 | 76 | ## Getting Started 77 | ```sh 78 | git clone https://github.com/yokawasa/envoy-proxy-demos.git 79 | cd envoy-proxy-demos/httproute-blue-green 80 | ``` 81 | 82 | > [NOTICE] Before you run this demo, make sure that all demo containers in previous demo are stopped! 83 | 84 | ## Run the Demo 85 | 86 | ### Build and Run containers 87 | 88 | ```sh 89 | docker-compose up --build -d 90 | 91 | # check all services are up 92 | docker-compose ps --service 93 | 94 | front-envoy 95 | service_blue 96 | service_green 97 | service_red 98 | 99 | # List containers 100 | docker-compose ps 101 | 102 | Name Command State Ports 103 | --------------------------------------------------------------------------------------------------------------------------------------- 104 | httproute-blue-green_front-envoy_1 /docker-entrypoint.sh /bin ... Up 10000/tcp, 0.0.0.0:8000->8000/tcp, 0.0.0.0:8001->8001/tcp 105 | httproute-blue-green_service_blue_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 106 | httproute-blue-green_service_green_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 107 | httproute-blue-green_service_red_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 108 | ``` 109 | 110 | ### Access each services 111 | 112 | Access serivce_blue and check if blue background page is displayed with 90% possibility and green background page is displayed with 10% possibility 113 | 114 | ```sh 115 | curl -s -v http://localhost:8000/service/blue 116 | ``` 117 | 118 | For example, you can repeat the access to '/service/blue' like this 119 | 120 | ```sh 121 | while true; do curl -s http://localhost:8000/service/blue | grep Hello && sleep 1; done 122 | 123 | Hello from blue (hostname: 7d82da79d3bf resolvedhostname:172.31.0.5) 124 | Hello from green (hostname: 7d82da79d3bf resolvedhostname:172.31.0.5) 125 | Hello from blue (hostname: 7d82da79d3bf resolvedhostname:172.31.0.5) 126 | Hello from blue (hostname: 7d82da79d3bf resolvedhostname:172.31.0.5) 127 | Hello from blue (hostname: 7d82da79d3bf resolvedhostname:172.31.0.5) 128 | Hello from blue (hostname: 7d82da79d3bf resolvedhostname:172.31.0.5) 129 | Hello from blue (hostname: 7d82da79d3bf resolvedhostname:172.31.0.5) 130 | Hello from blue (hostname: 7d82da79d3bf resolvedhostname:172.31.0.5) 131 | Hello from blue (hostname: 7d82da79d3bf resolvedhostname:172.31.0.5) 132 | Hello from blue (hostname: 7d82da79d3bf resolvedhostname:172.31.0.5) 133 | Hello from blue (hostname: 7d82da79d3bf resolvedhostname:172.31.0.5) 134 | Hello from green (hostname: 14de8b900934 resolvedhostname:172.31.0.4) 135 | Hello from blue (hostname: 7d82da79d3bf resolvedhostname:172.31.0.5) 136 | Hello from blue (hostname: 7d82da79d3bf resolvedhostname:172.31.0.5) 137 | ``` 138 | 139 | 140 | Access serivce_red and check if red background page is displayed 141 | ``` 142 | curl -s -v http://localhost:8000/service/red 143 | ``` 144 | 145 | ## Stop & Cleanup 146 | ```sh 147 | $ docker-compose down --remove-orphans --rmi all 148 | ``` 149 | 150 | --- 151 | [Top](../README.md) 152 | -------------------------------------------------------------------------------- /httproute-blue-green/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | 4 | front-envoy: 5 | build: 6 | context: ../apps 7 | dockerfile: Dockerfile-frontenvoy 8 | volumes: 9 | - ./front-envoy.yaml:/etc/front-envoy.yaml 10 | networks: 11 | - envoymesh 12 | expose: 13 | # Expose ports 8000 (for general traffic) and 8001 (for the admin server) 14 | - "8000" 15 | - "8001" 16 | ports: 17 | # Map the host port 8000 to container port 8000, and the host port 8001 to container port 8001 18 | - "8000:8000" 19 | - "8001:8001" 20 | 21 | service_blue: 22 | build: 23 | context: ../apps 24 | dockerfile: Dockerfile-service 25 | volumes: 26 | - ./service-envoy.yaml:/etc/service-envoy.yaml 27 | networks: 28 | envoymesh: 29 | aliases: 30 | - service_blue 31 | environment: 32 | - SERVICE_NAME=blue 33 | expose: 34 | - "80" 35 | service_green: 36 | build: 37 | context: ../apps 38 | dockerfile: Dockerfile-service 39 | volumes: 40 | - ./service-envoy.yaml:/etc/service-envoy.yaml 41 | networks: 42 | envoymesh: 43 | aliases: 44 | - service_green 45 | environment: 46 | - SERVICE_NAME=green 47 | expose: 48 | - "80" 49 | service_red: 50 | build: 51 | context: ../apps 52 | dockerfile: Dockerfile-service 53 | volumes: 54 | - ./service-envoy.yaml:/etc/service-envoy.yaml 55 | networks: 56 | envoymesh: 57 | aliases: 58 | - service_red 59 | environment: 60 | - SERVICE_NAME=red 61 | expose: 62 | - "80" 63 | 64 | networks: 65 | envoymesh: {} 66 | -------------------------------------------------------------------------------- /httproute-blue-green/front-envoy.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 8000 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | route_config: 15 | name: local_route 16 | virtual_hosts: 17 | - name: backend 18 | domains: 19 | - "*" 20 | routes: 21 | - match: 22 | prefix: "/service/blue" 23 | route: 24 | weighted_clusters: 25 | clusters: 26 | - name: service_green 27 | weight: 10 28 | - name: service_blue 29 | weight: 90 30 | - match: 31 | prefix: "/service/red" 32 | route: 33 | cluster: service_red 34 | http_filters: 35 | - name: envoy.filters.http.router 36 | typed_config: {} 37 | clusters: 38 | - name: service_blue 39 | connect_timeout: 0.25s 40 | type: strict_dns 41 | lb_policy: round_robin 42 | http2_protocol_options: {} 43 | load_assignment: 44 | cluster_name: service_blue 45 | endpoints: 46 | - lb_endpoints: 47 | - endpoint: 48 | address: 49 | socket_address: 50 | address: service_blue 51 | port_value: 80 52 | - name: service_green 53 | connect_timeout: 0.25s 54 | type: strict_dns 55 | lb_policy: round_robin 56 | http2_protocol_options: {} 57 | load_assignment: 58 | cluster_name: service_green 59 | endpoints: 60 | - lb_endpoints: 61 | - endpoint: 62 | address: 63 | socket_address: 64 | address: service_green 65 | port_value: 80 66 | - name: service_red 67 | connect_timeout: 0.25s 68 | type: strict_dns 69 | lb_policy: round_robin 70 | http2_protocol_options: {} 71 | load_assignment: 72 | cluster_name: service_red 73 | endpoints: 74 | - lb_endpoints: 75 | - endpoint: 76 | address: 77 | socket_address: 78 | address: service_red 79 | port_value: 80 80 | admin: 81 | access_log_path: "/dev/null" 82 | address: 83 | socket_address: 84 | address: 0.0.0.0 85 | port_value: 8001 86 | layered_runtime: 87 | layers: 88 | - name: static_layer_0 89 | static_layer: 90 | envoy: 91 | resource_limits: 92 | listener: 93 | example_listener_name: 94 | connection_limit: 10000 95 | -------------------------------------------------------------------------------- /httproute-blue-green/service-envoy.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | route_config: 15 | name: local_route 16 | virtual_hosts: 17 | - name: service 18 | domains: 19 | - "*" 20 | routes: 21 | - match: 22 | prefix: "/service" 23 | route: 24 | cluster: local_service 25 | http_filters: 26 | - name: envoy.filters.http.router 27 | typed_config: {} 28 | clusters: 29 | - name: local_service 30 | connect_timeout: 0.25s 31 | type: strict_dns 32 | lb_policy: round_robin 33 | load_assignment: 34 | cluster_name: local_service 35 | endpoints: 36 | - lb_endpoints: 37 | - endpoint: 38 | address: 39 | socket_address: 40 | address: 127.0.0.1 41 | port_value: 8080 42 | admin: 43 | access_log_path: "/dev/null" 44 | address: 45 | socket_address: 46 | address: 0.0.0.0 47 | port_value: 8081 48 | -------------------------------------------------------------------------------- /httproute-header-match/README.md: -------------------------------------------------------------------------------- 1 | # HTTP Routing: Routing based on Header Condition 2 | 3 | ## Demo Overview 4 | 5 | ![](../assets/demo-httproute-header-match.png) 6 | 7 | Key definition 1 - `virtual_hosts` in [front-envoy.yaml](front-envoy.yaml) 8 | ```yaml 9 | virtual_hosts: 10 | - name: backend 11 | domains: 12 | - "*" 13 | routes: 14 | - match: 15 | prefix: "/service/blue" 16 | headers: 17 | - name: "x-canary-version" 18 | exact_match: "service_green" 19 | route: 20 | cluster: service_green 21 | - match: 22 | prefix: "/service/blue" 23 | route: 24 | cluster: service_blue 25 | - match: 26 | prefix: "/service/red" 27 | route: 28 | cluster: service_red 29 | ``` 30 | 31 | Key definition 2 - `clusters` in [front-envoy.yaml](front-envoy.yaml) 32 | ```yaml 33 | clusters: 34 | - name: service_blue 35 | connect_timeout: 0.25s 36 | type: strict_dns 37 | lb_policy: round_robin 38 | http2_protocol_options: {} 39 | load_assignment: 40 | cluster_name: service_blue 41 | endpoints: 42 | - lb_endpoints: 43 | - endpoint: 44 | address: 45 | socket_address: 46 | address: service_blue 47 | port_value: 80 48 | - name: service_green 49 | connect_timeout: 0.25s 50 | type: strict_dns 51 | lb_policy: round_robin 52 | http2_protocol_options: {} 53 | load_assignment: 54 | cluster_name: service_green 55 | endpoints: 56 | - lb_endpoints: 57 | - endpoint: 58 | address: 59 | socket_address: 60 | address: service_green 61 | port_value: 80 62 | - name: service_red 63 | connect_timeout: 0.25s 64 | type: strict_dns 65 | lb_policy: round_robin 66 | http2_protocol_options: {} 67 | load_assignment: 68 | cluster_name: service_red 69 | endpoints: 70 | - lb_endpoints: 71 | - endpoint: 72 | address: 73 | socket_address: 74 | address: service_red 75 | port_value: 80 76 | ``` 77 | 78 | ## Getting Started 79 | ```sh 80 | git clone https://github.com/yokawasa/envoy-proxy-demos.git 81 | cd envoy-proxy-demos/httproute-header-match 82 | ``` 83 | 84 | > [NOTICE] Before you run this demo, make sure that all demo containers in previous demo are stopped! 85 | 86 | ## Run the Demo 87 | 88 | ### Build and Run containers 89 | 90 | ```sh 91 | docker-compose up --build -d 92 | 93 | # check all services are up 94 | docker-compose ps --service 95 | 96 | front-envoy 97 | service_blue 98 | service_green 99 | service_red 100 | 101 | # List containers 102 | docker-compose ps 103 | 104 | Name Command State Ports 105 | ----------------------------------------------------------------------------------------------------------------------------------------- 106 | httproute-header-match_front-envoy_1 /docker-entrypoint.sh /bin ... Up 10000/tcp, 0.0.0.0:8000->8000/tcp, 0.0.0.0:8001->8001/tcp 107 | httproute-header-match_service_blue_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 108 | httproute-header-match_service_green_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 109 | httproute-header-match_service_red_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 110 | ``` 111 | 112 | ### Access each services 113 | 114 | Access serivce_blue and check if blue background page is displayed 115 | 116 | ```sh 117 | curl -s -v http://localhost:8000/service/blue 118 | ``` 119 | 120 | Access serivce_blue with Headers `x-canary-version: service_green`and check if green background page (service_green) is displayed 121 | 122 | ```sh 123 | curl -s -H 'x-canary-version: service_green' http://localhost:8000/service/blue 124 | ``` 125 | 126 | Access serivce_red and check if red background page is displayed 127 | 128 | ```sh 129 | curl -s -v http://localhost:8000/service/red 130 | ``` 131 | 132 | ## Stop & Cleanup 133 | 134 | ```sh 135 | docker-compose down --remove-orphans --rmi all 136 | ``` 137 | 138 | --- 139 | [Top](../README.md) 140 | -------------------------------------------------------------------------------- /httproute-header-match/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | 4 | front-envoy: 5 | build: 6 | context: ../apps 7 | dockerfile: Dockerfile-frontenvoy 8 | volumes: 9 | - ./front-envoy.yaml:/etc/front-envoy.yaml 10 | networks: 11 | - envoymesh 12 | expose: 13 | # Expose ports 8000 (for general traffic) and 8001 (for the admin server) 14 | - "8000" 15 | - "8001" 16 | ports: 17 | # Map the host port 8000 to container port 80, and the host port 8001 to container port 8001 18 | - "8000:8000" 19 | - "8001:8001" 20 | 21 | service_blue: 22 | build: 23 | context: ../apps 24 | dockerfile: Dockerfile-service 25 | volumes: 26 | - ./service-envoy.yaml:/etc/service-envoy.yaml 27 | networks: 28 | envoymesh: 29 | aliases: 30 | - service_blue 31 | environment: 32 | - SERVICE_NAME=blue 33 | expose: 34 | - "80" 35 | service_green: 36 | build: 37 | context: ../apps 38 | dockerfile: Dockerfile-service 39 | volumes: 40 | - ./service-envoy.yaml:/etc/service-envoy.yaml 41 | networks: 42 | envoymesh: 43 | aliases: 44 | - service_green 45 | environment: 46 | - SERVICE_NAME=green 47 | expose: 48 | - "80" 49 | service_red: 50 | build: 51 | context: ../apps 52 | dockerfile: Dockerfile-service 53 | volumes: 54 | - ./service-envoy.yaml:/etc/service-envoy.yaml 55 | networks: 56 | envoymesh: 57 | aliases: 58 | - service_red 59 | environment: 60 | - SERVICE_NAME=red 61 | expose: 62 | - "80" 63 | 64 | networks: 65 | envoymesh: {} 66 | -------------------------------------------------------------------------------- /httproute-header-match/front-envoy.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | # Listener configured to listen on port 8000 4 | - address: 5 | socket_address: 6 | address: 0.0.0.0 7 | port_value: 8000 8 | # Listner's filter chain is configured that Envoy to manage HTTP traffic 9 | filter_chains: 10 | - filters: 11 | - name: envoy.filters.network.http_connection_manager 12 | typed_config: 13 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 14 | codec_type: auto 15 | stat_prefix: ingress_http 16 | route_config: 17 | name: local_route 18 | virtual_hosts: 19 | - name: backend 20 | domains: 21 | - "*" 22 | routes: 23 | - match: 24 | prefix: "/service/blue" 25 | headers: 26 | - name: "x-canary-version" 27 | exact_match: "service_green" 28 | route: 29 | cluster: service_green 30 | - match: 31 | prefix: "/service/blue" 32 | route: 33 | cluster: service_blue 34 | - match: 35 | prefix: "/service/red" 36 | route: 37 | cluster: service_red 38 | http_filters: 39 | - name: envoy.filters.http.router 40 | typed_config: {} 41 | clusters: 42 | - name: service_blue 43 | connect_timeout: 0.25s 44 | type: strict_dns 45 | lb_policy: round_robin 46 | http2_protocol_options: {} 47 | load_assignment: 48 | cluster_name: service_blue 49 | endpoints: 50 | - lb_endpoints: 51 | - endpoint: 52 | address: 53 | socket_address: 54 | address: service_blue 55 | port_value: 80 56 | - name: service_green 57 | connect_timeout: 0.25s 58 | type: strict_dns 59 | lb_policy: round_robin 60 | http2_protocol_options: {} 61 | load_assignment: 62 | cluster_name: service_green 63 | endpoints: 64 | - lb_endpoints: 65 | - endpoint: 66 | address: 67 | socket_address: 68 | address: service_green 69 | port_value: 80 70 | - name: service_red 71 | connect_timeout: 0.25s 72 | type: strict_dns 73 | lb_policy: round_robin 74 | http2_protocol_options: {} 75 | load_assignment: 76 | cluster_name: service_red 77 | endpoints: 78 | - lb_endpoints: 79 | - endpoint: 80 | address: 81 | socket_address: 82 | address: service_red 83 | port_value: 80 84 | admin: 85 | access_log_path: "/dev/null" 86 | address: 87 | socket_address: 88 | address: 0.0.0.0 89 | port_value: 8001 90 | layered_runtime: 91 | layers: 92 | - name: static_layer_0 93 | static_layer: 94 | envoy: 95 | resource_limits: 96 | listener: 97 | example_listener_name: 98 | connection_limit: 10000 99 | 100 | -------------------------------------------------------------------------------- /httproute-header-match/service-envoy.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | route_config: 15 | name: local_route 16 | virtual_hosts: 17 | - name: service 18 | domains: 19 | - "*" 20 | routes: 21 | - match: 22 | prefix: "/service" 23 | route: 24 | cluster: local_service 25 | http_filters: 26 | - name: envoy.filters.http.router 27 | typed_config: {} 28 | clusters: 29 | - name: local_service 30 | connect_timeout: 0.25s 31 | type: strict_dns 32 | lb_policy: round_robin 33 | load_assignment: 34 | cluster_name: local_service 35 | endpoints: 36 | - lb_endpoints: 37 | - endpoint: 38 | address: 39 | socket_address: 40 | address: 127.0.0.1 41 | port_value: 8080 42 | admin: 43 | access_log_path: "/dev/null" 44 | address: 45 | socket_address: 46 | address: 0.0.0.0 47 | port_value: 8081 48 | -------------------------------------------------------------------------------- /httproute-simple-match/README.md: -------------------------------------------------------------------------------- 1 | # HTTP Routing: Simple Match Routing 2 | 3 | ## Demo Overview 4 | All traffic is routed by the `front envoy` to the `service containers`. Internally the traffic is routed to the service envoys, then the service envoys route the request to the flask app via the loopback address. In this demo, all traffic is routed to the service envoys like this: 5 | - A request (path `/service/blue` & port `8000`) is routed to `service_blue` 6 | - A request (path `/service/green` & port `8000`) is routed to `service_green` 7 | - A request (path `/service/red` & port `8000`) is routed to `service_red` 8 | 9 | ![](../assets/demo-httproute-simple-match.png) 10 | 11 | Key definition 1 - `virtual_hosts` in [front-envoy.yaml](front-envoy.yaml) 12 | ```yaml 13 | virtual_hosts: 14 | - name: backend 15 | domains: 16 | - "*" 17 | routes: 18 | - match: 19 | prefix: "/service/blue" 20 | route: 21 | cluster: service_green 22 | - match: 23 | prefix: "/service/blue" 24 | route: 25 | cluster: service_blue 26 | - match: 27 | prefix: "/service/red" 28 | route: 29 | cluster: service_red 30 | ``` 31 | 32 | Key definition 2 - `clusters` in [front-envoy.yaml](front-envoy.yaml) 33 | ```yaml 34 | clusters: 35 | - name: service_blue 36 | connect_timeout: 0.25s 37 | type: strict_dns 38 | lb_policy: round_robin 39 | http2_protocol_options: {} 40 | load_assignment: 41 | cluster_name: service_blue 42 | endpoints: 43 | - lb_endpoints: 44 | - endpoint: 45 | address: 46 | socket_address: 47 | address: service_blue 48 | port_value: 80 49 | - name: service_green 50 | connect_timeout: 0.25s 51 | type: strict_dns 52 | lb_policy: round_robin 53 | http2_protocol_options: {} 54 | load_assignment: 55 | cluster_name: service_green 56 | endpoints: 57 | - lb_endpoints: 58 | - endpoint: 59 | address: 60 | socket_address: 61 | address: service_green 62 | port_value: 80 63 | - name: service_red 64 | connect_timeout: 0.25s 65 | type: strict_dns 66 | lb_policy: round_robin 67 | http2_protocol_options: {} 68 | load_assignment: 69 | cluster_name: service_red 70 | endpoints: 71 | - lb_endpoints: 72 | - endpoint: 73 | address: 74 | socket_address: 75 | address: service_red 76 | port_value: 80 77 | ``` 78 | 79 | ## Getting Started 80 | ```sh 81 | git clone https://github.com/yokawasa/envoy-proxy-demos.git 82 | cd envoy-proxy-demos/httproute-simple-match 83 | ``` 84 | 85 | > [NOTICE] Before you run this demo, make sure that all demo containers in previous demo are stopped! 86 | 87 | ## Run the Demo 88 | 89 | ### Build and Run containers 90 | 91 | ```sh 92 | docker-compose up --build -d 93 | 94 | # check all services are up 95 | docker-compose ps --service 96 | 97 | front-envoy 98 | service_blue 99 | service_green 100 | service_red 101 | 102 | # List containers 103 | docker-compose ps 104 | 105 | Name Command State Ports 106 | ----------------------------------------------------------------------------------------------------------------------------------------- 107 | httproute-simple-match_front-envoy_1 /docker-entrypoint.sh /bin ... Up 10000/tcp, 0.0.0.0:8000->8000/tcp, 0.0.0.0:8001->8001/tcp 108 | httproute-simple-match_service_blue_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 109 | httproute-simple-match_service_green_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 110 | httproute-simple-match_service_red_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 111 | ``` 112 | 113 | ### Access each services 114 | 115 | Access serivce_blue and check if blue background page is displayed 116 | 117 | ```sh 118 | open http://localhost:8000/service/blue 119 | # or 120 | curl -s -v http://localhost:8000/service/blue 121 | ``` 122 | 123 | Access serivce_gree and check if gree background page is displayed 124 | 125 | ```sh 126 | open http://localhost:8000/service/green 127 | # or 128 | curl -s -v http://localhost:8000/service/green 129 | ``` 130 | 131 | Access serivce_red and check if red background page is displayed 132 | ```sh 133 | open http://localhost:8000/service/green 134 | # or 135 | curl -s -v http://localhost:8000/service/red 136 | ``` 137 | 138 | ## Stop & Cleanup 139 | 140 | ```sh 141 | docker-compose down --remove-orphans --rmi all 142 | ``` 143 | 144 | --- 145 | [Top](../README.md) 146 | -------------------------------------------------------------------------------- /httproute-simple-match/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | 4 | front-envoy: 5 | build: 6 | context: ../apps 7 | dockerfile: Dockerfile-frontenvoy 8 | volumes: 9 | - ./front-envoy.yaml:/etc/front-envoy.yaml 10 | networks: 11 | - envoymesh 12 | expose: 13 | # Expose ports 8000 (for general traffic) and 8001 (for the admin server) 14 | - "8000" 15 | - "8001" 16 | ports: 17 | - "8000:8000" 18 | - "8001:8001" 19 | 20 | service_blue: 21 | build: 22 | context: ../apps 23 | dockerfile: Dockerfile-service 24 | volumes: 25 | - ./service-envoy.yaml:/etc/service-envoy.yaml 26 | networks: 27 | envoymesh: 28 | aliases: 29 | - service_blue 30 | environment: 31 | - SERVICE_NAME=blue 32 | expose: 33 | - "80" 34 | service_green: 35 | build: 36 | context: ../apps 37 | dockerfile: Dockerfile-service 38 | volumes: 39 | - ./service-envoy.yaml:/etc/service-envoy.yaml 40 | networks: 41 | envoymesh: 42 | aliases: 43 | - service_green 44 | environment: 45 | - SERVICE_NAME=green 46 | expose: 47 | - "80" 48 | service_red: 49 | build: 50 | context: ../apps 51 | dockerfile: Dockerfile-service 52 | volumes: 53 | - ./service-envoy.yaml:/etc/service-envoy.yaml 54 | networks: 55 | envoymesh: 56 | aliases: 57 | - service_red 58 | environment: 59 | - SERVICE_NAME=red 60 | expose: 61 | - "80" 62 | networks: 63 | envoymesh: {} 64 | -------------------------------------------------------------------------------- /httproute-simple-match/front-envoy.yaml: -------------------------------------------------------------------------------- 1 | # The static_resources block contains definitions for clusters and listeners that aren’t dynamically managed 2 | static_resources: 3 | listeners: 4 | # Listener configured to listen on port 8000 5 | - address: 6 | socket_address: 7 | address: 0.0.0.0 8 | port_value: 8000 9 | # Listner's filter chain is configured that Envoy to manage HTTP traffic 10 | filter_chains: 11 | - filters: 12 | - name: envoy.filters.network.http_connection_manager 13 | typed_config: 14 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 15 | codec_type: auto 16 | stat_prefix: ingress_http 17 | route_config: 18 | name: local_route 19 | # Virtual host configures to accept traffic for all domains. 20 | # With Routes, mapping traffic for /service/blue, /service/green, and /service/red to the appropriate clusters. 21 | virtual_hosts: 22 | - name: backend 23 | domains: 24 | - "*" 25 | routes: 26 | - match: 27 | prefix: "/service/blue" 28 | route: 29 | cluster: service_blue 30 | - match: 31 | prefix: "/service/green" 32 | route: 33 | cluster: service_green 34 | - match: 35 | prefix: "/service/red" 36 | route: 37 | cluster: service_red 38 | http_filters: 39 | - name: envoy.filters.http.router 40 | typed_config: {} 41 | # Static Clouster configurations: 42 | # You can configure timeouts, circuit breakers, discovery settings, and more on clusters 43 | # Clusters are composed of endpoints – a set of network locations that can serve requests for the cluster. 44 | # In this example, endpoints are canonically defined in DNS, which Envoy can read from. 45 | # Endpoints can also be defined directly as socket addresses, or read dynamically via the Endpoint Discovery Service. 46 | clusters: 47 | - name: service_blue 48 | connect_timeout: 0.25s 49 | type: strict_dns 50 | lb_policy: round_robin 51 | http2_protocol_options: {} 52 | load_assignment: 53 | cluster_name: service_blue 54 | endpoints: 55 | - lb_endpoints: 56 | - endpoint: 57 | address: 58 | socket_address: 59 | address: service_blue 60 | port_value: 80 61 | - name: service_green 62 | connect_timeout: 0.25s 63 | type: strict_dns 64 | lb_policy: round_robin 65 | http2_protocol_options: {} 66 | load_assignment: 67 | cluster_name: service_green 68 | endpoints: 69 | - lb_endpoints: 70 | - endpoint: 71 | address: 72 | socket_address: 73 | address: service_green 74 | port_value: 80 75 | - name: service_red 76 | connect_timeout: 0.25s 77 | type: strict_dns 78 | lb_policy: round_robin 79 | http2_protocol_options: {} 80 | load_assignment: 81 | cluster_name: service_red 82 | endpoints: 83 | - lb_endpoints: 84 | - endpoint: 85 | address: 86 | socket_address: 87 | address: service_red 88 | port_value: 80 89 | admin: 90 | access_log_path: "/dev/null" 91 | # The address object tells Envoy to create an admin server listening on port 8001. 92 | address: 93 | socket_address: 94 | address: 0.0.0.0 95 | port_value: 8001 96 | layered_runtime: 97 | layers: 98 | - name: static_layer_0 99 | static_layer: 100 | envoy: 101 | resource_limits: 102 | listener: 103 | example_listener_name: 104 | connection_limit: 10000 105 | 106 | -------------------------------------------------------------------------------- /httproute-simple-match/service-envoy.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | route_config: 15 | name: local_route 16 | virtual_hosts: 17 | - name: service 18 | domains: 19 | - "*" 20 | routes: 21 | - match: 22 | prefix: "/service" 23 | route: 24 | cluster: local_service 25 | http_filters: 26 | - name: envoy.filters.http.router 27 | typed_config: {} 28 | clusters: 29 | - name: local_service 30 | connect_timeout: 0.25s 31 | type: strict_dns 32 | lb_policy: round_robin 33 | load_assignment: 34 | cluster_name: local_service 35 | endpoints: 36 | - lb_endpoints: 37 | - endpoint: 38 | address: 39 | socket_address: 40 | address: 127.0.0.1 41 | port_value: 8080 42 | admin: 43 | access_log_path: "/dev/null" 44 | address: 45 | socket_address: 46 | address: 0.0.0.0 47 | port_value: 8081 48 | -------------------------------------------------------------------------------- /jaeger-tracing/README.md: -------------------------------------------------------------------------------- 1 | # Distributed Tracing: Jaeger Tracing 2 | 3 | ## Demo Overview 4 | This is a Jaeger tracing example built based on the [Envoy sandboxes (Jaeger Tracing)](https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/jaeger_tracing) that demonstrates Envoy’s [tracing](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/observability/tracing) capabilities using [Jaeger](https://www.jaegertracing.io/) as the tracing provider. 5 | 6 | All services in the demo support not only `service` endpoint (which is basically the same as [HTTP Routing: Simple Match Routing](../httproute-simple-match/README.md)) but also `trace` endpoint. All traffic is routed from the `front envoy` to the `service containers`. Internally the traffic is routed to the service envoys, then the service envoys route the request to the flask app via the loopback address. All trace data is collected into a `Jaeger` container. 7 | 8 | ![](../assets/demo-jaeger-tracing.png) 9 | 10 | ### Endpoint - trace 11 | In accessing to `trace` endpoint, all traffic is routed to the service envoys with trace header propagations like this: 12 | 13 | - A request (path `/trace/blue` & port `8000`) is routed to `service_blue` 14 | - `service_blue` internally calls `service_green` that then internally calls `service_red` with `trace header propagations` 15 | - A request (path `/trace/green` & port `8000`) is routed to `service_green` 16 | - `service_blue` internally calls `service_red` with `trace header propagations` 17 | - A request (path `/trace/red` & port `8000`) is routed to `service_red` 18 | 19 | ![](../assets/demo-jaeger-tracing-req-trace.png) 20 | 21 | #### Key configuration 1: The HTTP connection manager 22 | All envoys are configured to collect request traces (e.g., [tracing](https://www.envoyproxy.io/docs/envoy/latest/api-v2/config/filter/network/http_connection_manager/v2/http_connection_manager.proto#envoy-api-msg-config-filter-network-http-connection-manager-v2-httpconnectionmanager-tracing) in config.filter.network.http_connection_manager.v2.HttpConnectionManager in front envoy). 23 | ```yaml 24 | static_resources: 25 | listeners: 26 | - address: 27 | socket_address: 28 | address: 0.0.0.0 29 | port_value: 80 30 | traffic_direction: INBOUND 31 | filter_chains: 32 | - filters: 33 | - name: envoy.filters.network.http_connection_manager 34 | typed_config: 35 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 36 | tracing: 37 | provider: 38 | name: envoy.tracers.zipkin 39 | typed_config: 40 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 41 | collector_cluster: jaeger 42 | collector_endpoint: "/api/v2/spans" 43 | shared_span_context: false 44 | collector_endpoint_version: HTTP_JSON 45 | ``` 46 | 47 | > - The HTTP connection manager that handles the request must have the tracing object set. Please refer to [tracing object](https://www.envoyproxy.io/docs/envoy/latest/api-v2/config/filter/network/http_connection_manager/v2/http_connection_manager.proto#envoy-api-msg-config-filter-network-http-connection-manager-v2-httpconnectionmanager-tracing). 48 | > - For the configuration for an HTTP tracer provider used by Envoy, see [config.trace.v2.Tracing.Http](https://www.envoyproxy.io/docs/envoy/latest/api-v2/config/trace/v2/http_tracer.proto#envoy-api-msg-config-trace-v2-tracing-http) 49 | > 50 | 51 | > Presence of the object defines whether the connection manager emits tracing data to the configured tracing provider. You configure `tracing driver` in `name` field. Here are 4 parameter options for `tracing driver` and `envoy.tracers.zipkin` is selected here: 52 | > - envoy.tracers.lightstep 53 | > - envoy.tracers.zipkin 54 | > - envoy.tracers.dynamic_ot 55 | > - envoy.tracers.datadog 56 | > - envoy.tracers.opencensus 57 | > - envoy.tracers.xray 58 | > 59 | > Parameters for Config parts in zipkin deiver are [here](https://www.envoyproxy.io/docs/envoy/latest/api-v2/config/trace/v2/zipkin.proto#envoy-api-msg-config-trace-v2-zipkinconfig) 60 | 61 | #### Key configuration 2: Spans propagation setup (Trace deiver setup) 62 | 63 | All envoys in the demo are also configured to setup to propagate the spans generated by the Jaeger tracer to a Jaeger cluster. 64 | 65 | ```YAML 66 | static_resources: 67 | listeners: 68 | ... 69 | - address: 70 | socket_address: 71 | address: 0.0.0.0 72 | port_value: 9000 73 | traffic_direction: OUTBOUND 74 | filter_chains: 75 | - filters: 76 | - name: envoy.filters.network.http_connection_manager 77 | typed_config: 78 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 79 | tracing: 80 | provider: 81 | name: envoy.tracers.zipkin 82 | typed_config: 83 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 84 | collector_cluster: jaeger 85 | collector_endpoint: "/api/v2/spans" 86 | shared_span_context: false 87 | collector_endpoint_version: HTTP_JSON 88 | ... 89 | clusters: 90 | ... 91 | - name: jaeger 92 | connect_timeout: 1s 93 | type: strict_dns 94 | lb_policy: round_robin 95 | load_assignment: 96 | cluster_name: jaeger 97 | endpoints: 98 | - lb_endpoints: 99 | - endpoint: 100 | address: 101 | socket_address: 102 | address: jaeger 103 | port_value: 9411 104 | ``` 105 | 106 | #### Key configuration 3: Trace header propagation 107 | One of the most important benefits of tracing from Envoy is that it will take care of propagating the traces to the Jaeger service cluster. However, in order to fully take advantage of tracing, the application has to propagate trace headers that Envoy generates. The sample `trace header propagations` setup in servcie application code ([apps/service.py](../apps/service.py)) is this: 108 | 109 | ```python 110 | # ...omit... 111 | 112 | TRACE_HEADERS_TO_PROPAGATE = [ 113 | 'X-Ot-Span-Context', 114 | 'X-Request-Id', 115 | 116 | # Zipkin headers 117 | 'X-B3-TraceId', 118 | 'X-B3-SpanId', 119 | 'X-B3-ParentSpanId', 120 | 'X-B3-Sampled', 121 | 'X-B3-Flags', 122 | 123 | # Jaeger header (for native client) 124 | "uber-trace-id" 125 | ] 126 | 127 | def render_page(): 128 | return ('\n' 129 | 'Hello from {} (hostname: {} resolvedhostname:{})\n\n'.format( 130 | os.environ['SERVICE_NAME'], 131 | os.environ['SERVICE_NAME'], 132 | socket.gethostname(), 133 | socket.gethostbyname(socket.gethostname()))) 134 | 135 | # ...omit... 136 | 137 | @app.route('/trace/') 138 | def trace(service_color): 139 | headers = {} 140 | ## For Propagation test ## 141 | # Call service 'green' from service 'blue' 142 | if (os.environ['SERVICE_NAME']) == 'blue': 143 | for header in TRACE_HEADERS_TO_PROPAGATE: 144 | if header in request.headers: 145 | headers[header] = request.headers[header] 146 | ret = requests.get("http://localhost:9000/trace/green", headers=headers) 147 | # Call service 'red' from service 'green' 148 | elif (os.environ['SERVICE_NAME']) == 'green': 149 | for header in TRACE_HEADERS_TO_PROPAGATE: 150 | if header in request.headers: 151 | headers[header] = request.headers[header] 152 | ret = requests.get("http://localhost:9000/trace/red", headers=headers) 153 | return render_page() 154 | 155 | if __name__ == "__main__": 156 | app.run(host='127.0.0.1', port=8080, debug=True) 157 | ``` 158 | 159 | > **Zipkin tracer** 160 | - When using the `Zipkin tracer`, Envoy relies on the service to propagate the `B3 HTTP headers` ( `x-b3-traceid, x-b3-spanid, x-b3-parentspanid, x-b3-sampled, and x-b3-flags`). The x-b3-sampled header can also be supplied by an external client to either enable or disable tracing for a particular request. In addition, the single b3 header propagation format is supported, which is a more compressed format. Please refer to [B3 Header](https://www.envoyproxy.io/docs/envoy/latest/configuration/http_conn_man/headers#config-http-conn-man-headers-b3) for the detail. 161 | 162 | 163 | ## Getting Started 164 | ```sh 165 | git clone https://github.com/yokawasa/envoy-proxy-demos.git 166 | cd envoy-proxy-demos/jaeger-tracing 167 | ``` 168 | > [NOTICE] Before you run this demo, make sure that all demo containers in previous demo are stopped! 169 | 170 | ## Run the Demo 171 | 172 | ### Build and Run containers 173 | 174 | ```sh 175 | docker-compose up --build -d 176 | 177 | # check all services are up 178 | docker-compose ps --service 179 | 180 | front-envoy 181 | service_blue 182 | service_green 183 | service_red 184 | jaeger 185 | 186 | # List containers 187 | docker-compose ps 188 | 189 | Name Command State Ports 190 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 191 | jaeger-tracing_front-envoy_1 /docker-entrypoint.sh /bin ... Up 10000/tcp, 0.0.0.0:8000->8000/tcp, 0.0.0.0:8001->8001/tcp 192 | jaeger-tracing_jaeger_1 /go/bin/all-in-one-linux - ... Up 14250/tcp, 14268/tcp, 0.0.0.0:16686->16686/tcp, 5775/udp, 5778/tcp, 6831/udp, 6832/udp, 0.0.0.0:9411->9411/tcp 193 | jaeger-tracing_service_blue_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 194 | jaeger-tracing_service_green_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 195 | jaeger-tracing_service_red_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 196 | ``` 197 | 198 | ### Access each services and check tracing results 199 | 200 | Access the following 3 endpoints for tracing test. 201 | ``` 202 | curl -s -v http://localhost:8000/trace/blue 203 | curl -s -v http://localhost:8000/trace/green 204 | curl -s -v http://localhost:8000/trace/red 205 | ``` 206 | 207 | For example, when you access `/trace/blue`, you'll see the following output 208 | ```sh 209 | curl -s -v http://localhost:8000/trace/blue 210 | 211 | * Trying ::1... 212 | * TCP_NODELAY set 213 | * Connected to localhost (::1) port 8000 (#0) 214 | > GET /trace/blue HTTP/1.1 215 | > Host: localhost:8000 216 | > User-Agent: curl/7.54.0 217 | > Accept: */* 218 | > 219 | < HTTP/1.1 200 OK 220 | < content-type: text/html; charset=utf-8 221 | < content-length: 147 222 | < server: envoy 223 | < date: Sun, 17 Feb 2019 16:50:50 GMT 224 | < x-envoy-upstream-service-time: 32 225 | < 226 | 227 | Hello from blue (hostname: 9f71b1513720 resolvedhostname:172.21.0.5) 228 | 229 | * Connection #0 to host localhost left intact 230 | ``` 231 | 232 | Trace data would automatically have been generated and pushed to Jaeger via Envoy. In this part, check the Jaeger UI to see how the Jaeger visualize all the trace data collected. Here is a Jaeger UI url: 233 | 234 | ``` 235 | open http://localhost:16686 236 | ``` 237 | 238 | ![](../assets/jaeger-ui.png) 239 | 240 | You'll come up with Jager UI page like above, then search each traces. Here are example tracing results in Jaeger UI: 241 | 242 | ![](../assets/jaeger-ui-servide-blue.png) 243 | 244 | ![](../assets/jaeger-ui-servide-green.png) 245 | 246 | ![](../assets/jaeger-ui-servide-red.png) 247 | 248 | ## Stop & Cleanup 249 | 250 | ```sh 251 | docker-compose down --remove-orphans --rmi all 252 | ``` 253 | 254 | --- 255 | [Top](../README.md) 256 | -------------------------------------------------------------------------------- /jaeger-tracing/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | 4 | front-envoy: 5 | build: 6 | context: ../apps 7 | dockerfile: Dockerfile-frontenvoy 8 | volumes: 9 | - ./front-envoy.yaml:/etc/front-envoy.yaml 10 | networks: 11 | - envoymesh 12 | expose: 13 | # Expose ports 8000 (for general traffic) and 8001 (for the admin server) 14 | - "8000" 15 | - "8001" 16 | ports: 17 | - "8000:8000" 18 | - "8001:8001" 19 | 20 | service_blue: 21 | build: 22 | context: ../apps 23 | dockerfile: Dockerfile-service 24 | volumes: 25 | - ./service-blue-envoy-jaeger.yaml:/etc/service-envoy.yaml 26 | networks: 27 | envoymesh: 28 | aliases: 29 | - service_blue 30 | environment: 31 | - SERVICE_NAME=blue 32 | expose: 33 | - "80" 34 | service_green: 35 | build: 36 | context: ../apps 37 | dockerfile: Dockerfile-service 38 | volumes: 39 | - ./service-green-envoy-jaeger.yaml:/etc/service-envoy.yaml 40 | networks: 41 | envoymesh: 42 | aliases: 43 | - service_green 44 | environment: 45 | - SERVICE_NAME=green 46 | expose: 47 | - "80" 48 | service_red: 49 | build: 50 | context: ../apps 51 | dockerfile: Dockerfile-service 52 | volumes: 53 | - ./service-red-envoy-jaeger.yaml:/etc/service-envoy.yaml 54 | networks: 55 | envoymesh: 56 | aliases: 57 | - service_red 58 | environment: 59 | - SERVICE_NAME=red 60 | expose: 61 | - "80" 62 | jaeger: 63 | image: jaegertracing/all-in-one 64 | environment: 65 | - COLLECTOR_ZIPKIN_HTTP_PORT=9411 66 | networks: 67 | envoymesh: 68 | aliases: 69 | - jaeger 70 | expose: 71 | - "9411" 72 | - "16686" 73 | ports: 74 | - "9411:9411" 75 | - "16686:16686" 76 | networks: 77 | envoymesh: {} 78 | -------------------------------------------------------------------------------- /jaeger-tracing/front-envoy.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 8000 7 | traffic_direction: OUTBOUND 8 | filter_chains: 9 | - filters: 10 | - name: envoy.filters.network.http_connection_manager 11 | typed_config: 12 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 13 | generate_request_id: true 14 | tracing: 15 | provider: 16 | name: envoy.tracers.zipkin 17 | typed_config: 18 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 19 | collector_cluster: jaeger 20 | collector_endpoint: "/api/v2/spans" 21 | shared_span_context: false 22 | collector_endpoint_version: HTTP_JSON 23 | codec_type: auto 24 | stat_prefix: ingress_http 25 | route_config: 26 | name: local_route 27 | virtual_hosts: 28 | - name: backend 29 | domains: 30 | - "*" 31 | routes: 32 | - match: 33 | prefix: "/service/blue" 34 | route: 35 | cluster: service_blue 36 | - match: 37 | prefix: "/trace/blue" 38 | route: 39 | cluster: service_blue 40 | - match: 41 | prefix: "/service/green" 42 | route: 43 | cluster: service_green 44 | - match: 45 | prefix: "/trace/green" 46 | route: 47 | cluster: service_green 48 | - match: 49 | prefix: "/service/red" 50 | route: 51 | cluster: service_red 52 | - match: 53 | prefix: "/trace/red" 54 | route: 55 | cluster: service_red 56 | http_filters: 57 | - name: envoy.filters.http.router 58 | typed_config: {} 59 | use_remote_address: true 60 | clusters: 61 | - name: service_blue 62 | connect_timeout: 0.25s 63 | type: strict_dns 64 | lb_policy: round_robin 65 | http2_protocol_options: {} 66 | load_assignment: 67 | cluster_name: service_blue 68 | endpoints: 69 | - lb_endpoints: 70 | - endpoint: 71 | address: 72 | socket_address: 73 | address: service_blue 74 | port_value: 80 75 | - name: service_green 76 | connect_timeout: 0.25s 77 | type: strict_dns 78 | lb_policy: round_robin 79 | http2_protocol_options: {} 80 | load_assignment: 81 | cluster_name: service_green 82 | endpoints: 83 | - lb_endpoints: 84 | - endpoint: 85 | address: 86 | socket_address: 87 | address: service_green 88 | port_value: 80 89 | - name: service_red 90 | connect_timeout: 0.25s 91 | type: strict_dns 92 | lb_policy: round_robin 93 | http2_protocol_options: {} 94 | load_assignment: 95 | cluster_name: service_red 96 | endpoints: 97 | - lb_endpoints: 98 | - endpoint: 99 | address: 100 | socket_address: 101 | address: service_red 102 | port_value: 80 103 | - name: jaeger 104 | connect_timeout: 1s 105 | type: strict_dns 106 | lb_policy: round_robin 107 | load_assignment: 108 | cluster_name: jaeger 109 | endpoints: 110 | - lb_endpoints: 111 | - endpoint: 112 | address: 113 | socket_address: 114 | address: jaeger 115 | port_value: 9411 116 | admin: 117 | access_log_path: "/dev/null" 118 | address: 119 | socket_address: 120 | address: 0.0.0.0 121 | port_value: 8001 122 | -------------------------------------------------------------------------------- /jaeger-tracing/service-blue-envoy-jaeger.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | traffic_direction: INBOUND 8 | filter_chains: 9 | - filters: 10 | - name: envoy.filters.network.http_connection_manager 11 | typed_config: 12 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 13 | tracing: 14 | provider: 15 | name: envoy.tracers.zipkin 16 | typed_config: 17 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 18 | collector_cluster: jaeger 19 | collector_endpoint: "/api/v2/spans" 20 | shared_span_context: false 21 | collector_endpoint_version: HTTP_JSON 22 | codec_type: auto 23 | stat_prefix: ingress_http 24 | route_config: 25 | name: local_route 26 | virtual_hosts: 27 | - name: service_blue 28 | domains: 29 | - "*" 30 | routes: 31 | - match: 32 | prefix: "/" 33 | route: 34 | cluster: local_service 35 | decorator: 36 | operation: checkAvailability 37 | http_filters: 38 | - name: envoy.filters.http.router 39 | typed_config: {} 40 | - address: 41 | socket_address: 42 | address: 0.0.0.0 43 | port_value: 9000 44 | traffic_direction: OUTBOUND 45 | filter_chains: 46 | - filters: 47 | - name: envoy.filters.network.http_connection_manager 48 | typed_config: 49 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 50 | tracing: 51 | provider: 52 | name: envoy.tracers.zipkin 53 | typed_config: 54 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 55 | collector_cluster: jaeger 56 | collector_endpoint: "/api/v2/spans" 57 | shared_span_context: false 58 | collector_endpoint_version: HTTP_JSON 59 | codec_type: auto 60 | stat_prefix: egress_http 61 | route_config: 62 | name: service_green_route 63 | virtual_hosts: 64 | - name: service_green 65 | domains: 66 | - "*" 67 | routes: 68 | - match: 69 | prefix: "/trace" 70 | route: 71 | cluster: service_green 72 | decorator: 73 | operation: checkStock 74 | http_filters: 75 | - name: envoy.filters.http.router 76 | typed_config: {} 77 | clusters: 78 | - name: local_service 79 | connect_timeout: 0.250s 80 | type: strict_dns 81 | lb_policy: round_robin 82 | load_assignment: 83 | cluster_name: local_service 84 | endpoints: 85 | - lb_endpoints: 86 | - endpoint: 87 | address: 88 | socket_address: 89 | address: 127.0.0.1 90 | port_value: 8080 91 | - name: service_green 92 | connect_timeout: 0.250s 93 | type: strict_dns 94 | lb_policy: round_robin 95 | http2_protocol_options: {} 96 | load_assignment: 97 | cluster_name: service_green 98 | endpoints: 99 | - lb_endpoints: 100 | - endpoint: 101 | address: 102 | socket_address: 103 | address: service_green 104 | port_value: 80 105 | - name: jaeger 106 | connect_timeout: 1s 107 | type: strict_dns 108 | lb_policy: round_robin 109 | load_assignment: 110 | cluster_name: jaeger 111 | endpoints: 112 | - lb_endpoints: 113 | - endpoint: 114 | address: 115 | socket_address: 116 | address: jaeger 117 | port_value: 9411 118 | admin: 119 | access_log_path: "/dev/null" 120 | address: 121 | socket_address: 122 | address: 0.0.0.0 123 | port_value: 8081 124 | 125 | -------------------------------------------------------------------------------- /jaeger-tracing/service-green-envoy-jaeger.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | tracing: 13 | provider: 14 | name: envoy.tracers.zipkin 15 | typed_config: 16 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 17 | collector_cluster: jaeger 18 | collector_endpoint: "/api/v2/spans" 19 | shared_span_context: false 20 | collector_endpoint_version: HTTP_JSON 21 | codec_type: auto 22 | stat_prefix: ingress_http 23 | route_config: 24 | name: local_route 25 | virtual_hosts: 26 | - name: service_green 27 | domains: 28 | - "*" 29 | routes: 30 | - match: 31 | prefix: "/" 32 | route: 33 | cluster: local_service 34 | decorator: 35 | operation: checkAvailability 36 | http_filters: 37 | - name: envoy.filters.http.router 38 | typed_config: {} 39 | - address: 40 | socket_address: 41 | address: 0.0.0.0 42 | port_value: 9000 43 | traffic_direction: OUTBOUND 44 | filter_chains: 45 | - filters: 46 | - name: envoy.filters.network.http_connection_manager 47 | typed_config: 48 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 49 | tracing: 50 | provider: 51 | name: envoy.tracers.zipkin 52 | typed_config: 53 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 54 | collector_cluster: jaeger 55 | collector_endpoint: "/api/v2/spans" 56 | shared_span_context: false 57 | collector_endpoint_version: HTTP_JSON 58 | codec_type: auto 59 | stat_prefix: egress_http 60 | route_config: 61 | name: service_red_route 62 | virtual_hosts: 63 | - name: service_red 64 | domains: 65 | - "*" 66 | routes: 67 | - match: 68 | prefix: "/trace" 69 | route: 70 | cluster: service_red 71 | decorator: 72 | operation: checkStock 73 | http_filters: 74 | - name: envoy.filters.http.router 75 | typed_config: {} 76 | clusters: 77 | - name: local_service 78 | connect_timeout: 0.25s 79 | type: strict_dns 80 | lb_policy: round_robin 81 | load_assignment: 82 | cluster_name: local_service 83 | endpoints: 84 | - lb_endpoints: 85 | - endpoint: 86 | address: 87 | socket_address: 88 | address: 127.0.0.1 89 | port_value: 8080 90 | - name: service_red 91 | connect_timeout: 0.250s 92 | type: strict_dns 93 | lb_policy: round_robin 94 | http2_protocol_options: {} 95 | load_assignment: 96 | cluster_name: service_red 97 | endpoints: 98 | - lb_endpoints: 99 | - endpoint: 100 | address: 101 | socket_address: 102 | address: service_red 103 | port_value: 80 104 | - name: jaeger 105 | connect_timeout: 1s 106 | type: strict_dns 107 | lb_policy: round_robin 108 | load_assignment: 109 | cluster_name: jaeger 110 | endpoints: 111 | - lb_endpoints: 112 | - endpoint: 113 | address: 114 | socket_address: 115 | address: jaeger 116 | port_value: 9411 117 | admin: 118 | access_log_path: "/dev/null" 119 | address: 120 | socket_address: 121 | address: 0.0.0.0 122 | port_value: 8081 123 | -------------------------------------------------------------------------------- /jaeger-tracing/service-red-envoy-jaeger.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | traffic_direction: INBOUND 8 | filter_chains: 9 | - filters: 10 | - name: envoy.filters.network.http_connection_manager 11 | typed_config: 12 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 13 | tracing: 14 | provider: 15 | name: envoy.tracers.zipkin 16 | typed_config: 17 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 18 | collector_cluster: jaeger 19 | collector_endpoint: "/api/v2/spans" 20 | shared_span_context: false 21 | collector_endpoint_version: HTTP_JSON 22 | codec_type: auto 23 | stat_prefix: ingress_http 24 | route_config: 25 | name: local_route_service 26 | virtual_hosts: 27 | - name: service_red 28 | domains: 29 | - "*" 30 | routes: 31 | - match: 32 | prefix: "/" 33 | route: 34 | cluster: local_service 35 | decorator: 36 | operation: checkAvailability 37 | http_filters: 38 | - name: envoy.filters.http.router 39 | typed_config: {} 40 | clusters: 41 | - name: local_service 42 | connect_timeout: 0.25s 43 | type: strict_dns 44 | lb_policy: round_robin 45 | load_assignment: 46 | cluster_name: local_service 47 | endpoints: 48 | - lb_endpoints: 49 | - endpoint: 50 | address: 51 | socket_address: 52 | address: 127.0.0.1 53 | port_value: 8080 54 | - name: jaeger 55 | connect_timeout: 1s 56 | type: strict_dns 57 | lb_policy: round_robin 58 | load_assignment: 59 | cluster_name: jaeger 60 | endpoints: 61 | - lb_endpoints: 62 | - endpoint: 63 | address: 64 | socket_address: 65 | address: jaeger 66 | port_value: 9411 67 | admin: 68 | access_log_path: "/dev/null" 69 | address: 70 | socket_address: 71 | address: 0.0.0.0 72 | port_value: 8081 73 | -------------------------------------------------------------------------------- /timeouts-retries/README.md: -------------------------------------------------------------------------------- 1 | # Timeouts and Retries 2 | 3 | Envoy allows retries to be configured both in the [route configuration](https://www.envoyproxy.io/docs/envoy/v1.5.0/api-v2/rds.proto#envoy-api-msg-routeaction-retrypolicy) as well as for specific requests via [request headers](https://www.envoyproxy.io/docs/envoy/v1.5.0/configuration/http_filters/router_filter#config-http-filters-router-headers). The demo here shows how to configure request timeouts and retries using the envoy route configuration. 4 | 5 | ## Demo Overview 6 | 7 | ![](../assets/demo-timeouts-retries.png) 8 | 9 | Front proxy configurations in this demo are the same as the ones in [HTTP Routing: Simple Match Routing](../httproute-simple-match) except the following two additional behaviors: 10 | - `Timeouts` (5 seconds) for the request to `service_blue` 11 | - `Retries` that Envoy will attempt to do if `service_red` responds with any 5xx response code 12 | 13 | For Service Containers in the demo, `delay` fault injection and `abort` fault injection are configured in `service_blue` and `service_red` respectively (which are the same configuration as the ones in [Fault Injection Demo](../fault-injection)) 14 | 15 | Key definition - `virtual_hosts` in [front-envoy.yaml](front-envoy.yaml) 16 | ```yaml 17 | virtual_hosts: 18 | - name: backend 19 | domains: 20 | - "*" 21 | routes: 22 | - match: 23 | prefix: "/service/blue" 24 | route: 25 | cluster: service_blue 26 | timeout: 5s 27 | - match: 28 | prefix: "/service/green" 29 | route: 30 | cluster: service_green 31 | - match: 32 | prefix: "/service/red" 33 | route: 34 | cluster: service_red 35 | retry_policy: 36 | retry_on: "5xx" 37 | num_retries: 3 38 | per_try_timeout: 5s 39 | ``` 40 | > - `timeout`: (Duration) Specifies the timeout for the route. If not specified, the default is 15s. For more detail, see`timeout`section in [RouteAction](https://www.envoyproxy.io/docs/envoy/v1.5.0/api-v2/rds.proto#routeaction) 41 | > - `retry_policy` indicates the retry policy for all routes in this virtual host. For more detail on retry_policy, see [route.RetryPolicy](https://www.envoyproxy.io/docs/envoy/v1.5.0/api-v2/rds.proto#envoy-api-msg-routeaction-retrypolicy) 42 | > - `retry_on`: it's retry condition by which the Envoy can retry on different types of conditions depending on application requirements. For example, network failure, all 5xx response codes, idempotent 4xx response codes, etc. 43 | > - `num_retires`: Maximum number of retries. Envoy will continue to retry any number of times. An exponential backoff algorithm is used between each retry. 44 | 45 | 46 | ## Getting Started 47 | ```sh 48 | git clone https://github.com/yokawasa/envoy-proxy-demos.git 49 | cd envoy-proxy-demos/timeouts-retries 50 | ``` 51 | > [NOTICE] Before you run this demo, make sure that all demo containers in previous demo are stopped! 52 | 53 | ## Run the Demo 54 | 55 | ### Build and Run containers 56 | 57 | ```sh 58 | docker-compose up --build -d 59 | 60 | # check all services are up 61 | docker-compose ps --service 62 | 63 | front-envoy 64 | service_blue 65 | service_green 66 | service_red 67 | 68 | # List containers 69 | docker-compose ps 70 | 71 | Name Command State Ports 72 | ----------------------------------------------------------------------------------------------------------------------------------- 73 | timeouts-retries_front-envoy_1 /docker-entrypoint.sh /bin ... Up 10000/tcp, 0.0.0.0:8000->8000/tcp, 0.0.0.0:8001->8001/tcp 74 | timeouts-retries_service_blue_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 75 | timeouts-retries_service_green_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 76 | timeouts-retries_service_red_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 77 | ``` 78 | 79 | ### Access each services 80 | 81 | Access serivce_blue and check if 50% of requests to service_blue are timeout error (over 5 seconds timeout error with 504 status code). The following helper command allow you to send requests repeatedly (For example, send 10 requests to http://localhost:8000/service/blue). 82 | 83 | ```sh 84 | ../helpers/send-requests.sh http://localhost:8000/service/blue 10 85 | 86 | Sending GET request: http://localhost:8000/service/blue 87 | 504 88 | Sending GET request: http://localhost:8000/service/blue 89 | 504 90 | Sending GET request: http://localhost:8000/service/blue 91 | 504 92 | Sending GET request: http://localhost:8000/service/blue 93 | 200 94 | Sending GET request: http://localhost:8000/service/blue 95 | 200 96 | ``` 97 | 98 | Access serivce_blue and check if green background page is displayed. It is expected that nothting special will occur 99 | 100 | ```sh 101 | curl -s http://localhost:8000/service/green 102 | ``` 103 | 104 | Access serivce_red and check if most of requests to service_red are ok (200 status code), but seldomly you'll get abort error (503 status code). To explain what happens behind the senene, 50% of requests to `service_red` will be aborted with 503 error code due to the fault injection config in service_red, however the request will be recovered by the front proxy's retry mechanism, which is why most of the requests to service_red tuned out to be ok (200 status code). The following helper command allow you to send requests repeatedly (For example, send 10 requests to http://localhost:8000/service/blue) 105 | 106 | ```sh 107 | ../helpers/send-requests.sh http://localhost:8000/service/red 10 108 | 109 | Sending GET request: http://localhost:8000/service/red 110 | 200 111 | Sending GET request: http://localhost:8000/service/red 112 | 200 113 | Sending GET request: http://localhost:8000/service/red 114 | 200 115 | Sending GET request: http://localhost:8000/service/red 116 | 503 117 | Sending GET request: http://localhost:8000/service/red 118 | 200 119 | Sending GET request: http://localhost:8000/service/red 120 | 200 121 | Sending GET request: http://localhost:8000/service/red 122 | 200 123 | Sending GET request: http://localhost:8000/service/red 124 | 200 125 | Sending GET request: http://localhost:8000/service/red 126 | 200 127 | Sending GET request: http://localhost:8000/service/red 128 | 200 129 | ``` 130 | 131 | The example run above shows 503 status code one time out of 10 requests, however as explained above this isn't what actually occured. Let's see what it was like with `docker-compose logs`: 132 | 133 | ``` 134 | docker-compose logs -f 135 | 136 | service_red_1 | [2020-08-13T22:58:42.619Z] "GET /service/red HTTP/2" 200 - 0 148 1 1 "-" "curl/7.54.0" "c381450e-b8f9-4b06-9b08-adab5bbb5b87" "localhost:8000" "127.0.0.1:8080" 137 | service_red_1 | [2020-08-13T22:58:43.645Z] "GET /service/red HTTP/2" 200 - 0 148 2 1 "-" "curl/7.54.0" "fd67460c-a332-4510-8b78-fc870a8db246" "localhost:8000" "127.0.0.1:8080" 138 | service_red_1 | [2020-08-13T22:58:44.671Z] "GET /service/red HTTP/2" 503 FI 0 18 0 - "-" "curl/7.54.0" "0e89d112-3e53-4c23-8360-83d8debc8b14" "localhost:8000" "-" 139 | service_red_1 | [2020-08-13T22:58:44.688Z] "GET /service/red HTTP/2" 200 - 0 148 2 2 "-" "curl/7.54.0" "0e89d112-3e53-4c23-8360-83d8debc8b14" "localhost:8000" "127.0.0.1:8080" 140 | service_red_1 | [2020-08-13T22:58:45.714Z] "GET /service/red HTTP/2" 503 FI 0 18 0 - "-" "curl/7.54.0" "536e2d42-92fb-4146-833d-8501ed859d04" "localhost:8000" "-" 141 | service_red_1 | [2020-08-13T22:58:45.729Z] "GET /service/red HTTP/2" 503 FI 0 18 0 - "-" "curl/7.54.0" "536e2d42-92fb-4146-833d-8501ed859d04" "localhost:8000" "-" 142 | service_red_1 | [2020-08-13T22:58:45.755Z] "GET /service/red HTTP/2" 503 FI 0 18 0 - "-" "curl/7.54.0" "536e2d42-92fb-4146-833d-8501ed859d04" "localhost:8000" "-" 143 | service_red_1 | [2020-08-13T22:58:45.755Z] "GET /service/red HTTP/2" 503 FI 0 18 0 - "-" "curl/7.54.0" "536e2d42-92fb-4146-833d-8501ed859d04" "localhost:8000" "-" 144 | service_red_1 | [2020-08-13T22:58:45.779Z] "GET /service/red HTTP/2" 200 - 0 148 2 1 "-" "curl/7.54.0" "536e2d42-92fb-4146-833d-8501ed859d04" "localhost:8000" "127.0.0.1:8080" 145 | service_red_1 | [2020-08-13T22:58:46.805Z] "GET /service/red HTTP/2" 200 - 0 148 3 2 "-" "curl/7.54.0" "c84a1945-f342-43a2-bb72-27a3dcc25ab6" "localhost:8000" "127.0.0.1:8080" 146 | service_red_1 | [2020-08-13T22:58:47.826Z] "GET /service/red HTTP/2" 200 - 0 148 2 1 "-" "curl/7.54.0" "7700a887-d419-4f9f-965d-107504007a6c" "localhost:8000" "127.0.0.1:8080" 147 | service_red_1 | [2020-08-13T22:58:48.853Z] "GET /service/red HTTP/2" 200 - 0 148 1 1 "-" "curl/7.54.0" "9f3a2717-83da-495f-8115-159a02854446" "localhost:8000" "127.0.0.1:8080" 148 | service_red_1 | [2020-08-13T22:58:49.881Z] "GET /service/red HTTP/2" 503 FI 0 18 0 - "-" "curl/7.54.0" "664deb97-c446-464c-82c0-ad5f4ed2c8d1" "localhost:8000" "-" 149 | service_red_1 | [2020-08-13T22:58:49.893Z] "GET /service/red HTTP/2" 503 FI 0 18 0 - "-" "curl/7.54.0" "664deb97-c446-464c-82c0-ad5f4ed2c8d1" "localhost:8000" "-" 150 | service_red_1 | [2020-08-13T22:58:49.936Z] "GET /service/red HTTP/2" 200 - 0 148 2 1 "-" "curl/7.54.0" "664deb97-c446-464c-82c0-ad5f4ed2c8d1" "localhost:8000" "127.0.0.1:8080" 151 | service_red_1 | [2020-08-13T22:58:50.965Z] "GET /service/red HTTP/2" 200 - 0 148 1 1 "-" "curl/7.54.0" "f4d7012b-7eb3-44a3-9a16-c8d345049707" "localhost:8000" "127.0.0.1:8080" 152 | ... 153 | ``` 154 | 155 | It shows `service_red` was be aborted with 503 error code, and that requests from the front proxy was retried and was recovered if it was within `3` retries, the value of `num_retries`. 156 | 157 | 158 | ## Stop & Cleanup 159 | 160 | ```sh 161 | docker-compose down --remove-orphans --rmi all 162 | ``` 163 | 164 | --- 165 | [Top](../README.md) 166 | -------------------------------------------------------------------------------- /timeouts-retries/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | 4 | front-envoy: 5 | build: 6 | context: ../apps 7 | # Build a container using the Dockerfile-frontenvoy file located in the current directory 8 | dockerfile: Dockerfile-frontenvoy 9 | volumes: 10 | # Mount the front-envoy.yaml file in this directory as /etc/front-envoy.yaml 11 | - ./front-envoy.yaml:/etc/front-envoy.yaml 12 | networks: 13 | # Create and use a Docker network named “envoymesh” for this container 14 | - envoymesh 15 | expose: 16 | # Expose ports 8000 (for general traffic) and 8001 (for the admin server) 17 | - "8000" 18 | - "8001" 19 | ports: 20 | # Map the host port 8000 to container port 8000, and the host port 8001 to container port 8001 21 | - "8000:8000" 22 | - "8001:8001" 23 | 24 | service_blue: 25 | build: 26 | context: ../apps 27 | dockerfile: Dockerfile-service 28 | volumes: 29 | - ./service-envoy-fault-injection-delay.yaml:/etc/service-envoy.yaml 30 | networks: 31 | envoymesh: 32 | aliases: 33 | - service_blue 34 | environment: 35 | - SERVICE_NAME=blue 36 | expose: 37 | - "80" 38 | service_green: 39 | build: 40 | context: ../apps 41 | dockerfile: Dockerfile-service 42 | volumes: 43 | - ./service-envoy.yaml:/etc/service-envoy.yaml 44 | networks: 45 | envoymesh: 46 | aliases: 47 | - service_green 48 | environment: 49 | - SERVICE_NAME=green 50 | expose: 51 | - "80" 52 | service_red: 53 | build: 54 | context: ../apps 55 | dockerfile: Dockerfile-service 56 | volumes: 57 | - ./service-envoy-fault-injection-abort.yaml:/etc/service-envoy.yaml 58 | networks: 59 | envoymesh: 60 | aliases: 61 | - service_red 62 | environment: 63 | - SERVICE_NAME=red 64 | expose: 65 | - "80" 66 | 67 | networks: 68 | envoymesh: {} 69 | -------------------------------------------------------------------------------- /timeouts-retries/front-envoy.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 8000 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | route_config: 15 | name: local_route 16 | virtual_hosts: 17 | - name: backend 18 | domains: 19 | - "*" 20 | routes: 21 | - match: 22 | prefix: "/service/blue" 23 | route: 24 | cluster: service_blue 25 | timeout: 5s 26 | - match: 27 | prefix: "/service/green" 28 | route: 29 | cluster: service_green 30 | - match: 31 | prefix: "/service/red" 32 | route: 33 | cluster: service_red 34 | retry_policy: 35 | retry_on: "5xx" 36 | num_retries: 3 37 | per_try_timeout: 5s 38 | http_filters: 39 | - name: envoy.filters.http.router 40 | typed_config: {} 41 | clusters: 42 | - name: service_blue 43 | connect_timeout: 0.25s 44 | type: strict_dns 45 | lb_policy: round_robin 46 | http2_protocol_options: {} 47 | load_assignment: 48 | cluster_name: service_blue 49 | endpoints: 50 | - lb_endpoints: 51 | - endpoint: 52 | address: 53 | socket_address: 54 | address: service_blue 55 | port_value: 80 56 | - name: service_green 57 | connect_timeout: 0.25s 58 | type: strict_dns 59 | lb_policy: round_robin 60 | http2_protocol_options: {} 61 | load_assignment: 62 | cluster_name: service_green 63 | endpoints: 64 | - lb_endpoints: 65 | - endpoint: 66 | address: 67 | socket_address: 68 | address: service_green 69 | port_value: 80 70 | - name: service_red 71 | connect_timeout: 0.25s 72 | type: strict_dns 73 | lb_policy: round_robin 74 | http2_protocol_options: {} 75 | load_assignment: 76 | cluster_name: service_red 77 | endpoints: 78 | - lb_endpoints: 79 | - endpoint: 80 | address: 81 | socket_address: 82 | address: service_red 83 | port_value: 80 84 | admin: 85 | access_log_path: "/dev/null" 86 | address: 87 | socket_address: 88 | address: 0.0.0.0 89 | port_value: 8001 90 | layered_runtime: 91 | layers: 92 | - name: static_layer_0 93 | static_layer: 94 | envoy: 95 | resource_limits: 96 | listener: 97 | example_listener_name: 98 | connection_limit: 10000 99 | -------------------------------------------------------------------------------- /timeouts-retries/service-envoy-fault-injection-abort.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | access_log: 15 | name: envoy.access_loggers.file 16 | typed_config: 17 | "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog 18 | path: /dev/stdout 19 | route_config: 20 | name: local_route 21 | virtual_hosts: 22 | - name: service 23 | domains: 24 | - "*" 25 | routes: 26 | - match: 27 | prefix: "/service" 28 | route: 29 | cluster: local_service 30 | http_filters: 31 | - name: envoy.filters.http.fault 32 | typed_config: 33 | "@type": type.googleapis.com/envoy.config.filter.http.fault.v2.HTTPFault 34 | abort: 35 | http_status: 503 36 | percentage: 37 | numerator: 50 38 | denominator: HUNDRED 39 | - name: envoy.filters.http.router 40 | typed_config: {} 41 | clusters: 42 | - name: local_service 43 | connect_timeout: 0.25s 44 | type: strict_dns 45 | lb_policy: round_robin 46 | load_assignment: 47 | cluster_name: local_service 48 | endpoints: 49 | - lb_endpoints: 50 | - endpoint: 51 | address: 52 | socket_address: 53 | address: 127.0.0.1 54 | port_value: 8080 55 | admin: 56 | access_log_path: /dev/stdout 57 | address: 58 | socket_address: 59 | address: 0.0.0.0 60 | port_value: 8081 61 | #runtime: 62 | # symlink_root: /srv/runtime/current 63 | # subdirectory: envoy 64 | -------------------------------------------------------------------------------- /timeouts-retries/service-envoy-fault-injection-delay.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | filter_chains: 8 | - filters: 9 | - name: envoy.filters.network.http_connection_manager 10 | typed_config: 11 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 12 | codec_type: auto 13 | stat_prefix: ingress_http 14 | access_log: 15 | name: envoy.access_loggers.file 16 | typed_config: 17 | "@type": type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog 18 | path: /dev/stdout 19 | route_config: 20 | name: local_route 21 | virtual_hosts: 22 | - name: service 23 | domains: 24 | - "*" 25 | routes: 26 | - match: 27 | prefix: "/service" 28 | route: 29 | cluster: local_service 30 | http_filters: 31 | - name: envoy.filters.http.fault 32 | typed_config: 33 | "@type": type.googleapis.com/envoy.config.filter.http.fault.v2.HTTPFault 34 | delay: 35 | #type: fixed 36 | fixed_delay: 10s 37 | percentage: 38 | numerator: 50 39 | denominator: HUNDRED 40 | - name: envoy.filters.http.router 41 | typed_config: {} 42 | clusters: 43 | - name: local_service 44 | connect_timeout: 0.25s 45 | type: strict_dns 46 | lb_policy: round_robin 47 | load_assignment: 48 | cluster_name: local_service 49 | endpoints: 50 | - lb_endpoints: 51 | - endpoint: 52 | address: 53 | socket_address: 54 | address: 127.0.0.1 55 | port_value: 8080 56 | admin: 57 | access_log_path: /dev/stdout 58 | address: 59 | socket_address: 60 | address: 0.0.0.0 61 | port_value: 8081 62 | #runtime: 63 | # symlink_root: /srv/runtime/current 64 | # subdirectory: envoy 65 | -------------------------------------------------------------------------------- /timeouts-retries/service-envoy.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | filter_chains: 8 | - filters: 9 | - name: envoy.http_connection_manager 10 | config: 11 | codec_type: auto 12 | stat_prefix: ingress_http 13 | route_config: 14 | name: local_route 15 | virtual_hosts: 16 | - name: service 17 | domains: 18 | - "*" 19 | routes: 20 | - match: 21 | prefix: "/service" 22 | route: 23 | cluster: local_service 24 | http_filters: 25 | - name: envoy.router 26 | config: {} 27 | clusters: 28 | - name: local_service 29 | connect_timeout: 0.25s 30 | type: strict_dns 31 | lb_policy: round_robin 32 | hosts: 33 | - socket_address: 34 | address: 127.0.0.1 35 | port_value: 8080 36 | admin: 37 | access_log_path: "/dev/null" 38 | address: 39 | socket_address: 40 | address: 0.0.0.0 41 | port_value: 8081 42 | -------------------------------------------------------------------------------- /zipkin-tracing/README.md: -------------------------------------------------------------------------------- 1 | # Distributed Tracing: Zipkin Tracing 2 | 3 | ## Demo Overview 4 | This is a Zipkin tracing example built based on the [Envoy sandboxes (Zipkin Tracing)](https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/zipkin_tracing) that demonstrates Envoy’s [tracing](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/observability/tracing) capabilities using [Zipkin](https://zipkin.io/) as the tracing provider. 5 | 6 | All services in the demo support not only `service` endpoint (which is basically the same as [HTTP Routing: Simple Match Routing](../httproute-simple-match/README.md)) but also `trace` endpoint. All traffic is routed by the `front envoy` to the `service containers`. Internally the traffic is routed to the service envoys, then the service envoys route the request to the flask app via the loopback address. All trace data is collected into a `Zipkin` container. 7 | 8 | ![](../assets/demo-zipkin-tracing.png) 9 | 10 | ### Endpoint - trace 11 | In accessing to `trace` endpoint, all traffic is routed to the service envoys with trace header propagations like this: 12 | 13 | - A request (path `/trace/blue` & port `8000`) is routed to `service_blue` 14 | - `service_blue` internally calls `service_green` that then internally calls `service_red` with `trace header propagations` 15 | - A request (path `/trace/green` & port `8000`) is routed to `service_green` 16 | - `service_blue` internally calls `service_red` with `trace header propagations` 17 | - A request (path `/trace/red` & port `8000`) is routed to `service_red` 18 | 19 | ![](../assets/demo-zipkin-tracing-req-trace.png) 20 | 21 | #### Key configuration 1: The HTTP connection manager 22 | All envoys are configured to collect request traces (e.g., [tracing](https://www.envoyproxy.io/docs/envoy/latest/api-v2/config/filter/network/http_connection_manager/v2/http_connection_manager.proto#envoy-api-msg-config-filter-network-http-connection-manager-v2-httpconnectionmanager-tracing) in config.filter.network.http_connection_manager.v2.HttpConnectionManager in front envoy). 23 | 24 | ```yaml 25 | static_resources: 26 | listeners: 27 | - address: 28 | socket_address: 29 | address: 0.0.0.0 30 | port_value: 8000 31 | traffic_direction: OUTBOUND 32 | filter_chains: 33 | - filters: 34 | - name: envoy.filters.network.http_connection_manager 35 | typed_config: 36 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 37 | generate_request_id: true 38 | tracing: 39 | provider: 40 | name: envoy.tracers.zipkin 41 | typed_config: 42 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 43 | collector_cluster: zipkin 44 | collector_endpoint: "/api/v2/spans" 45 | collector_endpoint_version: HTTP_JSON 46 | ``` 47 | 48 | > - The HTTP connection manager that handles the request must have the tracing object set. Please refer to [tracing object](https://www.envoyproxy.io/docs/envoy/latest/api-v2/config/filter/network/http_connection_manager/v2/http_connection_manager.proto#envoy-api-msg-config-filter-network-http-connection-manager-v2-httpconnectionmanager-tracing). 49 | > - For the configuration for an HTTP tracer provider used by Envoy, see [config.trace.v2.Tracing.Http](https://www.envoyproxy.io/docs/envoy/latest/api-v2/config/trace/v2/http_tracer.proto#envoy-api-msg-config-trace-v2-tracing-http) 50 | > 51 | 52 | > Presence of the object defines whether the connection manager emits tracing data to the configured tracing provider. You configure `tracing driver` in `name` field. Here are 4 parameter options for `tracing driver` and `envoy.tracers.zipkin` is selected here: 53 | > - envoy.tracers.lightstep 54 | > - envoy.tracers.zipkin 55 | > - envoy.tracers.dynamic_ot 56 | > - envoy.tracers.datadog 57 | > - envoy.tracers.opencensus 58 | > - envoy.tracers.xray 59 | > 60 | > Parameters for Config parts in zipkin deiver are [here](https://www.envoyproxy.io/docs/envoy/latest/api-v2/config/trace/v2/zipkin.proto#envoy-api-msg-config-trace-v2-zipkinconfig) 61 | 62 | #### Key configuration 2: Spans propagation setup (Trace deiver setup) 63 | 64 | All envoys in the demo are also configured to setup to propagate the spans generated by the Zipkin tracer to a Zipkin cluster. 65 | 66 | ```YAML 67 | static_resources: 68 | listeners: 69 | ... 70 | - address: 71 | socket_address: 72 | address: 0.0.0.0 73 | port_value: 9000 74 | traffic_direction: OUTBOUND 75 | filter_chains: 76 | - filters: 77 | - name: envoy.filters.network.http_connection_manager 78 | typed_config: 79 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 80 | tracing: 81 | provider: 82 | name: envoy.tracers.zipkin 83 | typed_config: 84 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 85 | collector_cluster: jaeger 86 | collector_endpoint: "/api/v2/spans" 87 | shared_span_context: false 88 | collector_endpoint_version: HTTP_JSON 89 | ... 90 | clusters: 91 | ... 92 | - name: zipkin 93 | connect_timeout: 1s 94 | type: strict_dns 95 | lb_policy: round_robin 96 | load_assignment: 97 | cluster_name: zipkin 98 | endpoints: 99 | - lb_endpoints: 100 | - endpoint: 101 | address: 102 | socket_address: 103 | address: zipkin 104 | port_value: 9411 105 | ``` 106 | 107 | #### Key configuration 3: Trace header propagation 108 | One of the most important benefits of tracing from Envoy is that it will take care of propagating the traces to the Zipkin service cluster. However, in order to fully take advantage of tracing, the application has to propagate trace headers that Envoy generates. The sample `trace header propagations` setup in servcie application code ([apps/service.py](../apps/service.py)) is this: 109 | 110 | ```python 111 | # ...omit... 112 | 113 | TRACE_HEADERS_TO_PROPAGATE = [ 114 | 'X-Ot-Span-Context', 115 | 'X-Request-Id', 116 | 117 | # Zipkin headers 118 | 'X-B3-TraceId', 119 | 'X-B3-SpanId', 120 | 'X-B3-ParentSpanId', 121 | 'X-B3-Sampled', 122 | 'X-B3-Flags', 123 | 124 | # Jaeger header (for native client) 125 | "uber-trace-id" 126 | ] 127 | 128 | def render_page(): 129 | return ('\n' 130 | 'Hello from {} (hostname: {} resolvedhostname:{})\n\n'.format( 131 | os.environ['SERVICE_NAME'], 132 | os.environ['SERVICE_NAME'], 133 | socket.gethostname(), 134 | socket.gethostbyname(socket.gethostname()))) 135 | 136 | # ...omit... 137 | 138 | @app.route('/trace/') 139 | def trace(service_color): 140 | headers = {} 141 | ## For Propagation test ## 142 | # Call service 'green' from service 'blue' 143 | if (os.environ['SERVICE_NAME']) == 'blue': 144 | for header in TRACE_HEADERS_TO_PROPAGATE: 145 | if header in request.headers: 146 | headers[header] = request.headers[header] 147 | ret = requests.get("http://localhost:9000/trace/green", headers=headers) 148 | # Call service 'red' from service 'green' 149 | elif (os.environ['SERVICE_NAME']) == 'green': 150 | for header in TRACE_HEADERS_TO_PROPAGATE: 151 | if header in request.headers: 152 | headers[header] = request.headers[header] 153 | ret = requests.get("http://localhost:9000/trace/red", headers=headers) 154 | return render_page() 155 | 156 | if __name__ == "__main__": 157 | app.run(host='127.0.0.1', port=8080, debug=True) 158 | ``` 159 | 160 | > **Zipkin tracer** 161 | - When using the `Zipkin tracer`, Envoy relies on the service to propagate the `B3 HTTP headers` ( `x-b3-traceid, x-b3-spanid, x-b3-parentspanid, x-b3-sampled, and x-b3-flags`). The x-b3-sampled header can also be supplied by an external client to either enable or disable tracing for a particular request. In addition, the single b3 header propagation format is supported, which is a more compressed format. Please refer to [B3 Header](https://www.envoyproxy.io/docs/envoy/latest/configuration/http_conn_man/headers#config-http-conn-man-headers-b3) for the detail. 162 | 163 | 164 | ## Getting Started 165 | ```sh 166 | $ git clone https://github.com/yokawasa/envoy-proxy-demos.git 167 | $ cd envoy-proxy-demos/zipkin-tracing 168 | ``` 169 | > [NOTICE] Before you run this demo, make sure that all demo containers in previous demo are stopped! 170 | 171 | ## Run the Demo 172 | 173 | ### Build and Run containers 174 | 175 | ```sh 176 | docker-compose up --build -d 177 | 178 | # check all services are up 179 | docker-compose ps --service 180 | 181 | front-envoy 182 | service_blue 183 | service_green 184 | service_red 185 | zipkin 186 | 187 | # List containers 188 | docker-compose ps 189 | 190 | Name Command State Ports 191 | --------------------------------------------------------------------------------------------------------------------------------- 192 | zipkin-tracing_front-envoy_1 /docker-entrypoint.sh /bin ... Up 10000/tcp, 0.0.0.0:8000->8000/tcp, 0.0.0.0:8001->8001/tcp 193 | zipkin-tracing_service_blue_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 194 | zipkin-tracing_service_green_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 195 | zipkin-tracing_service_red_1 /bin/sh -c /usr/local/bin/ ... Up 10000/tcp, 80/tcp 196 | zipkin-tracing_zipkin_1 /bin/sh -c /zipkin/run.sh Up (health: starting) 9410/tcp, 0.0.0.0:9411->9411/tcp 197 | ``` 198 | 199 | ### Access each services and check tracing results 200 | 201 | Access the following 3 endpoints for tracing test. 202 | ``` 203 | curl -s -v http://localhost:8000/trace/blue 204 | curl -s -v http://localhost:8000/trace/green 205 | curl -s -v http://localhost:8000/trace/red 206 | ``` 207 | 208 | For example, when you access `/trace/blue`, you'll see the following output 209 | ```sh 210 | curl -v http://localhost:8000/trace/blue 211 | 212 | * Trying ::1... 213 | * TCP_NODELAY set 214 | * Connected to localhost (::1) port 8000 (#0) 215 | > GET /trace/blue HTTP/1.1 216 | > Host: localhost:8000 217 | > User-Agent: curl/7.54.0 218 | > Accept: */* 219 | > 220 | < HTTP/1.1 200 OK 221 | < content-type: text/html; charset=utf-8 222 | < content-length: 147 223 | < server: envoy 224 | < date: Sun, 17 Feb 2019 17:27:50 GMT 225 | < x-envoy-upstream-service-time: 23 226 | < 227 | 228 | Hello from blue (hostname: 7400d4d450cd resolvedhostname:172.22.0.3) 229 | 230 | * Connection #0 to host localhost left intact 231 | ``` 232 | 233 | Trace data would automatically have been generated and pushed to Zipkin via Envoy. In this part, check the Zipkin UI to see how the Zipkin visualize all the trace data collected. Here is a Zipkin UI url: 234 | 235 | ``` 236 | open http://localhost:9411 237 | ``` 238 | 239 | ![](../assets/zipkin-ui.png) 240 | 241 | You'll come up with Zipkin UI page like above, then search each traces. Here are example tracing results in Zipkin UI: 242 | 243 | ![](../assets/zipkin-ui-servide-blue.png) 244 | 245 | ![](../assets/zipkin-ui-servide-green.png) 246 | 247 | 248 | ## Stop & Cleanup 249 | 250 | ```sh 251 | docker-compose down --remove-orphans --rmi all 252 | ``` 253 | 254 | --- 255 | [Top](../README.md) 256 | -------------------------------------------------------------------------------- /zipkin-tracing/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | 4 | front-envoy: 5 | build: 6 | context: ../apps 7 | dockerfile: Dockerfile-frontenvoy 8 | volumes: 9 | - ./front-envoy.yaml:/etc/front-envoy.yaml 10 | networks: 11 | - envoymesh 12 | expose: 13 | # Expose ports 80 (for general traffic) and 8001 (for the admin server) 14 | - "8000" 15 | - "8001" 16 | ports: 17 | - "8000:8000" 18 | - "8001:8001" 19 | 20 | service_blue: 21 | build: 22 | context: ../apps 23 | dockerfile: Dockerfile-service 24 | volumes: 25 | - ./service-blue-envoy-zipkin.yaml:/etc/service-envoy.yaml 26 | networks: 27 | envoymesh: 28 | aliases: 29 | - service_blue 30 | environment: 31 | - SERVICE_NAME=blue 32 | expose: 33 | - "80" 34 | service_green: 35 | build: 36 | context: ../apps 37 | dockerfile: Dockerfile-service 38 | volumes: 39 | - ./service-green-envoy-zipkin.yaml:/etc/service-envoy.yaml 40 | networks: 41 | envoymesh: 42 | aliases: 43 | - service_green 44 | environment: 45 | - SERVICE_NAME=green 46 | expose: 47 | - "80" 48 | service_red: 49 | build: 50 | context: ../apps 51 | dockerfile: Dockerfile-service 52 | volumes: 53 | - ./service-red-envoy-zipkin.yaml:/etc/service-envoy.yaml 54 | networks: 55 | envoymesh: 56 | aliases: 57 | - service_red 58 | environment: 59 | - SERVICE_NAME=red 60 | expose: 61 | - "80" 62 | zipkin: 63 | image: openzipkin/zipkin 64 | networks: 65 | envoymesh: 66 | aliases: 67 | - zipkin 68 | expose: 69 | - "9411" 70 | ports: 71 | - "9411:9411" 72 | 73 | networks: 74 | envoymesh: {} 75 | -------------------------------------------------------------------------------- /zipkin-tracing/front-envoy.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 8000 7 | traffic_direction: OUTBOUND 8 | filter_chains: 9 | - filters: 10 | - name: envoy.filters.network.http_connection_manager 11 | typed_config: 12 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 13 | generate_request_id: true 14 | tracing: 15 | provider: 16 | name: envoy.tracers.zipkin 17 | typed_config: 18 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 19 | collector_cluster: zipkin 20 | collector_endpoint: "/api/v2/spans" 21 | collector_endpoint_version: HTTP_JSON 22 | codec_type: auto 23 | stat_prefix: ingress_http 24 | route_config: 25 | name: local_route 26 | virtual_hosts: 27 | - name: backend 28 | domains: 29 | - "*" 30 | routes: 31 | - match: 32 | prefix: "/service/blue" 33 | route: 34 | cluster: service_blue 35 | - match: 36 | prefix: "/trace/blue" 37 | route: 38 | cluster: service_blue 39 | - match: 40 | prefix: "/service/green" 41 | route: 42 | cluster: service_green 43 | - match: 44 | prefix: "/trace/green" 45 | route: 46 | cluster: service_green 47 | - match: 48 | prefix: "/service/red" 49 | route: 50 | cluster: service_red 51 | - match: 52 | prefix: "/trace/red" 53 | route: 54 | cluster: service_red 55 | http_filters: 56 | - name: envoy.filters.http.router 57 | typed_config: {} 58 | clusters: 59 | - name: service_blue 60 | connect_timeout: 0.25s 61 | type: strict_dns 62 | lb_policy: round_robin 63 | http2_protocol_options: {} 64 | load_assignment: 65 | cluster_name: service_blue 66 | endpoints: 67 | - lb_endpoints: 68 | - endpoint: 69 | address: 70 | socket_address: 71 | address: service_blue 72 | port_value: 80 73 | - name: service_green 74 | connect_timeout: 0.25s 75 | type: strict_dns 76 | lb_policy: round_robin 77 | http2_protocol_options: {} 78 | load_assignment: 79 | cluster_name: service_green 80 | endpoints: 81 | - lb_endpoints: 82 | - endpoint: 83 | address: 84 | socket_address: 85 | address: service_green 86 | port_value: 80 87 | - name: service_red 88 | connect_timeout: 0.25s 89 | type: strict_dns 90 | lb_policy: round_robin 91 | http2_protocol_options: {} 92 | load_assignment: 93 | cluster_name: service_red 94 | endpoints: 95 | - lb_endpoints: 96 | - endpoint: 97 | address: 98 | socket_address: 99 | address: service_red 100 | port_value: 80 101 | - name: zipkin 102 | connect_timeout: 1s 103 | type: strict_dns 104 | lb_policy: round_robin 105 | load_assignment: 106 | cluster_name: zipkin 107 | endpoints: 108 | - lb_endpoints: 109 | - endpoint: 110 | address: 111 | socket_address: 112 | address: zipkin 113 | port_value: 9411 114 | admin: 115 | access_log_path: "/dev/null" 116 | address: 117 | socket_address: 118 | address: 0.0.0.0 119 | port_value: 8001 120 | -------------------------------------------------------------------------------- /zipkin-tracing/service-blue-envoy-zipkin.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | traffic_direction: INBOUND 8 | filter_chains: 9 | - filters: 10 | - name: envoy.filters.network.http_connection_manager 11 | typed_config: 12 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 13 | tracing: 14 | provider: 15 | name: envoy.tracers.zipkin 16 | typed_config: 17 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 18 | collector_cluster: zipkin 19 | collector_endpoint: "/api/v2/spans" 20 | collector_endpoint_version: HTTP_JSON 21 | codec_type: auto 22 | stat_prefix: ingress_http 23 | route_config: 24 | name: local_route 25 | virtual_hosts: 26 | - name: service_blue 27 | domains: 28 | - "*" 29 | routes: 30 | - match: 31 | prefix: "/" 32 | route: 33 | cluster: local_service 34 | decorator: 35 | operation: checkAvailability 36 | http_filters: 37 | - name: envoy.filters.http.router 38 | typed_config: {} 39 | - address: 40 | socket_address: 41 | address: 0.0.0.0 42 | port_value: 9000 43 | traffic_direction: OUTBOUND 44 | filter_chains: 45 | - filters: 46 | - name: envoy.filters.network.http_connection_manager 47 | typed_config: 48 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 49 | tracing: 50 | provider: 51 | name: envoy.tracers.zipkin 52 | typed_config: 53 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 54 | collector_cluster: zipkin 55 | collector_endpoint: "/api/v2/spans" 56 | collector_endpoint_version: HTTP_JSON 57 | codec_type: auto 58 | stat_prefix: egress_http 59 | route_config: 60 | name: service_green_route 61 | virtual_hosts: 62 | - name: service_green 63 | domains: 64 | - "*" 65 | routes: 66 | - match: 67 | prefix: "/trace" 68 | route: 69 | cluster: service_green 70 | decorator: 71 | operation: checkStock 72 | http_filters: 73 | - name: envoy.filters.http.router 74 | typed_config: {} 75 | clusters: 76 | - name: local_service 77 | connect_timeout: 0.25s 78 | type: strict_dns 79 | lb_policy: round_robin 80 | load_assignment: 81 | cluster_name: local_service 82 | endpoints: 83 | - lb_endpoints: 84 | - endpoint: 85 | address: 86 | socket_address: 87 | address: 127.0.0.1 88 | port_value: 8080 89 | - name: service_green 90 | connect_timeout: 0.250s 91 | type: strict_dns 92 | lb_policy: round_robin 93 | http2_protocol_options: {} 94 | load_assignment: 95 | cluster_name: service_green 96 | endpoints: 97 | - lb_endpoints: 98 | - endpoint: 99 | address: 100 | socket_address: 101 | address: service_green 102 | port_value: 80 103 | - name: zipkin 104 | connect_timeout: 1s 105 | type: strict_dns 106 | lb_policy: round_robin 107 | load_assignment: 108 | cluster_name: zipkin 109 | endpoints: 110 | - lb_endpoints: 111 | - endpoint: 112 | address: 113 | socket_address: 114 | address: zipkin 115 | port_value: 9411 116 | admin: 117 | access_log_path: "/dev/null" 118 | address: 119 | socket_address: 120 | address: 0.0.0.0 121 | port_value: 8081 122 | -------------------------------------------------------------------------------- /zipkin-tracing/service-green-envoy-zipkin.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | traffic_direction: INBOUND 8 | filter_chains: 9 | - filters: 10 | - name: envoy.filters.network.http_connection_manager 11 | typed_config: 12 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 13 | tracing: 14 | provider: 15 | name: envoy.tracers.zipkin 16 | typed_config: 17 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 18 | collector_cluster: zipkin 19 | collector_endpoint: "/api/v2/spans" 20 | collector_endpoint_version: HTTP_JSON 21 | codec_type: auto 22 | stat_prefix: ingress_http 23 | route_config: 24 | name: local_route 25 | virtual_hosts: 26 | - name: service_green 27 | domains: 28 | - "*" 29 | routes: 30 | - match: 31 | prefix: "/" 32 | route: 33 | cluster: local_service 34 | decorator: 35 | operation: checkAvailability 36 | http_filters: 37 | - name: envoy.filters.http.router 38 | typed_config: {} 39 | - address: 40 | socket_address: 41 | address: 0.0.0.0 42 | port_value: 9000 43 | traffic_direction: OUTBOUND 44 | filter_chains: 45 | - filters: 46 | - name: envoy.filters.network.http_connection_manager 47 | typed_config: 48 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 49 | tracing: 50 | provider: 51 | name: envoy.tracers.zipkin 52 | typed_config: 53 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 54 | collector_cluster: zipkin 55 | collector_endpoint: "/api/v2/spans" 56 | collector_endpoint_version: HTTP_JSON 57 | codec_type: auto 58 | stat_prefix: egress_http 59 | route_config: 60 | name: service_red_route 61 | virtual_hosts: 62 | - name: service_red 63 | domains: 64 | - "*" 65 | routes: 66 | - match: 67 | prefix: "/trace" 68 | route: 69 | cluster: service_red 70 | decorator: 71 | operation: checkStock 72 | http_filters: 73 | - name: envoy.filters.http.router 74 | typed_config: {} 75 | clusters: 76 | - name: local_service 77 | connect_timeout: 0.25s 78 | type: strict_dns 79 | lb_policy: round_robin 80 | load_assignment: 81 | cluster_name: local_service 82 | endpoints: 83 | - lb_endpoints: 84 | - endpoint: 85 | address: 86 | socket_address: 87 | address: 127.0.0.1 88 | port_value: 8080 89 | - name: service_red 90 | connect_timeout: 0.250s 91 | type: strict_dns 92 | lb_policy: round_robin 93 | http2_protocol_options: {} 94 | load_assignment: 95 | cluster_name: service_red 96 | endpoints: 97 | - lb_endpoints: 98 | - endpoint: 99 | address: 100 | socket_address: 101 | address: service_red 102 | port_value: 80 103 | - name: zipkin 104 | connect_timeout: 1s 105 | type: strict_dns 106 | lb_policy: round_robin 107 | load_assignment: 108 | cluster_name: zipkin 109 | endpoints: 110 | - lb_endpoints: 111 | - endpoint: 112 | address: 113 | socket_address: 114 | address: zipkin 115 | port_value: 9411 116 | admin: 117 | access_log_path: "/dev/null" 118 | address: 119 | socket_address: 120 | address: 0.0.0.0 121 | port_value: 8081 122 | -------------------------------------------------------------------------------- /zipkin-tracing/service-red-envoy-zipkin.yaml: -------------------------------------------------------------------------------- 1 | static_resources: 2 | listeners: 3 | - address: 4 | socket_address: 5 | address: 0.0.0.0 6 | port_value: 80 7 | traffic_direction: INBOUND 8 | filter_chains: 9 | - filters: 10 | - name: envoy.filters.network.http_connection_manager 11 | typed_config: 12 | "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 13 | tracing: 14 | provider: 15 | name: envoy.tracers.zipkin 16 | typed_config: 17 | "@type": type.googleapis.com/envoy.config.trace.v2.ZipkinConfig 18 | collector_cluster: zipkin 19 | collector_endpoint: "/api/v2/spans" 20 | collector_endpoint_version: HTTP_JSON 21 | codec_type: auto 22 | stat_prefix: ingress_http 23 | route_config: 24 | name: local_route_service 25 | virtual_hosts: 26 | - name: service_red 27 | domains: 28 | - "*" 29 | routes: 30 | - match: 31 | prefix: "/" 32 | route: 33 | cluster: local_service 34 | decorator: 35 | operation: checkAvailability 36 | http_filters: 37 | - name: envoy.filters.http.router 38 | typed_config: {} 39 | clusters: 40 | - name: local_service 41 | connect_timeout: 0.25s 42 | type: strict_dns 43 | lb_policy: round_robin 44 | load_assignment: 45 | cluster_name: local_service 46 | endpoints: 47 | - lb_endpoints: 48 | - endpoint: 49 | address: 50 | socket_address: 51 | address: 127.0.0.1 52 | port_value: 8080 53 | - name: zipkin 54 | connect_timeout: 1s 55 | type: strict_dns 56 | lb_policy: round_robin 57 | load_assignment: 58 | cluster_name: zipkin 59 | endpoints: 60 | - lb_endpoints: 61 | - endpoint: 62 | address: 63 | socket_address: 64 | address: zipkin 65 | port_value: 9411 66 | admin: 67 | access_log_path: "/dev/null" 68 | address: 69 | socket_address: 70 | address: 0.0.0.0 71 | port_value: 8081 72 | --------------------------------------------------------------------------------