Demo of Istio VirtualService fault injection (delay and abort) to simulate latency and failures, with step-by-step examples, testing commands, and best-practice guidance.
Use this file to discover all available pages before exploring further.
In this lesson you’ll implement two Istio fault-injection patterns: a delay and an abort. These traffic-shaping capabilities are applied at the VirtualService level to simulate latency and failures so you can observe and validate how your application behaves under adverse conditions.Prerequisites
A Kubernetes cluster with Istio installed.
The target namespace must be labeled for Istio sidecar injection (the example uses the default namespace).
Ensure your namespace is labeled for Istio sidecar injection before deploying sample apps. You can label a namespace with:
root@controlplane ~ ➜ kubectl get ns --show-labelsNAME STATUS AGE LABELSdefault Active 21m istio-injection=enabled,kubernetes.io/metadata.name=defaultistio-system Active 51s kubernetes.io/metadata.name=istio-systemkube-node-lease Active 21m kubernetes.io/metadata.name=kube-node-leasekube-public Active 21m kubernetes.io/metadata.name=kube-publickube-system Active 21m kubernetes.io/metadata.name=kube-system
Deploy the helloworld sample app and confirm resources are created
root@controlplane ~ ➜ kubectl apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/helloworld/helloworld.yamlservice/helloworld createddeployment.apps/helloworld-v1 createddeployment.apps/helloworld-v2 created
Create a test Pod (a utility pod with curl that stays running)
root@controlplane ~ ➜ kubectl run test --image=curlimages/curl --command -- sleep 1dpod/test created
Fault injection is configured on VirtualService HTTP routes. DestinationRule is used for connection-level settings (circuit breaking, TLS settings, subsets), not for HTTP fault injection.
Confirm there are no existing VirtualServices or DestinationRules for this service
root@controlplane ~ ➜ kubectl get vsNo resources found in default namespace.root@controlplane ~ ➜ kubectl get destinationrules.networking.istio.ioNo resources found in default namespace.
Fault injection patterns overview
Fault type
Purpose
VirtualService snippet / example file
Delay
Simulate added latency (fixed or percentage of traffic)
Modify the VirtualService to abort requests with a chosen HTTP error status. The example below returns HTTP 500 for 100% of requests; save it as vs-abort-500.yaml:
Run a short loop from the test pod to observe a mix of 200 and 404 responses:
root@controlplane ~ ➜ kubectl exec -ti test -- /bin/sh -c 'for i in $(seq 1 10); do curl --head helloworld.default.svc:5000/hello; echo "----" ; done'
Sample mixed output (200 and 404 responses interleaved):
HTTP/1.1 200 OKserver: envoydate: Tue, 15 Apr 2025 15:59:21 GMTcontent-type: text/html; charset=utf-8content-length: 59x-envoy-upstream-service-time: 119----HTTP/1.1 404 Not Foundcontent-length: 18content-type: text/plaindate: Tue, 15 Apr 2025 15:59:21 GMTserver: envoy----# ...and so on
Partial delays
You can apply delays to a percentage of traffic the same way you apply partial aborts — replace the abort section with the delay configuration and specify the percentage.
When you hear “fault injection” think “VirtualService”. Fault injection (delay and abort) is configured on VirtualService HTTP routes. Circuit breaking and connection-level settings belong in DestinationRule.