원클릭으로
eg-service-mesh
Integrate Envoy Gateway with Istio ambient mesh or Cilium for unified ingress and service mesh
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Integrate Envoy Gateway with Istio ambient mesh or Cilium for unified ingress and service mesh
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Configure client-facing traffic policies -- timeouts, connection limits, TLS settings, HTTP behavior
Production-grade Envoy Gateway setup with comprehensive security, observability, high availability, and operational best practices
Envoy Gateway version information, compatibility matrix, and upgrade readiness checks
Envoy AI Gateway contribution orchestrator — interviews you about your contribution and guides you through the correct workflow using contributor skills
Envoy Gateway contribution orchestrator — interviews you about your contribution and guides you through the correct workflow using contributor skills
Operational patterns for Kubernetes controllers — leader election, RBAC, finalizer safety, Server-Side Apply, extension hooks, credential rotation, and drift detection
| name | eg-service-mesh |
| description | Integrate Envoy Gateway with Istio ambient mesh or Cilium for unified ingress and service mesh |
You help developers integrate Envoy Gateway with their service mesh (Istio or Cilium) for a unified traffic management experience. You assess the current state, configure the integration, and address the known challenges of running Envoy Gateway alongside a service mesh.
Before generating any configuration, ask the user these questions. Skip questions the user has already answered. Ask in a conversational tone, grouping related questions when it makes sense.
Service mesh: Which service mesh are you using?
Current state: Is the service mesh already installed, or are you setting up both?
Gateway role: Do you want Envoy Gateway as the ingress only, or also as a waypoint proxy for the mesh?
mTLS: Do you need mTLS between the gateway and mesh-managed services?
Observability: What observability integration do you need?
Check the cluster state to understand what is already installed.
# Check if Istio is installed
kubectl get namespace istio-system 2>/dev/null && echo "Istio namespace exists" || echo "No Istio namespace"
# Check Istio version and mode
istioctl version 2>/dev/null || echo "istioctl not found"
# Check for ambient mode (ztunnel DaemonSet)
kubectl get daemonset -n istio-system ztunnel 2>/dev/null && echo "Ambient mode detected" || echo "Ambient mode not detected"
# Check for sidecar injection
kubectl get namespace -l istio-injection=enabled 2>/dev/null
# Check if Envoy Gateway is already installed
kubectl get namespace envoy-gateway-system 2>/dev/null && echo "Envoy Gateway namespace exists" || echo "No EG namespace"
helm list -n envoy-gateway-system 2>/dev/null
Envoy Gateway and Istio can coexist in the same cluster. They use different controller names and manage different GatewayClass resources.
Use the /eg-install skill to install Envoy Gateway:
helm install eg oci://docker.io/envoyproxy/gateway-helm \
--version v1.7.0 \
-n envoy-gateway-system \
--create-namespace
Verify both GatewayClasses exist and are accepted:
# Envoy Gateway's GatewayClass
kubectl get gatewayclass eg -o jsonpath='{.status.conditions[?(@.type=="Accepted")].status}'
# Expected: True
# Istio's GatewayClass (if using Istio's Gateway API implementation)
kubectl get gatewayclass istio -o jsonpath='{.status.conditions[?(@.type=="Accepted")].status}' 2>/dev/null
Important: Envoy Gateway and Istio use different GatewayClass resources. Routes attached to a Gateway with gatewayClassName: eg are managed by Envoy Gateway. Routes attached to a Gateway with gatewayClassName: istio are managed by Istio. They do not conflict.
The traffic path differs significantly between Istio sidecar mode and ambient mode.
In sidecar mode, traffic flows through a double-proxy chain:
Client -> Envoy Gateway Proxy -> Istio Sidecar -> Application Pod
The Envoy Gateway proxy handles north-south concerns (TLS termination, auth, rate limiting), and the Istio sidecar handles east-west concerns (mTLS, authorization policy, telemetry).
Gateway configuration (sidecar mode):
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: eg
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: ingress-gw
namespace: gateway-system # TODO: Replace with your namespace
spec:
gatewayClassName: eg # Managed by Envoy Gateway, NOT Istio
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: "*.example.com" # TODO: Replace
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: wildcard-tls
allowedRoutes:
namespaces:
from: All
Sidecar injection for the Envoy Gateway proxy itself:
By default, Istio may inject a sidecar into the Envoy Gateway proxy pods. This creates an unnecessary triple-proxy scenario. Disable sidecar injection for the Envoy Gateway namespace:
kubectl label namespace envoy-gateway-system istio-injection=disabled --overwrite
Or use pod annotations on the EnvoyProxy resource:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: no-sidecar-proxy
namespace: envoy-gateway-system
spec:
provider:
type: Kubernetes
kubernetes:
envoyDeployment:
pod:
annotations:
sidecar.istio.io/inject: "false"
In ambient mode, there are no sidecars. Traffic flows through the ztunnel (L4) and optional waypoint proxies (L7):
Client -> Envoy Gateway Proxy -> ztunnel -> Application Pod
Or with a waypoint proxy:
Client -> Envoy Gateway Proxy -> ztunnel -> Waypoint Proxy -> Application Pod
Envoy Gateway can also serve as a waypoint proxy in ambient mode, providing a unified Envoy-based data plane for both ingress and in-mesh L7 processing.
Use the same Gateway configuration as sidecar mode above (the Gateway resource is identical for both modes).
Enroll the application namespace in ambient mesh:
kubectl label namespace app-namespace istio.io/dataplane-mode=ambient
Configure the Envoy Gateway proxy to participate in the mesh's mTLS identity or to trust the mesh CA.
Use BackendTLSPolicy so Envoy Gateway trusts the Istio CA when connecting to mesh-managed backends:
# First, export the Istio root CA certificate
kubectl get secret istio-ca-secret -n istio-system -o jsonpath='{.data.ca-cert\.pem}' | base64 -d > istio-root-ca.pem
# Create a ConfigMap with the Istio CA cert in the backend namespace.
# BackendTLSPolicy.caCertificateRefs is a LocalObjectReference, so the
# ConfigMap must live in the same namespace as the BackendTLSPolicy.
kubectl create configmap istio-root-ca \
--from-file=ca.crt=istio-root-ca.pem \
-n app-namespace # TODO: Replace with backend namespace
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: mesh-backend-tls
namespace: app-namespace # TODO: Replace with backend namespace
spec:
targetRefs:
- group: ""
kind: Service
name: my-app-service # TODO: Replace with your backend service
sectionName: "8080" # TODO: Replace with your service port name
validation:
caCertificateRefs:
- group: ""
kind: ConfigMap
name: istio-root-ca
hostname: my-app-service.app-namespace.svc.cluster.local # TODO: Replace with SPIFFE-compatible hostname
In Istio ambient mode, enroll the Envoy Gateway proxy namespace in the mesh so the ztunnel handles mTLS automatically:
kubectl label namespace envoy-gateway-system istio.io/dataplane-mode=ambient
This allows the Envoy Gateway proxy to communicate with mesh services through the ztunnel, which handles the mTLS handshake transparently.
Configure Envoy Gateway and Istio to use the same observability backends for correlated telemetry.
Both Envoy Gateway and Istio support OpenTelemetry. Configure them to export traces to the same collector.
Envoy Gateway tracing (via EnvoyProxy):
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: mesh-integrated-proxy
namespace: envoy-gateway-system
spec:
telemetry:
tracing:
provider:
host: otel-collector.observability.svc.cluster.local # TODO: Replace
port: 4317
type: OpenTelemetry
samplingRate: 100 # TODO: Match Istio's sampling rate
customTags:
mesh.component:
type: Literal
literal:
value: "envoy-gateway"
Istio tracing (via MeshConfig or Telemetry API):
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
name: mesh-tracing
namespace: istio-system
spec:
tracing:
- providers:
- name: otel
randomSamplingPercentage: 100 # TODO: Match EG's sampling rate
Important: Both Envoy Gateway and Istio must propagate the same trace context headers (traceparent, tracestate for W3C Trace Context, or x-b3-* for Zipkin B3). Ensure your application also propagates these headers for end-to-end trace correlation.
Add Prometheus scrape annotations to the EnvoyProxy resource (prometheus.io/scrape: "true", prometheus.io/port: "19001") and enable enableVirtualHostStats: true in spec.telemetry.metrics. Istio metrics are already scraped by Prometheus if installed with default monitoring. Envoy Gateway metrics (prefixed with envoy_) can be correlated with Istio metrics by upstream/downstream cluster names.
Address the known challenges of running Envoy Gateway with a service mesh.
In Istio sidecar mode, traffic passes through two Envoy proxies: the Envoy Gateway proxy and the Istio sidecar. This adds latency (typically 1-3ms per hop) and complicates debugging.
Mitigations:
Envoy Gateway and Istio both provide L7 traffic management features (routing, auth, rate limiting). Establish clear ownership:
| Concern | Owner | Rationale |
|---|---|---|
| TLS termination | Envoy Gateway | Edge responsibility |
| External authentication (JWT, OIDC) | Envoy Gateway | North-south concern |
| Rate limiting | Envoy Gateway | Edge protection |
| mTLS between services | Istio | East-west concern |
| Service-to-service authorization | Istio | Mesh identity-based |
| Retries, circuit breaking | Either | Choose one to avoid double retries |
Important: Do not configure retries in both Envoy Gateway and Istio for the same request path. This causes retry amplification (e.g., 3 retries x 3 retries = 9 total attempts). Choose one layer for retry logic.
As of Envoy Gateway v1.7.0, there is no native service mesh integration feature. The integration patterns described here use standard Kubernetes networking and Gateway API resources. For updates on native integration, see GitHub issue #7500 in the Envoy Gateway repository.
Istio ambient mode provides the best integration path because:
# Check if Cilium is installed
kubectl get pods -n kube-system -l k8s-app=cilium
cilium status 2>/dev/null || echo "Cilium CLI not found"
# Check Cilium version and features
kubectl get configmap cilium-config -n kube-system -o yaml 2>/dev/null | grep -E "enable-|kube-proxy"
Envoy Gateway works alongside Cilium as the CNI. If Cilium is providing LoadBalancer IPs via BGP, configure the EnvoyProxy to use Cilium's LoadBalancer class.
helm install eg oci://docker.io/envoyproxy/gateway-helm \
--version v1.7.0 \
-n envoy-gateway-system \
--create-namespace
If using Cilium BGP for LoadBalancer IP allocation:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: cilium-proxy
namespace: envoy-gateway-system
spec:
provider:
type: Kubernetes
kubernetes:
envoyService:
# Use Cilium's BGP control plane for LoadBalancer IP allocation
loadBalancerClass: io.cilium/bgp-control-plane # TODO: Only if using Cilium BGP
Cilium's eBPF datapath handles L4 traffic very efficiently (kernel-level packet processing). Envoy Gateway adds L7 capabilities on top.
Architecture:
Client -> Cilium eBPF (L3/L4) -> Envoy Gateway Proxy (L7) -> Cilium eBPF (L3/L4) -> Application Pod
When to use Envoy Gateway vs Cilium's built-in L7:
Cilium also has its own Gateway API implementation (CEC - Cilium Envoy Config). If you only need basic HTTP routing, Cilium's built-in Gateway API support may be sufficient. Use Envoy Gateway when you need the full Envoy Gateway extension CRDs (SecurityPolicy, BackendTrafficPolicy, ClientTrafficPolicy, EnvoyExtensionPolicy).
Cilium NetworkPolicies complement Envoy Gateway SecurityPolicies at different layers.
Cilium NetworkPolicy (L3/L4):
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-gateway-to-app
namespace: app-namespace # TODO: Replace
spec:
endpointSelector:
matchLabels:
app: my-app # TODO: Replace with your app labels
ingress:
- fromEndpoints:
- matchLabels:
# Allow traffic only from Envoy Gateway proxy pods
gateway.envoyproxy.io/owning-gateway-name: ingress-gw # TODO: Replace
toPorts:
- ports:
- port: "8080"
protocol: TCP
For L7 authentication and authorization, use the /eg-auth skill to create SecurityPolicy resources targeting your HTTPRoutes.
Defense in depth: Use Cilium NetworkPolicies for L3/L4 network restrictions and Envoy Gateway SecurityPolicies for L7 authentication/authorization. This ensures that even if one layer is misconfigured, the other provides protection.
Cilium provides Hubble for network-level observability. Combine Hubble with Envoy Gateway's telemetry for full-stack visibility.
# Enable Hubble (if not already enabled)
cilium hubble enable --ui
# Observe traffic flowing through the gateway
hubble observe --namespace app-namespace --protocol http
Configure Envoy Gateway to export metrics and traces alongside Cilium:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: cilium-proxy
namespace: envoy-gateway-system
spec:
telemetry:
metrics:
enableVirtualHostStats: true
sinks:
- type: OpenTelemetry
openTelemetry:
host: otel-collector.observability.svc.cluster.local # TODO: Replace
port: 4317
tracing:
provider:
host: otel-collector.observability.svc.cluster.local # TODO: Replace
port: 4317
type: OpenTelemetry
samplingRate: 10 # TODO: Adjust for production
Generate a complete set of Kubernetes manifests for the chosen integration:
v1.7.0).gateway.networking.k8s.io/v1 for Gateway API resources and gateway.envoyproxy.io/v1alpha1 for Envoy Gateway extension CRDs.