Aller au contenu

How to Route Kubernetes Egress Traffic Through a Proxy Using Istio (Step-by-Step Guide)

Sitemap

Want to secure and control outbound traffic from your Kubernetes apps? This guide will focus on the procedure of setting the egress traffic through a proxy using Istio but the legitimate and appropriate way, with the help of clean YAML, and with the use of realistic and even achievable configurations.

👉 if you’re not a Medium member, read this story for free, here==.==

Why This Guide Matters

In most cases of real-world Kubernetes deployments, especially in enterprise environments, one is forbidden to direct traffic to the internet immediately. This will necessitate the proxy that any traffic passes through first:

  • HTTP/S proxies
  • Corporate firewalls
  • Allow-list-based routing

This is where Istio’s Egress Gateway + ServiceEntry combo becomes essential.

This guide will teach you how to:

  • Configure Kubernetes to route outbound traffic through a proxy
  • Use Istio Egress Gateway to enforce policies
  • Avoid common pitfalls like IP-based routing

Perfect for: DevOps engineers, SREs, and Kubernetes practitioners working in regulated or security-conscious environments.

Use Case

Let’s assume you want all your pods to access api.github.com, but only through a corporate proxy at proxy.corp.internal:3128.

We will proceed to build it from the very beginning, the Istio way.

Step 1: Basic Kubernetes Deployment

We’ll begin with a basic Kubernetes deployment using a curl container to validate outbound network traffic.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
        - name: app
          image: curlimages/curl
          command: ["sleep", "infinity"]

Step 2: Enable Istio Sidecar Injection

Sidecar injection is the key to unlocking Istio’s traffic control, it lets you intercept, inspect, and route outbound traffic with precision.

kubectl label namespace default istio-injection=enabled

Redeploy your pods afterward so sidecars get injected.## 🚀 8 FREE DevOps Labs That’ll Actually Make You Better — Not Just Busy

When attempting to get into DevOps or enhance what you already have, free or low-cost alternatives are as good as the…

medium.com

View original## I Passed the CKA and Created a Free Kubernetes Lab Book With 20+ Exam-Style Scenarios

🆓 Not a Medium member? You can still read this full story for free — no paywall, no catch. 👉 Click here to access it…

medium.com

View original

DevOpsDynamo

Istio Learning List

View list

7 stories

Step 3: Define a ServiceEntry

This tells Istio which external domains are allowed and how to treat them.

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: allow-github
spec:
  hosts:
    - api.github.com
  location: MESH_EXTERNAL
  ports:
    - number: 443
      name: https
      protocol: HTTPS
  resolution: DNS

Step 4: Configure the Istio Egress Gateway

The Egress Gateway acts as your traffic exit point, and where the proxy logic kicks in.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: egressgateway
  servers:
    - port:
        number: 443
        name: https
        protocol: HTTPS
      hosts:
        - api.github.com

Step 5: Route Traffic Through the Gateway

Use a VirtualService to explicitly route traffic for GitHub through the egress gateway.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: github-egress
spec:
  hosts:
    - api.github.com
  gateways:
    - istio-egressgateway
  tls:
    - match:
        - port: 443
          sniHosts:
            - api.github.com
      route:
        - destination:
            host: api.github.com
            port:
              number: 443

Step 6: Originate TLS at Gateway (Best Practice)

This ensures TLS handshake happens at the gateway level, not in the pod.

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: tls-github
spec:
  host: api.github.com
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL

Optional: Add Explicit Proxy Env Variables (Non-Istio)

If your pods need to route via HTTP_PROXY directly:

env:
  - name: HTTP_PROXY
    value: http://proxy.corp.internal:3128
  - name: HTTPS_PROXY
    value: http://proxy.corp.internal:3128
  - name: NO_PROXY
    value: localhost,127.0.0.1,.svc.cluster.local

This works outside of Istio, but is less controllable for multi-tenant clusters.## The CKA Exam Changed After February 18 — Here’s What You Actually Need to Practice Now

For the Certified Kubernetes Administrator (CKA) exam in 2025, the main thing you need is not just to memorize…

medium.com

View original## Kubernetes Deployment Best Practices That Actually Work in Production

Kubernetes is a powerful tool if employed on purpose. Throwing together YAML files and hoping your app survives…

medium.com

View original

Step 7: Test It

kubectl exec -it <pod-name> -- curl https://api.github.com

Monitor your proxy logs or Istio telemetry (istioctl proxy-config) to confirm traffic flow.

Wrap-Up

You have now acquired the various setup methods of:

  • Set up Kubernetes egress routing
  • Use Istio Egress Gateway to control outbound access
  • Enforce traffic through a secure proxy

This setup is battle-tested in production environments and makes your cluster network policies compliant, observable, and secure.

What’s Next?

👉 In Part 3, we’ll cover:

  • How to enforce outbound mTLS
  • Handle DNS wildcards
  • And route multiple domains through different proxies

Found this helpful?

  • Clap 👏 and follow for more no-fluff Kubernetes + Istio content.

P.S: For anyone digging into Istio routing, this deep dive by Guy Saar is gold.

📘 Conquer the CKA Exam 🔥 40% OFF with JANUARY26 (valid January 17–18 only) Gumroad: devopsdynamo.gumroad.com/l/Conquer-cka-exam Payhip: payhip.com/b/3iAsH

More from DevOpsDynamo

[

See more recommendations

](https://medium.com/?source=post_page---read_next_recirc--d76879410e01---------------------------------------)