As cloud architectures evolve from single-provider footprints into dynamic, multi-cloud Kubernetes environments spanning AWS EKS, GCP GKE, and Azure AKS, the traditional security perimeter has effectively collapsed. Microservices dynamically scale, IP addresses become hyper-ephemeral, and cross-cloud traffic routes over untrusted public transit networks.
To secure these environments, adopting a Zero-Trust Architecture (ZTA)—operating on the principle of "never trust, always verify"—is no longer optional. However, the first generation of Zero-Trust implementations heavily relied on user-space sidecar proxy patterns (e.g., Envoy-based service meshes). While feature-rich, sidecar proxies impose severe penalties: substantial memory overhead, CPU bloat per pod, added P99 latency due to repeated user/kernel-space context switches, and complex proxy lifecycle management.
At Ecstaticloud, we have moved beyond sidecar proxies by leveraging eBPF (Extended Berkeley Packet Filter). By dropping security enforcement and network visibility directly into the Linux kernel, we achieve granular L3-L7 identity-aware security, cross-cloud packet encryption, and real-time observability—at native kernel speeds.
This post breaks down how to architect and implement an eBPF-driven Zero-Trust security layer across multi-cloud Kubernetes clusters using Cilium and Tetragon.
1. Why eBPF is Disrupting Service Meshes and Security
To understand why eBPF is superior for Zero-Trust enforcement, we must examine the path a network packet takes in both paradigms.
Traditional Sidecar Proxy Approach:
[Pod A App] <-> [Envoy Proxy] -> (iptables) -> [Kernel Network Stack] -> [Wire] -> [Kernel] -> (iptables) -> [Envoy Proxy] <-> [Pod B App]
Context switches: 4 per hop | High CPU & Latency Overhead
eBPF Direct-Path Approach:
[Pod A App] -------------------> [Linux Kernel / eBPF Engine] -------------------> [Wire] -------------------> [Linux Kernel / eBPF Engine] -------------------> [Pod B App]
Context switches: 0 extra | Sub-millisecond latency | Zero Sidecars
The Limits of Sidecars & iptables
- Memory & CPU Taxes: Running a proxy container alongside every workload pod consumes 30MB–100MB RAM per replica. In a cluster with 5,000 pods, you waste hundreds of gigabytes of RAM just on security sidecars.
- Context Switching Overhead: Packets travel from socket to user-space Envoy proxy, back to kernel space, across the wire, and reverse the process at the destination.
iptablesScalability Limits: Traditional Kubernetes CNI networks rely oniptablesorIPVSrules. As services scale into tens of thousands of endpoints,$ iptables -Llinear evaluation causes $O(N)$ lookup degradation and severe kernel locks during updates.
The eBPF Advantage
eBPF allows developers to run sandboxed, bytecode programs directly within the Linux kernel without changing kernel source code or loading kernel modules.
- eXpress Data Path (XDP): Runs eBPF programs at the network driver level before memory allocation (
sk_buff), allowing instant packet dropping or line-rate filtering. - Socket Programs (
sockmap): Bypasses the TCP/IP stack entirely for local pod-to-pod or pod-to-proxy communications, piping data directly socket-to-socket. - Identity Over IP: eBPF maps numeric security identities to pods based on Kubernetes metadata (labels, namespaces, service accounts) rather than relying on brittle IP addresses.
2. Multi-Cloud Zero-Trust Architecture Overview
Our target architecture links an AWS EKS cluster (us-east-1) with a GCP GKE cluster (us-central1) into a single logical security fabric using Cilium ClusterMesh.
+------------------------------------+ +------------------------------------+
| AWS EKS (us-east-1) | | GCP GKE (us-central1) |
| +------------------------------+ | | +------------------------------+ |
| | Payment Microservice | | | | Analytics Microservice | |
| | Label: app=payment | | | | Label: app=analytics | |
| | Identity ID: 1045 | | | | Identity ID: 2091 | |
| +--------------+---------------+ | | +--------------^---------------+ |
| | | | | |
| [eBPF Engine] | | [eBPF Engine] |
| | | | | |
+-----------------|------------------+ +-----------------|------------------+
| |
+==== Native WireGuard Encrypted Tunnel =====+
(Enforced via Kernel eBPF BPF_MAP)
Core Components
- Cilium CNI with
kube-proxyReplacement: Completely removeskube-proxyandiptablesin favor of eBPF maps for K8s Service load balancing. - Cilium ClusterMesh: Synchronizes endpoint identity definitions across multi-cloud control planes via an optimized etcd kvstore mesh.
- Transparent Kernel Encryption: Node-to-node and pod-to-pod traffic between clouds is encrypted on-the-fly using kernel-level WireGuard.
- Tetragon (eBPF Runtime Security): Monitors process executions, system calls, and file access at the kernel layer to prevent supply-chain and runtime attacks.
3. Step-by-Step Implementation Guide
Step 1: Cluster Preparation & Prerequisites
Ensure both AWS EKS and GCP GKE clusters have direct network connectivity via cloud VPC Peering, AWS Transit Gateway, or a dedicated Interconnect. Pod CIDRs between clusters must not overlap.
- Cluster A (EKS): Pod CIDR
10.200.0.0/16 - Cluster B (GKE): Pod CIDR
10.201.0.0/16
Step 2: Deploy Cilium with Kube-Proxy Replacement on AWS EKS
Deploy Cilium using Helm, opting into full eBPF host routing and direct server return (DSR) to completely bypass kube-proxy.
Save this file as cilium-eks-values.yaml:
cluster:
name: eks-us-east-1
id: 1
kubeProxyReplacement: true
ebpf:
masquerade: true
hostRouting: true
tunnelProtocol: "" # Direct routing with Wireguard mesh
ipam:
mode: kubernetes
encryption:
enabled: true
type: wireguard
clustermesh:
useAPIServer: true
config:
enabled: true
clusters:
- name: eks-us-east-1
address: eks-control-plane.ecstaticloud.internal
port: 2379
- name: gke-us-central1
address: gke-control-plane.ecstaticloud.internal
port: 2379
hubble:
enabled: true
relay:
enabled: true
ui:
enabled: true
Apply the configuration via Helm:
helm repo add cilium https://helm.cilium.io/
helm repo update
helm install cilium cilium/cilium \
--version 1.15.1 \
--namespace kube-system \
-f cilium-eks-values.yaml
Repeat the process on the GKE cluster using cluster.name: gke-us-central1 and cluster.id: 2 with its respective Pod CIDR.
Step 3: Connect Control Planes via ClusterMesh
Verify eBPF connectivity and link the clusters across multi-cloud boundaries:
# Verify Cilium status on Cluster A
cilium status --wait
# Connect Cluster A (EKS) to Cluster B (GKE)
cilium clustermesh connect \
--destination-context gke-us-central1-context
# Validate cross-cluster mesh status
cilium clustermesh status
Output confirmation:
Phase: Ready
Nodes: 12/12
Services: 45/45
Identities: 128/128
Global Services: 8 synchronized
4. Crafting L3/L4/L7 Zero-Trust Security Policies
In a Zero-Trust eBPF environment, default action is DEFAULT DENY. All pod communication must be explicitly authorized using identity attributes.
Default-Deny Everything Policy
Apply this cluster-wide to force an explicit trust model:
apiVersion: "cilium.io/v2"
kind: CiliumClusterwideNetworkPolicy
metadata:
name: default-deny-all
spec:
endpointSelector: {}
ingress: []
egress:
# Allow local DNS resolution only
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s:k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
rules:
dns:
- matchPattern: "*"
Multi-Cloud L7 Identity Policy
Now, authorize a multi-cloud interaction: Allow the analytics workload running in GCP GKE to call the payment API endpoint running in AWS EKS over mutual TLS and HTTP POST to /v1/charge ONLY.
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: allow-cross-cloud-analytics-to-payment
namespace: production
spec:
endpointSelector:
matchLabels:
app: payment
tier: api
ingress:
- fromEndpoints:
- matchLabels:
# Matches identity assigned to remote cluster workloads
io.cilium.k8s.policy.cluster: gke-us-central1
app: analytics
tier: processing
toPorts:
- ports:
- port: "8443"
protocol: TCP
rules:
http:
- method: "POST"
path: "/v1/charge"
Because enforcement occurs at the eBPF layer within the Linux kernel socket buffer (sockmap), the policy is applied without spawning local Envoy sidecar proxies, saving CPU cycles and drastically lowering P99 latency.
5. Kernel-Level Runtime Security with Tetragon
Network-level security covers ingress and egress, but Zero-Trust requires verifying process execution and file integrity within the pod. If an attacker discovers an RCE vulnerability in your Java application, network policies won't stop them from executing a local binary or inspecting container memory.
This is where Tetragon comes in. Tetragon attaches eBPF programs directly to system calls (execve, openat, capabilities) to detect and synchronously block threats at the kernel level.
Deploying a Tetragon TracingPolicy
Below is a production policy that intercepts execution attempts of shell utilities (bash, sh, curl, wget) within production workloads and terminates the offending process in real time before damage occurs.
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: block-shell-execution-in-prod
namespace: kube-system
spec:
kprobes:
- call: "sys_execve"
syscall: true
args:
- index: 0
type: "string" # Path of executable
selectors:
- matchNamespaces:
- production
matchArgs:
- index: 0
operator: "In"
values:
- "/bin/bash"
- "/bin/sh"
- "/usr/bin/curl"
- "/usr/bin/wget"
matchActions:
- action: Sigkill # Terminate process synchronously in kernel!
If an attacker executes a web shell payload targeting a container in the production namespace:
- The
sys_execvesystem call triggers the eBPF tracepoint. - Tetragon evaluates the rule inside kernel space in nanoseconds.
- It issues a
SIGKILLdirectly to the thread before execution completes.
6. Real-time Observability via Hubble
Observability is a critical pillar of Zero-Trust. Without visual verification of identity flows, configuring policies safely becomes impossible. Hubble uses the same eBPF instrumentation to provide high-resolution tracing without packet sniffing overhead.
Query real-time network flows across clusters via the Hubble CLI:
# Stream denied ingress traffic across all clusters
hubble observe --verdict DENIED --follow
# Filter flows from GCP to AWS payment service
hubble observe \
--from-label io.cilium.k8s.policy.cluster=gke-us-central1 \
--to-label app=payment \
--protocol http \
-o json
Hubble Observability Output Example:
{
"flow": {
"time": "2026-03-30T10:14:22.102837210Z",
"verdict": "FORWARDED",
"IP": {
"source": "10.201.12.44",
"destination": "10.200.4.108"
},
"source": {
"namespace": "production",
"pod_name": "analytics-worker-8694d4d59-x2p12",
"labels": ["app=analytics", "io.cilium.k8s.policy.cluster=gke-us-central1"]
},
"destination": {
"namespace": "production",
"pod_name": "payment-api-5c4bb8378-m9k11",
"labels": ["app=payment"]
},
"l7": {
"type": "REQUEST",
"http": {
"method": "POST",
"url": "/v1/charge",
"protocol": "HTTP/1.1"
}
}
}
}
7. Performance Benchmarks: eBPF vs. Sidecar Architecture
At Ecstaticloud, we ran synthetic benchmark tests (using fortio and wrk2) across a 100-node multi-cloud environment to measure the impact of swapping a traditional Envoy-based service mesh for an eBPF-native Cilium architecture.
| Metric | Traditional Envoy Sidecar Mesh | Cilium eBPF Zero-Trust | Delta / Improvement | | :--- | :--- | :--- | :--- | | P99 Latency (10k RPS) | 4.82 ms | 1.14 ms | 76.3% Reduction | | CPU Overhead (per 1,000 pods) | ~18.5 Cores | ~1.2 Cores | 93.5% Savings | | RAM Overhead (per 1,000 pods) | ~48.0 GB | ~2.1 GB | 95.6% Savings | | Throughput (Gbps) | 6.2 Gbps | 9.4 Gbps | 51.6% Increase |
Conclusion & Architectural Takeaways
Implementing Zero-Trust across multi-cloud Kubernetes clusters no longer requires sacrificing application performance or inflating cloud spend on sidecar proxies. By decoupling security logic from user-space applications and pushing enforcement into the Linux kernel via eBPF, you achieve:
- True Multi-Cloud Identity Continuity: Consistent security policy across AWS, GCP, Azure, and bare metal.
- Sub-Millisecond Overhead: Near-native kernel throughput and negligible latency impact on HTTP/gRPC workloads.
- Deep Defense-in-Depth: Combining network layer enforcement (Cilium CNPs) with process-level runtime prevention (Tetragon) into a single cohesive architecture.
Next Steps
- Start by deploying Cilium in audit mode (
policy-enforcement: audit) to observe existing network flows using Hubble UI before switching to default-deny enforcement. - Explore Cilium SPIRE integration to incorporate cryptographic SPIFFE identities into eBPF policy validation for hardened zero-trust environments.