Episode 7 makes the mesh resilient to failures: retries with retry budgets and per-host limits, per-request timeouts, circuit breakers via outlier detection and connection pools, and fault injection for testing system resilience.

On real networks, failures are normal: connections drop, Pods restart, backends slow down. A resilient application is not one that never fails, but one that recovers quickly when failures happen. Episode 7 covers four resilience patterns you can install without changing application code: retries, timeouts, circuit breakers, and fault injection.
Retries make Envoy repeat a failed request before giving up:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: productpage-retry
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
retries:
attempts: 3
perTryTimeout: 2s
retryOn: connect-failure,refused-stream,5xxattempts: 3 allows up to three retries, perTryTimeout limits the duration of a single attempt, and retryOn determines which conditions are worth retrying — 5xx includes 500 and 503, but not errors that are not server responses.
Warning
Be careful with non-idempotent endpoints. If a request triggers a payment, automatic retries can duplicate transactions. Restrict retryOn to requests that are safe to repeat.
Retries can also be capped globally per service with a RetryBudget (available in newer Istio versions):
apiVersion: networking.istio.io/v1
kind: RetryBudget
metadata:
name: productpage-budget
spec:
match:
- hosts:
- productpage
retryBudget:
percent: 20
minRetriesPerSecond: 10retryBudget.percent: 20 means additional retries are capped at 20 percent of normal traffic — preventing retry storms when many requests fail at once, something that can make an outage worse.
A timeout limits the total time a single request may take:
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
timeout: 5stimeout: 5s stops a request that runs longer than five seconds and returns a 504 error to the client. Combining a timeout with perTryTimeout keeps latency under control: if the backend is slow, you fail fast instead of hanging.
The circuit breaker in Istio is built from two parts: the connection pool and outlier detection. Both live in a DestinationRule:
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: productpage-circuit
spec:
host: productpage
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 100
http2MaxRequests: 1000
outlierDetection:
consecutive5xxErrors: 5
interval: 30s
baseEjectionTime: 1m
maxEjectionPercent: 100How it works is simple: the connection pool limits how many connections and requests may target a Pod. If a Pod starts producing 5xx errors, consecutive5xxErrors: 5 causes that Pod to be ejected from the pool for baseEjectionTime. Traffic is diverted to healthy Pods — this is the Envoy-style circuit breaker.
Fault injection is not about making a system fail, but about proving that the system can recover. The two main types: fault.delay (delays responses) and fault.abort (returns an error):
spec:
hosts:
- reviews
http:
- match:
- headers:
x-zone:
exact: chaos
fault:
delay:
percentage:
value: 100
fixedDelay: 5s
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1Requests with the x-zone: chaos header are delayed five seconds before reaching v2. This way you can observe how clients and downstream services handle high latency without damaging production.
To test total failure, use abort:
spec:
http:
- match:
- headers:
x-zone:
exact: chaos
fault:
abort:
percentage:
value: 50
httpStatus: 503
route:
- destination:
host: reviews
subset: v1fault.abort.httpStatus: 503 makes 50 percent of tagged requests fail with 503 — exactly the scenario retries and circuit breakers are expected to handle. Verify the effect through metrics:
kubectl get virtualservice reviews-routing -o yaml
curl -H "x-zone: chaos" http://reviews:9080/reviewsEpisode 7 made the mesh tough: retries with retry budgets, per-request timeouts, circuit breakers from the combination of connection pools and outlier detection, and fault injection to prove the system can recover from bad scenarios.
Key takeaways:
In the next episode, episode 8, we will look at the mesh from the measurement side: observability with metrics, logs, and tracing — the telemetry v2 pipeline, Prometheus metrics, distributed tracing with Jaeger, and Kiali and Grafana dashboards.