Skip to main content
In this demo we configure a simple Istio VirtualService for an httpbin sample app. VirtualServices are a core Istio resource — they control how requests are routed within the mesh and are required by many other features (gateways, retries, rewrites, etc.). This walkthrough covers:
  • Verifying Istio injection
  • Deploying httpbin
  • Creating a test pod in a separate namespace
  • Creating and applying a VirtualService
  • Demonstrating how namespace injection affects routing
  • URL rewrites
  • Quick reference of common VirtualService features

1. Verify Istio injection in namespaces

Check namespace labels to see whether istio-injection is enabled:
Example output:

2. Deploy the httpbin sample app

Deploy the httpbin sample from the Istio repository:
Confirm the httpbin pod is running and has a sidecar (2/2 ready):
Example:

3. Create a separate namespace and a test pod

Create a test namespace and run a simple nginx pod there:
Example pod status (without injection):
A 1/1 READY means the Istio sidecar is not injected into this pod. We’ll use this to demonstrate how VirtualService behavior depends on sidecar injection.

4. Test connectivity from the non-injected test pod

Exec into the test pod and curl the httpbin service in the default namespace:
Example responses:
Note: By default Istio is permissive — services can communicate across namespaces unless you enable stricter mTLS policies or other restrictions.
If a pod’s namespace is not labeled for istio-injection, its traffic does not traverse the Envoy sidecar. VirtualService rules apply only when traffic routes through the sidecar.

5. Create the first VirtualService

Create vs.yaml defining a VirtualService that routes httpbin traffic to the httpbin service on port 8000:
Apply it:
Example:
This VirtualService mirrors the existing Kubernetes service behavior (no changes yet), so requests routed through an Envoy sidecar will hit the service as before.

6. Break the VirtualService (for demonstration)

Edit the VirtualService and change the destination port to 9000 to intentionally misroute requests:
Apply the modified VirtualService:
If you curl from the test pod now you may still see it working — why?
  • If the test pod’s namespace is not Istio-injection-enabled (1/1 Ready), its traffic bypasses Envoy and the VirtualService has no effect. The traffic goes directly to the Kubernetes service which listens on port 8000, so the request succeeds.
  • Once the test namespace has injection enabled and the pod is re-created with the sidecar (2/2), the VirtualService will intercept the traffic and route it to port 9000 — which the service is not listening on — resulting in a 503 Service Unavailable.

7. Enable Istio injection for the test namespace and re-create the pod

You can use istioctl analyze to get hints and then label the namespace:
After labeling, delete the test pod so it gets re-created with a sidecar:
You should now see 2/2:
Now exec into the pod and curl the httpbin service:
With the VirtualService pointing to port 9000 you will see a 503 Service Unavailable. Fix the VirtualService back to port 8000 and apply:
Requests should succeed again.
When you enable istio-injection=enabled on a namespace, existing pods must be re-created (deleted) to get the Envoy sidecar injected. Labeling alone is not sufficient — restart the pods.

8. URL rewrites with VirtualService

You can add a rewrite rule in the VirtualService. Example: rewrite /hello to / and route to httpbin:
Test steps:
  1. Before applying the rewrite, curl httpbin.default.svc:8000/hello returns 404 page not found (no /hello endpoint).
  2. Apply the VirtualService with the rewrite:
  3. After applying, curl httpbin.default.svc:8000/hello returns the root endpoint as if you requested /.
This shows how VirtualService can transform request URIs before routing to the service.

9. Quick reference: common VirtualService capabilities

The following table summarizes common VirtualService patterns and short YAML samples. Representative YAML examples:
  • DestinationRule with subsets:
  • VirtualService with a timeout:
  • ServiceEntry for external hosts:
  • VirtualService with header-based match and URI prefix:
  • VirtualService with retries:

10. Final notes & references

  • VirtualServices are foundational: you will use them extensively together with DestinationRules, Gateways, and Policies.
  • In exam / production scenarios, copy the YAML snippets from the official docs and adapt them — you are expected to reference documentation rather than memorize every field.
  • Always ensure the namespace/pod you are testing from is injection-enabled if you want VirtualService rules to be enforced by the Envoy sidecar.
Useful links: This concludes the VirtualService demo. Next up: DestinationRules and advanced traffic management.

Watch Video

Practice Lab