Skip to main content
This guide shows how to use Istio ServiceEntry to control outbound traffic from the mesh and how to route mesh-originating egress through an Istio Egress Gateway. Follow the steps below to:
  • Install Istio with outboundTrafficPolicy = REGISTRY_ONLY.
  • Observe behavior before and after automatic sidecar injection.
  • Create a ServiceEntry allowing egress to www.wikipedia.org.
  • Configure an Egress Gateway + DestinationRule + VirtualService to force mesh traffic through the egress gateway.
  • Verify traffic and inspect egress gateway logs.
Prerequisites:
  • kubectl configured with a cluster
  • Permissions to install Istio and create resources
  • istioctl available (instructions below)

1) Install Istio (set outboundTrafficPolicy to REGISTRY_ONLY)

Download the desired Istio release and add istioctl to your PATH:
Dump the demo profile to a file, edit it, and change the mesh config to REGISTRY_ONLY:
Update meshConfig.outboundTrafficPolicy.mode inside demo.yaml:
Install Istio using the modified profile:
Verify Istio system pods are running:
Be aware: REGISTRY_ONLY blocks outbound traffic to external services unless they’re registered with Istio (for example, via a ServiceEntry). Use ServiceEntry to explicitly allow specific external hosts when using this policy.

2) Create a test pod (nginx) and test connectivity before injection

Run a simple test pod. Note: the official nginx image may not include curl. If curl is missing, use a curl-enabled image (for example, curlimages/curl) or install curl in the pod. Create and exec into the pod:
From inside the container, test outbound access to Wikipedia (fetch headers only):
If the pod is not Istio-injected, you should see an HTTP 301 redirect and then 200 headers:
Exit the pod shell:

3) Enable automatic sidecar injection for the namespace and re-run the test

Label the default namespace for Istio automatic sidecar injection, then recreate the test pod:
With outboundTrafficPolicy = REGISTRY_ONLY and no ServiceEntry, the sidecar will block the external request. The sidecar returns a 502 Bad Gateway:
Exit the pod shell:
Labeling a namespace with istio-injection=enabled enables automatic sidecar injection for new pods in that namespace. Existing pods must be recreated to receive a sidecar.

4) Create a ServiceEntry for www.wikipedia.org to allow egress

Create a ServiceEntry in the same namespace as the test pod (default) to register www.wikipedia.org with Istio so sidecars can allow and route traffic. service_entry.yaml
Apply the ServiceEntry:
Exec into the test pod and retry the curl. With the ServiceEntry present, you should see 301 → 200 responses:

5) Configure an Egress Gateway, DestinationRule, and VirtualService

To route mesh-originating traffic through an Istio egress gateway, create three resources:
  • Gateway that selects the egress gateway pod (selector must match egress pod labels).
  • DestinationRule pointing to the egress gateway service/subset.
  • VirtualService that routes mesh traffic to the egress gateway and configures how the egress gateway forwards to the external host.
Confirm the egress gateway pod and labels:
Create the Gateway selecting the egress gateway (selector must match labels): gateway.yaml
Apply the Gateway:
Create a DestinationRule that points traffic to the egress gateway service from the default namespace: destinationrule.yaml
Apply the DestinationRule:
Now create the VirtualService that handles two routing phases:
  • mesh-originating requests: match gateways: [mesh] and route to the egress gateway service subset.
  • gateway-handled requests: match gateways: [istio-egressgateway] and forward to the external host.
virtualservice.yaml
Apply the VirtualService:

6) Verify traffic flows through the egress gateway and tail logs

Tail logs from the egress gateway deployment in one terminal (replace resource if different):
In another terminal, exec into the test pod and perform the request:
Expected results:
  • The test pod still sees the normal 301 → 200 responses.
  • Egress gateway logs include the forwarded request. Example Envoy log snippet:
Important: To force mesh-originating traffic through an Istio egress gateway, the VirtualService must include the mesh gateway in gateways and have a match for gateways: [mesh]. Without this, sidecar proxies are not instructed to route to the egress gateway and traffic may go directly to the Internet or be blocked by REGISTRY_ONLY.

7) Example: VirtualService without mesh vs with mesh

VirtualService that only lists the egress gateway (no mesh) — this handles requests arriving at the egress gateway but does not instruct pods inside the mesh to send requests to the gateway:
The VirtualService shown in step 5 (the virtualservice.yaml) includes mesh and explicitly routes mesh-originating traffic to the egress gateway before the gateway forwards it to the external host.

8) Notes, exam tips, and quick reference

  • ServiceEntry registers external services (DNS hosts, IPs, ranges) with Istio so sidecars will allow and route egress traffic when outbound policy is REGISTRY_ONLY.
  • Egress gateway pattern typically uses three resources:
    • Gateway: selects the egress proxy pod.
    • DestinationRule: targets the egress gateway service/subset.
    • VirtualService: routes mesh traffic to the gateway and gateway traffic to the external host.
  • For exams and real-world tasks: keep templates handy and update hosts, ports, resolution, and namespaces quickly.
  • Many orgs do not send all Internet traffic through an egress gateway, but doing so enables centralized monitoring, policy enforcement, and security controls.
Resources quick reference:

9) Useful ServiceEntry examples

ServiceEntry for multiple HTTPS external hosts:
ServiceEntry for external cluster with static endpoints:
Wildcard host ServiceEntry:

That wraps up ServiceEntry and egress gateway basics. Practice creating these manifests and verifying behavior by tailing egress gateway logs and testing from pods both with and without sidecar injection. Links and references:

Watch Video

Practice Lab