How Do You Control Egress Traffic in Kubernetes?
Egress traffic control restricts which external destinations Pods can reach. Implementation options include Network Policy egress rules (IP-based), Cilium DNS-based egress policies, Istio ServiceEntries and egress gateways, and cloud-native NAT gateways. This prevents data exfiltration and limits the blast radius of compromised Pods.
Detailed Answer
Controlling egress (outbound) traffic is a critical security measure that prevents compromised Pods from communicating with external command-and-control servers, exfiltrating data, or accessing unauthorized APIs.
Why Egress Control Matters
Without egress restrictions, a compromised Pod can:
- Send stolen data to any external server
- Download malware from the internet
- Communicate with command-and-control infrastructure
- Access unauthorized cloud APIs using stolen credentials
- Mine cryptocurrency using cluster compute resources
Approach 1: Network Policy Egress Rules
The simplest approach, using standard Kubernetes Network Policies:
# Default deny all egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
---
# Allow DNS
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
---
# Allow specific external IPs (e.g., payment processor)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-stripe
namespace: production
spec:
podSelector:
matchLabels:
app: payment-service
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 35.232.0.0/16 # Stripe's IP range (example)
ports:
- protocol: TCP
port: 443
Limitation: IP-based filtering breaks when cloud service IPs change.
Approach 2: Cilium DNS-Based Egress
Cilium allows egress filtering by domain name:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-external-apis
namespace: production
spec:
endpointSelector:
matchLabels:
app: payment-service
egress:
- toFQDNs:
- matchName: "api.stripe.com"
- matchName: "api.sendgrid.com"
- matchPattern: "*.amazonaws.com"
toPorts:
- ports:
- port: "443"
protocol: TCP
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
This allows outbound HTTPS only to api.stripe.com and api.sendgrid.com — regardless of their IP addresses.
Approach 3: Istio Egress Gateway
An egress gateway centralizes all outbound traffic through a dedicated proxy:
# Define the external service
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: stripe-api
namespace: production
spec:
hosts:
- api.stripe.com
ports:
- number: 443
name: https
protocol: TLS
resolution: DNS
location: MESH_EXTERNAL
---
# Route through the egress gateway
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: stripe-via-egress
namespace: production
spec:
hosts:
- api.stripe.com
gateways:
- istio-system/istio-egressgateway
- mesh
tls:
- match:
- gateways:
- mesh
port: 443
sniHosts:
- api.stripe.com
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
port:
number: 443
- match:
- gateways:
- istio-system/istio-egressgateway
port: 443
sniHosts:
- api.stripe.com
route:
- destination:
host: api.stripe.com
port:
number: 443
Benefits of egress gateways:
- Centralized logging of all outbound traffic
- Fixed source IP for external API whitelisting
- TLS origination for plain HTTP backends
- Rate limiting on outbound requests
Approach 4: Cloud NAT Gateway
For cloud environments, route all egress through a NAT gateway:
Pods → Cluster Network → NAT Gateway → Internet
│
Fixed IP
(for IP whitelisting)
This provides a fixed source IP but does not offer per-service filtering within the cluster.
Egress Control Comparison
| Feature | Network Policy | Cilium FQDN | Istio Egress GW | Cloud NAT | |---|---|---|---|---| | IP-based filtering | Yes | Yes | Yes | No | | DNS-based filtering | No | Yes | Yes | No | | L7 filtering | No | Partial | Yes | No | | Logging | CNI-dependent | Yes | Yes | Yes | | Fixed source IP | No | No | Yes | Yes | | Complexity | Low | Medium | High | Low |
Best Practice: Layered Approach
Combine multiple approaches for defense in depth:
Layer 1: Default-deny egress Network Policy (blocks everything)
Layer 2: DNS-based allow rules (Cilium FQDN policies)
Layer 3: Egress gateway for audit logging
Layer 4: Cloud NAT for fixed source IP
Layer 5: IDS/IPS monitoring for anomalous traffic
Monitoring Egress
# With Cilium — monitor DNS-based egress
cilium monitor --type drop --to-identity world
# With Istio — check egress gateway logs
kubectl logs -n istio-system -l app=istio-egressgateway
# Alert on unexpected egress destinations
# Configure Prometheus alerts for new destination IPs/domains
Why Interviewers Ask This
Interviewers ask this to assess whether you understand outbound traffic security — a critical defense against data exfiltration, command-and-control communication, and supply chain attacks.
Common Follow-Up Questions
Key Takeaways
- Default-deny egress combined with explicit allow rules is the foundation of egress control.
- DNS-based egress filtering (Cilium, Istio) is more practical than IP-based filtering for cloud APIs.
- Egress gateways centralize outbound traffic for logging, monitoring, and IP whitelisting.