Circuit Breaking Using Istio¶
Circuit breaking is an important pattern for creating resilient microservice applications. Circuit breaking allows you to write applications that limit the impact of failures, latency spikes, and other undesirable effects of network peculiarities.
circuit breaking in Istio is handled by DestinationRule
.
How Does Circuit Breaker Work?¶
A circuit breaker typically operates in three main states: Closed
, Open
, and Half-Open
.
-
Closed
Normal operation, requests pass through, system monitors for issues.
If requests are successful, it remains in the
Closed
state. However, if the Failure Threshold is exceeded, it transitions to theOpen
state. -
Open
Detected issue, blocks all incoming requests immediately.
Once in the
Open
state, the circuit breaker undergoes a reset after a pre-defined delay. Following the reset, it transitions to theHalf-Open
state. -
Half-Open
Testing phase, allows limited requests to check if the issue is resolved before deciding to fully reopen or stay closed.
If the request is successful, it transitions to the
Closed
state; if unsuccessful, it transitions back to theOpen
state.
Let's see it in action!
Step 1: Deploy Application¶
First, let's deploy the application and other Istio components:
Make sure to replace the value of external-dns.alpha.kubernetes.io/target
annotation in virtual service with the istio load balancer DNS.
Note
The reyanshkharga/nodeapp:buggy
application intermittently throws an intentional error with HTTP status code 502
.
Assuming your folder structure looks like the one below:
|-- manifests
│ |-- 00-namespace.yml
│ |-- nodeapp-deployment.yml
│ |-- nodeapp-service.yml
│ |-- gateway.yml
│ |-- destination-rule.yml
│ |-- virtual-service.yml
Let's apply the manifests to create the kubernetes and istio objects:
Verify if the istio proxies are created for the application:
# Retrieve proxy configuration
istioctl proxy-config routes svc/istio-ingressgateway -n istio-system
Step 2: Generate Traffic Using Fortio¶
Fortio is a fast, small (4Mb docker image, minimal dependencies), reusable, embeddable go library as well as a command line tool and server process, the server includes a simple web UI and REST API to trigger run and see graphical representation of the results (both a single latency graph and a multiple results comparative min, max, avg, qps and percentiles graphs).
Deploy a fortio pod as follows:
Now, let's generate traffic on our nodeapp service using fortio as follows:
# Set fortio pod name
export FORTIO_POD=traffic-generator
# Call nodeapp service using fortio pod (Try this multiple times)
kubectl exec $FORTIO_POD -n circuit-breaker -c fortio -- /usr/bin/fortio curl -quiet http://nodeapp-service
You'll notice that as soon as the application throws a 5xx
error (502
in this case), the circuit breaker outlier detector ejects the pod from the load balancing pool for specified baseEjectionTime
and in that time period all the requests fail. This is circuit breaking in action.
Wait for baseEjectionTime
and try again.
Step 3: View Prometheus Metrics¶
You can see the UO (upstream overflow)
metric in prometheus using the following query:
sum(istio_requests_total{destination_app="nodeapp", source_app="traffic-generator"}) by (response_code, response_flags, source_app)
U0
flag indicates that requests were rejected due to circuit breaker configuration.
Clean Up¶
Assuming your folder structure looks like the one below:
|-- manifests
│ |-- 00-namespace.yml
│ |-- nodeapp-deployment.yml
│ |-- nodeapp-service.yml
│ |-- gateway.yml
│ |-- destination-rule.yml
│ |-- virtual-service.yml
│ |-- fortio-traffic-generator.yml
Let's delete all the kubernetes and istio resources we created: