# Cilium > Cilium is an open source, CNCF graduated project that uses eBPF to deliver networking, security, and observability for Kubernetes and cloud native platforms. It provides a high-performance Container Network Interface (CNI), an eBPF-based kube-proxy replacement, identity-based network policy, transparent encryption, multi-cluster connectivity, a sidecar-free service mesh, and deep network observability through Hubble. Cilium was created by Isovalent part of Cisco and runs in production at Google, Amazon, Microsoft Azure, Adobe, Bell Canada, The New York Times, Datadog, Bloomberg, TikTok, Alibaba Cloud, and thousands of other companies. Official site: https://cilium.io. Documentation: https://docs.cilium.io **What is Cilium** Cilium is a cloud native networking and security platform for Kubernetes built on eBPF, a Linux kernel technology that runs sandboxed programs inside the kernel without changing kernel source or loading modules. By programming the dataplane in eBPF, Cilium replaces iptables-based packet processing with a more scalable, lower-latency, identity-aware dataplane. Cilium operates at the network (L3/L4) and application (L7) layers. It assigns a security identity to each Kubernetes workload, enforces policy based on identity rather than IP address, and provides visibility into every network flow. The Hubble sub project adds flow logs, metrics, and a service dependency map; the Tetragon sub project adds eBPF-based runtime security and enforcement. Cilium graduated in the Cloud Native Computing Foundation (CNCF) in 2023 and is the default or recommended CNI for many managed Kubernetes platforms and distributions, including Google GKE Dataplane V2, Microsoft AKS, Digital Ocean Kubernetes, Red Hat OpenShift, kind, and more. Cilium is often compared to other CNIs such as Calico and Flannel. It differs primarily in its eBPF dataplane, which enables identity-aware policy, scalability, and observability that IP-table-based CNIs can't provide natively. For service mesh, Cilium's sidecar-free approach and eBPF dataplane separate it from others like Istio or Linkerd. **Core capabilities** - **Container networking (CNI):** Kubernetes pod networking with an eBPF dataplane, IPAM, overlay (VXLAN/Geneve) and native/direct routing modes, ENI/Azure delegated IPAM, and BIG TCP and netkit for high throughput. - **kube-proxy replacement:** eBPF-based service load balancing for ClusterIP, NodePort, and LoadBalancer services, with Maglev consistent hashing, Direct Server Return (DSR), and XDP acceleration, eliminating iptables scaling bottlenecks. - **Network policy and security:** identity-based microsegmentation with Kubernetes NetworkPolicy and CiliumNetworkPolicy (CNP) at L3/L4/L7, DNS/FQDN-aware policy, and host firewall for zero-trust networking. - **Observability with Hubble:** identity-aware L3/L4/L7 network flow logs, DNS visibility, Prometheus and OpenTelemetry metrics, Grafana dashboards, and a real-time service dependency map. - **Transparent encryption:** WireGuard and IPsec pod-to-pod in-transit encryption with no application changes and ztunnel for mTLS, supporting compliance and FIPS requirements. - **Multi-cluster (Cluster Mesh):** cross-cluster service discovery, global services, and pod-to-pod connectivity, observability, and security across clusters, regions, and clouds. - **Sidecar-free service mesh:** eBPF and Envoy-based L7 traffic management and mutual TLS (mTLS) without per-pod sidecar proxies, reducing latency and resource overhead. - **Runtime security (Tetragon):** eBPF-based process execution, file access, and network monitoring with kernel-level enforcement for threat detection and forensics. --- This is the **full** version (`llms-full.txt`). [llms.txt](https://cilium.io/llms.txt) is the map and this file is the territory: it contains one section per page linked from llms.txt, in the same order. Content pages on cilium.io are inlined in full, the Blog entry expands to the full text of every post published on the site plus an index of external posts, and map entries without substantive on-site text keep their one-line description. For deep technical specifications, see the official documentation at https://docs.cilium.io. ## Use cases ### High Performance Cloud Native Networking (CNI) URL: https://cilium.io/use-cases/cni Category: Networking _Enhance the speed and efficiency of your Kubernetes and cloud native networks_ **How can I have scalable and consistent networking across clouds?** There are dozens of CNIs available for Kubernetes but, their features, scale, and performance vary greatly. Many of them rely on a legacy technology (iptables) that cannot handle the scale and churn of Kubernetes environments leading to increased latency and reduced throughput. Most CNIs also only offer support for L3/L4 Kubernetes network policy but little beyond. Many Cloud Provider have their own custom CNIs which results in operational complexity for customers operating in multi-cloud environments. #### High Performance Cloud Native Networking CNI Cilium’s control and data plane has been built from the ground up for large-scale and highly dynamic cloud native environments where 100s and even 1000s of containers are created and destroyed within seconds. Cilium’s control plane is highly optimized, running in Kubernetes clusters with 1,000s of nodes and 100K pods. Cilium’s data plane uses eBPF for efficient load-balancing and incremental updates, avoiding the pitfalls of large iptables rulesets. #### Scalability Cilium is built to scale. Whether you're running a few nodes or managing a cluster with thousands, Cilium can handle it. Cilium’s eBPF-powered networking is optimized for large scale operations. This means you can grow your operations without worrying about the network becoming a bottleneck. #### Network Security Cilium doesn't just excel in performance, it also brings robust security features. With identity-based security that goes beyond traditional IP address-based ACLs, Cilium provides fine-grained policy enforcement. This allows you to control who can talk to whom, reducing the attack surface and helping secure your cloud native applications. #### Integration Cilium integrates seamlessly with Kubernetes, providing networking and security through a CNI plugin. Cilium has been tested, validated, and optimized across multiple clouds and Kubernetes distributions. All major cloud providers have already standardized on Cilium for cloud native networking and security needs with Kubernetes. Managed Kubernetes offerings from Google Cloud, AWS, Azure, Alibaba, DigitalOcean, and several smaller platforms like Civo, Linode, etc, leverage Cilium for their CNI. _Adopters & resources referenced on this page:_ AWS picks Cilium for Networking & Security on EKS Anywhere; Cilium in Anthos and Google Kubernetes Engine (GKE) as Dataplane V2; Azure CNI Powered by Cilium in Azure Kubernetes Service; Alibaba Cloud turns to Cilium for improved Network Performance and Scalability; SysEleven Picks Cilium as the Preferred Networking Solution for their Platform; CNI Benchmark: Understanding Cilium Network Performance. ### Kube-proxy Replacement URL: https://cilium.io/use-cases/kube-proxy Category: Networking _Enhanced networking speed and efficiency for your Kubernetes clusters_ **Liberating Kubernetes From kube-proxy and IPtables** IPtables and Netfilter are the two foundational technologies of kube-proxy for implementing the Service abstraction. They carry legacy accumulated over 20 years of development grounded in more traditional networking environments that are typically far more static than your average Kubernetes cluster. In the age of cloud native, they are no longer the best tool for the job, especially in terms of performance, reliability, scalability, and operations. #### Kubernetes Without Kube-Proxy Cilium’s control and data plane has been built from the ground up for large-scale and highly dynamic cloud native environments where 100s and even 1000s of containers are created and destroyed within seconds. Cilium’s control plane is highly optimized, running in Kubernetes clusters of up to 5K nodes and 100K pods. Cilium’s data plane uses eBPF for efficient load-balancing and incremental updates, avoiding the pitfalls of large IPtables rulesets. #### Seamless Integration and Upgrade If you already have kube-proxy running as a DaemonSet, transitioning to Cilium is a breeze. Replacing kube-proxy with Cilium is a straightforward process, as Cilium provides a Kubernetes-native implementation that is fully compatible with the Kubernetes API. Existing Kubernetes applications and configurations can continue to work seamlessly with Cilium. #### Unlock Advanced Configuration Modes Cilium's kube-proxy replacement offers advanced configuration modes to cater to your specific needs. Features like client source IP preservation ensure that your service connections remain intact, while Maglev Consistent Hashing enhances load balancing and resiliency. With support for Direct Server Return (DSR) and Hybrid DSR/SNAT modes, you can optimize traffic routing and improve performance. _Adopters & resources referenced on this page:_ Post Finance picks Cilium for Cloud Native Networking; SmartNews leverages Cilium to improve performance and scaling; Service Load-Balancing Without Kube-Proxy on Kubermatic; Kakao improves network performance and lowers costs with Cilium; Why is the kernel community replacing iptables with BPF?. ### Layer 4 Load Balancer URL: https://cilium.io/use-cases/load-balancer Category: Networking _High performance load balancing with low overhead_ **How can I implement efficient L4 load balancing with low overhead and cost?** Configuring and managing load balancing into your cluster can be challenging due to the complexity involved in setting up connectivity and synchronization between the clusters and the outside world. Traditional hardware load balancers can be very costly while software load balancers may not provide the performance you need. External-to-Pod (North-South) LB also typically requires additional tooling, adding more complexity, cost, and overhead. #### XDP and eBPF powered scalable Load Balancing and Ingress Cilium can attract traffic with BGP and accelerate it leveraging XDP and eBPF. Together these technologies provide a very robust and secure implementation of Load Balancing. Cilium and eBPF operate at the kernel layer. With this level of context intelligent decisions can be made about how to connect different workloads whether on the same node or between clusters. With eBPF and XDP Cilium enables significant improvements in latency and performance. Cilium's standalone load balancer offers a high-performance LB, providing huge throughput gains at a reduced CPU overhead. #### Cilium Standalone Layer 4 Load Balancer XDP Cilium's high performance, robust load balancing implementation is tuned for the scale and churn of cloud native environments. You can replace expensive legacy boxes in your network with Cilium as a standalone load balancer. This unlocks the potential of DSR and Maglev for handling north/south traffic in on-premises environments without requiring Kubernetes to manage the network border. _Adopters & resources referenced on this page:_ Efficiently handling production traffic with Cilium Standalone Layer 4 Load Balancer XDP; Software L4 Load Balancing for Kubernetes Services at Yahoo. ### Advanced Network Policy URL: https://cilium.io/use-cases/network-policy Category: Security _Maintain identity based policies effectively at scale_ **How can I implement granular security policies when IPs change quickly?** Kubernetes network policies provide an application-centric construct for defining security policies at L3/L4 level. One of the primary challenges is how to effectively enforce security policies when traditional IP rules don't apply. Modern systems often churn IPs dynamically making it difficult to rely entirely on TCP/UDP ports and IP addresses for scaling security policies. #### Application and DNS Aware Policies with Cilium Cilium implements Kubernetes Network Policies for L3/L4 level and extends with L7 policies for fine grained API-level security for common protocols such as HTTP, Kafka, gRPC, etc. For example, the endpoint with label role=frontend can only perform the REST API call GET /userdata/[0-9]+, all other API interactions with role=backend are restricted. #### Scaling policies with Identities not IPs Cilium decouples security from network addressing using workload identity derived from labels and metadata, allowing for more flexible and efficient scaling without constant security rule updates. #### Policy visualization and editing Cilium provides a simple and intuitive network policy editor UI easing the cognitive overhead of writing network policies. It can often be painful to get the YAML syntax and formatting right when implementing network policies. There are many subtleties in the behavior of the network policy specification (e.g. default allow/deny, namespacing, wildcarding, rules combination, etc) that can result in misconfiguration. #### Multi-cluster Policies Cluster Mesh, Cilium's multi-cluster implementation features Network policy enforcement spanning multiple clusters. The same policy enforcement you are familiar with from a single cluster simply expands and works across multiple clusters. #### Cluster-wide Policies Cilium also features cluster wide policies which are non-namespaced and cluster scoped via the extended CiliumClusterwideNetworkPolicy CRD. Using cluster-wide policies, administrators can enforce consistent policies across all namespaces, simplifying network management. _Adopters & resources referenced on this page:_ Scaling for the future with Cilium; Observability for a highly available multi cluster environment with Hubble; How ClickHouse is Using Cilium to Implement Efficient Network Policies; Self-service, Zero Trust Network Security; Enforcing Network Policies for Host Processes via eBPF; Migrating to Cilium for Better Networking, Visibility and Security; Implementing Zero Trust Security with Cilium. ### Transparent Encryption URL: https://cilium.io/use-cases/transparent-encryption Category: Security _Encryption without operational headache_ **How can I encrypt traffic on my clusters while minimizing operational overhead?** Many compliance frameworks require encryption, but Kubernetes lacks native pod-to-pod encryption. Two common solutions to this problem are embedding encryption within the application or using a service mesh. Embedding encryption within the app is complex and requires application and security expertise. On the other hand, most service mesh implementations are very complex and challenging to manage and operate. #### What does Cilium provide? Cilium provides a straightforward solution for enabling the encryption of all node-to-node traffic with just one switch, no application changes or additional proxies. Cilium features automatic key rotation with overlapping keys, efficient datapath encryption through in-kernel IPsec or WireGuard, and can encrypt all traffic, including non-standard traffic like UDP. Simply configuring all nodes across all clusters with a common key and all communication between nodes is automatically encrypted. _Adopters & resources referenced on this page:_ Achieving HIPAA compliance with Cilium’s transparent encryption; Seamless Network Security and Privacy with Cilium. ### Cluster Mesh URL: https://cilium.io/use-cases/cluster-mesh Category: Networking _Unleashing the power of multi-cluster networking with Cilium Cluster Mesh_ **Seamless connectivity for multiple Kubernetes clusters** Multi-cluster Kubernetes setups are often adopted for reasons like fault isolation, scalability, and geographical distribution. This approach can lead to networking complexities. With such multi-cluster setups, traditional networking models struggle with service discovery, network segmentation, policy enforcement, and load balancing across clusters. Additionally, managing security protocols and policies across multiple environments can be a challenging endeavour due to the distributed nature of services. #### Cluster Mesh, Cilium's Multi-Cluster Networking Implementation Cilium Cluster Mesh allows you to connect the networks of multiple clusters in such as way that pods in each cluster can discover and access services in all other clusters of the mesh, provided all the clusters run Cilium as their CNI. This allows effectively joining multiple clusters into a large unified network, regardless of the Kubernetes distribution or location each of them is running. #### High Availability and Fault Tolerance Cluster Mesh enhances your services high availability and fault tolerance. It supports the operation of Kubernetes clusters in multiple regions or availability zones. If resources become temporarily unavailable, are misconfigured in one cluster, or offline for upgrades, it enables failover to other clusters, ensuring your services remain accessible at all times. #### Transparent Service Discovery Cluster Mesh automates service discovery across your Kubernetes clusters. Using standard Kubernetes services, it automatically merges services with identical names and namespaces across clusters into a global service. This means your applications can discover and interact with services, irrespective of the cluster they reside in, greatly simplifying cross-cluster communication. #### Effortless Pod IP Routing Cluster Mesh is able to handle Pod IP routing across multiple Kubernetes clusters at native performance. By using either tunneling or direct-routing, it circumvents the need for any gateways or proxies. This allows your pods to communicate across clusters seamlessly, enhancing the overall efficiency of your microservice architecture. #### Shared Services Across Clusters Cluster Mesh enables sharing of services such as secrets management, logging, monitoring, or DNS between all clusters. This reduces operational overhead, simplifies management, and maintains isolation between tenant clusters. #### Uniform Network Policy Enforcement Cluster Mesh extends Cilium's Layer 3-7 network policy enforcement to all clusters in the mesh. It standardizes the application of network policies, ensuring a consistent security approach across your entire Kubernetes deployment, irrespective of the number of clusters involved. _Adopters & resources referenced on this page:_ Most mature multi cluster application management technology; Transforming Networking with Cilium at Ecco; Multi-cluster networking with Cilium at Form3; Building ClickHouse Cloud From Scratch in a Year; How Wildlife Studios built a Global Multi Cluster Gaming Infrastructure with Cilium; Strengthening Security Across Distributed Kubernetes Clusters; High Performance Data Backend for Your AI/ML with MinIO and Cilium Cluster Mesh. ### Cilium Service Mesh URL: https://cilium.io/use-cases/service-mesh Category: Networking _Revolutionizing networking and simplify operations_ **Performance Meets Simplicity** Traditional service meshes, despite their benefits, can present significant challenges. These include the complexity and error-prone nature of IP and port-based network policies, performance overhead due to their proxy-based architecture, limited granularity in visibility of service-to-service communication, interoperability issues with existing infrastructure, scalability challenges as the number of services and traffic volumes increase, and operational and resource overhead. #### Cilium's Next-Generation Service Mesh Cilium Service Mesh redefines traditional service mesh frameworks by integrating the mesh layer directly into the kernel using eBPF, thus eliminating the need for sidecar proxies. It manages connectivity at both the networking and application protocol layers, handling protocols like IP, TCP, UDP, HTTP, Kafka, gRPC, and DNS with greater efficiency. #### Superior Networking with eBPF At the heart of Cilium is eBPF, a revolutionary technology built into the Linux kernel. With eBPF, Cilium delivers lightning-fast, efficient, and scalable networking. This bypasses the performance drawbacks of traditional proxies, enabling direct and efficient communication between your services. #### Control Plane Options Cilium Service Mesh gives users the choice of control plane options for the ideal balance of complexity and richness, from simpler options such as Ingress and Gateway API to richer options with Istio, to the full power of Envoy via the Envoy CRD. #### Sidecar-free Option With Cilium Service Mesh, users now have the choice to run a service mesh with sidecars or without them, based on their specific requirements and constraints. This flexibility reduces the complexity and overhead impact of sidecars. #### Hands-On: eCHO Playlist Whether you’re bootstrapping a service mesh from the ground up or adopting Cilium’s eBPF-powered service mesh later in your service mesh journey, the eCHO Recaps: Cilium Service Mesh playlist shows the entire timeline starting from the first demo and hands-on commands. Follow each episode as to see how service mesh includes ingress and Gateway API traffic management, all on real clusters with CLI walk throughs you can replay on-demand. _Adopters & resources referenced on this page:_ How Roche Manages Network Connectivity for 1000+ Edge Clusters; Strengthening Security Across Distributed Kubernetes Clusters; Revolutionizing Mesh Layers: Transitioning from Istio to Cilium at the New York Times; Simplifying Service Mesh with Encryption from Cilium. ### Gateway API URL: https://cilium.io/use-cases/gateway-api Category: Networking _Robust Kubernetes Ingress for traffic management_ **Evolving Past Ingress** Gateway API addresses the limitations of the Kubernetes Ingress API, which has traditionally been used to route traffic into Kubernetes clusters. While the Ingress API supports basic routing based on path and host rules, it lacks support for advanced routing features, only supports HTTP and HTTPS traffic, doesn’t separate out user/operator concerns, and can lead to inconsistencies due to vendor-specific annotations. Gateway API overcomes these constraints, providing a more robust, extensible, and role-oriented approach to traffic engineering.​ #### Advanced Routing and Protocol Support Cilium’s Gateway API implementation provides a fully conformant implementation of Kubernetes Ingress and offers advanced routing capabilities that go beyond the limitations of the Ingress API. It supports features such as traffic splitting, header modification, and URL rewriting. Additionally, it extends beyond HTTP and HTTPS traffic, with support of other protocols such as TCP, UDP, and gRPC. This allows for a more flexible and sophisticated routing strategies. #### Role-Oriented and Extensible Cilium’s Gateway API implementation was designed with different operational roles in mind, such as Infrastructure Providers, Cluster Operators, and Application Developers. By decomposing the Ingress API into several Gateway API objects, different personas can be assigned the appropriate access and privileges according to their responsibilities. This means that, for example, application developers would be allowed to create Route objects in a specified namespace, but would not be able to modify the Gateway configuration or edit Route objects in other namespaces.​ #### Reducing Tool Sprawl Cilium aims to simplify operations by reducing the number of cloud native networking, observability, and security tools required. It natively supports not just the Gateway API but also features like a sidecar-less Service Mesh, Transparent Encryption, Network Policies, and built-in observability with Hubble. This approach makes life easier for cluster operators, who only need a single tool to manage and upgrade for many, if not all, of their Kubernetes networking needs​​. #### Gateway API for Service Mesh (GAMMA) By leveraging the standard Kubernetes Gateway API for Mesh Management and Administration(GAMMA), Cilium can be used for sophisticated East-West traffic management within the cluster. Cilium support for GAMMA translates into simplicity for operators while providing advanced traffic management. ### Ingress URL: https://cilium.io/use-cases/ingress Category: Networking _Enhancing Kubernetes Ingress With Cilium_ **How can I expose my services with a protocol-aware mechanism?** The Kubernetes ecosystem is rich with ingress controllers, yet they often introduce complexity and limitations. Kubernetes ingress solutions often fall short when it comes to scalability, visibility, and security in dynamic cloud native environments. Many rely on iptables or other legacy networking constructs, which can lead to inefficient resource usage, performance bottlenecks, and limited observability. Additionally, ensuring source IP visibility, seamless TLS handling, and integration with advanced network policies often requires complex workarounds or additional tools, complicating operations and increasing overhead. #### Flexible Load Balancer for Simplified Management Cilium Ingress introduces flexible load balancer modes, enabling you to choose between dedicated and shared configurations tailored to your needs. In shared mode, resources are conserved by utilizing a single load balancer across all ingress resources. In dedicated mode, each ingress receives an independent load balancer, preventing conflicts like overlapping path prefixes. This adaptability ensures that scaling your application architecture never compromises performance or resource efficiency. #### Seamless Source IP Visibility Cilium Ingress ensures that backend applications retain access to the original source IP, a common pain point with other solutions. By leveraging TPROXY and the intelligent configuration of Envoy, Cilium maintains transparency in HTTP headers such as X-Forwarded-For and X-Envoy-External-Address. This seamless visibility is vital for debugging, logging, and implementing IP-based access controls without additional overhead. #### Advanced TLS Management With support for TLS termination and passthrough, Cilium Ingress simplifies secure traffic handling. It enables multi-TLS backend sharing while dynamically routing based on SNI. This eliminates configuration complexity and ensures robust security, even in highly dynamic environments. Applications benefit from simplified setup and seamless performance. #### eBPF Powered Network Security Cilium embeds security directly into the network layer using eBPF. This approach allows fine-grained enforcement of CiliumNetworkPolicies for traffic entering and exiting the cluster. Traffic passes through an Envoy proxy integrated with Cilium's policy engine, enabling precise control over network behavior. This dual-layer security ensures compliance with organizational policies while protecting against advanced threats. ### BGP URL: https://cilium.io/use-cases/bgp Category: Networking _Harness the infinite potential of Border Gateway Protocol (BGP) with Cilium_ **Supercharge Your Routing Protocol** Traditional IP routing can be static and inflexible, especially in cloud native environments where workloads are constantly being created, moved, and deleted. BGP's inherent ability to manage complex network topologies and routing data makes it an excellent fit for the dynamic and distributed nature of modern cloud native environments. #### Elevate your Networking Infrastructure with Cilium’s BGP Cilium amplifies the power of BGP, the backbone of the internet, to bring you high-speed, scalable, and secure routing for your cloud environments. Seamlessly integrating with existing infrastructure, Cilium's BGP is perfect for a range of deployments, from hybrid to multi cloud to edge. With advanced traffic engineering features, you'll have granular control over your network traffic, optimizing your network's performance and security. #### Effortless Integration of Existing Network Infrastructure Cilium's BGP support is designed to be simple and easy to integrate with your existing networking infrastructure. Wherever your application is running, Cilium can ensure efficient BGP routing for all your workloads. Many network infrastructures already use BGP for routing. By leveraging BGP, Cilium can seamlessly integrate with existing infrastructure, allowing Kubernetes pods to communicate with other parts of the network. _Adopters & resources referenced on this page:_ Trip.com's Hybrid Cloud Approach with Cilium for Workload Routing; Sidecar BGP Peering Pattern with Cilium at Preferred Networks; Leveraging Cilium’s BGP in Private Data Centers. ### Egress Gateway URL: https://cilium.io/use-cases/egress-gateway Category: Networking _Enhancing network security and traffic control exiting Kubernetes environments_ **Integrating Unpredictable IPs** Pods typically have ever-changing IP addresses in Kubernetes environments. Even if masquerading is used to mitigate this, the IP addresses of nodes can also change frequently. Egress gateways provide a way to route all outbound traffic from certain pods through a specific node with a predictable IP address. This predictable IP can be useful for scenarios where the traffic destination requires a known source IP, for instance, when working with legacy systems or firewall rules. #### Harness the Power of Egress Gateway with Cilium Egress Gateway with Cilium fundamentally transforms Kubernetes networking by addressing dynamic IP challenges, ensuring seamless integration with legacy systems and enhancing network security. It provides precise control over traffic routing, enabling selective direction of pod traffic through stable, predictable IP addresses. This feature enables granular traffic management, effective monitoring and filtering, and workload-specific routing, all while facilitating interoperability with systems requiring known source IPs. #### Selective Traffic Control The egress gateway allows fine-grained control over which pods' traffic should be routed through the gateway node. This is done by applying egress gateway policies that use label selectors to target specific pods. This selective routing can help in implementing security policies, achieving network isolation, and managing network costs. #### Workload-Specific Routing In multi-tenant Kubernetes clusters, different workloads might need to interact with different external systems that have specific network requirements. Egress gateways can help meet these requirements by allowing the configuration of workload-specific routing rules. _Adopters & resources referenced on this page:_ Zero Trust Networking at Scale (20k+ VCPUs, 100+ Dev Teams); Cilium Egress Gateway at Corner Banca SA. ### Host Firewall URL: https://cilium.io/use-cases/host-firewall Category: Networking _Host Security That Scales With Kubernetes_ **How can I secure the host namespace with same consistent security model?** Kubernetes nodes are the backbone of any cluster, but securing them presents unique challenges beyond the capabilities of traditional firewalls. Without granular host-level controls, nodes are vulnerable to unauthorized access, exposing critical cluster components, like kube-apiserver or etcd, to potential breaches. Static firewall rules struggle to adapt to the dynamic nature of Kubernetes environments, leaving gaps in protection during workload changes or updates. Additionally, misconfigurations in restrictive policies can disrupt essential communications, while limited visibility into host-level traffic makes monitoring and troubleshooting difficult. #### Consistent Security for Nodes and Pods Traditionally, securing Kubernetes environments required managing separate security models for nodes and pods, resulting in operational complexity and potential blind spots. Cilium Host Firewall eliminates this inconsistency by applying the same network policy model to the host. This approach extends Kubernetes declarative, policy-driven security model to the nodes hosting your workloads, delivering seamless, consistent protection across your entire environment. By leveraging YAML manifests, administrators can define, apply, and manage host-level policies with the same ease and precision as Kubernetes Network Policies, creating a unified approach to securing both pods and their underlying hosts. #### Host Security That Scales With Kubernetes Cilium Host Firewall empowers administrators to enforce fine-grained policies for node-level traffic. By matching on node labels, you can create targeted rules that allow or deny traffic based on specific needs, such as permitting only SSH or ICMP traffic to specific nodes. This level of control ensures that your nodes are protected from unauthorized access while maintaining the flexibility required for smooth operations. Cilium Host Firewall ensures consistent, granular, and adaptable security for every node in your cluster, giving you the confidence to scale securely in even the most demanding environments. ### Bandwidth and Latency Optimization URL: https://cilium.io/use-cases/bandwidth-optimization Category: Networking _Simple and intuitive network performance optimization_ **Offering Latency and throughput improvements while controlling pod network contention** Kubernetes lacks native traffic control capabilities, making Traffic Rate-Limiting essential for optimal resource consumption and to prevent bandwidth exhaustion. While Kubernetes does offer Bandwidth Rate-Limiting, it is still experimental and can have detrimental effects on latency. Furthermore, connecting to external-facing Kubernetes clusters may result in a poor user experience due to most TCP congestion protocols not being designed for today's diverse networks. #### Optimal Bandwidth Management with Cilium’s Bandwidth Manager Cilium’s Bandwidth Manager allows rate-limiting per Pod with just one line of YAML. Compared to other alternatives, the Bandwidth Manager provides a 4x reduction in latency, ensuring a smooth network experience and isn’t detrimental to performances and is designed for multi-queue and multi-core NICs. #### Accelerate network performance with Cilium BBR Cilium supports BBR, a congestion control algorithm developed by Google, making it the first platform to do so. Google observed up to 2,700x improvement in throughput when testing BBR, making it a valuable addition for optimizing network performance. Cilium’s BBR provides exceptional improvements in throughput and latency for external-facing applications, offering consumers a delightful user experience #### 100Gbit/S Clusters With Cilium: Building Tomorrows Networking Cilium BIG TCP allows for larger packets than the traditional 64KB limit by leveraging IPv6's Hop-by-Hop header, which can specify payload lengths up to 512KB. This is particularly useful for organizations building networks capable of 100Gbps and beyond. BIG TCP does not require modifying the MTU on network devices, making it easier to implement than Jumbo Frames. With BIG TCP, Cilium offers enhanced network performance for nodes, enabling users to extract as much performance as possible from the network. _Adopters & resources referenced on this page:_ How Flipkart Implements Bandwidth QoS with Cilium; BIG Performances with BIG TCP on Cilium. ### IPv6-Native Kubernetes Networking with Cilium URL: https://cilium.io/use-cases/ipv6 Category: Networking _Cloud native networking at IPv6 scale, powered by eBPF_ **IPv6-Native Kubernetes Networking with Cilium** IPv6 adoption is accelerating across modern infrastructure. Address exhaustion, large-scale cluster growth, and cloud native connectivity are pushing platform teams toward IPv6-first designs. Cilium brings IPv6 deep into the Kubernetes datapath, enabling clusters to operate at scale without sacrificing performance, visibility, or control. Rather than treating IPv6 as a compatibility layer, Cilium integrates it directly into how traffic flows through the cluster. IPv6 unlocks massive address space, simplified routing, and long-term scalability. Cilium turns those advantages into practical outcomes for Kubernetes by combining IPv6-native networking with high-performance eBPF data paths. The result is a Kubernetes networking layer ready for the next decade of growth. #### IPv6 Underlay with Overlay Simplicity Operating Kubernetes across diverse infrastructure often requires abstraction from the physical network. Encapsulation modes such as VXLAN and Geneve provide that abstraction, allowing clusters to behave consistently regardless of where they run. Cilium enables these overlays to operate on top of an IPv6-only physical network. The underlay can be entirely IPv6 while pod-to-pod traffic continues to flow through a stable encapsulated datapath. This allows platform teams to modernize their networks to IPv6 without rethinking how Kubernetes connectivity is designed or operated. The result is an IPv6-native foundation with the same predictable networking model teams already trust. #### IPv6-Aware Egress Control Service networking is one of the most performance-sensitive paths in Kubernetes. Legacy approaches based on iptables introduce latency, complexity, and scaling challenges, problems that become more pronounced in large IPv6 environments. Cilium delivers IPv6 service handling directly in eBPF. Load balancing, service translation, and traffic steering all happen at the kernel level without relying on iptables or kube-proxy. IPv6 traffic benefits from the same high-performance, low-latency datapath that has made Cilium a standard for large-scale clusters. This creates a clean, efficient service model for IPv6 workloads that scales naturally as clusters grow. #### A Unified IPv6 Datapath Built on eBPF IPv6 in Cilium is implemented with the same eBPF-based datapath that powers IPv4 networking, security, and observability. This creates a unified model in which IPv4, IPv6, and dual-stack clusters share the same architecture and operational semantics. For platform teams, this means fewer special cases, simpler troubleshooting, and confidence that IPv6 workloads behave exactly as expected at scale. _Adopters & resources referenced on this page:_ TikTok's IPv6 Journey To Cilium: Pitfalls and Lessons Learned; IPv6 First, Not Just Ready: Kubernetes Without IPv4 Using Cilium at ESnet. ### Multicast URL: https://cilium.io/use-cases/multicast Category: Networking _eBPF-Powered Efficiency for Multicast in Kubernetes_ **Smarter Network Utilization** IP multicast is a bandwidth-conserving technology that reduces traffic by simultaneously delivering a single stream of information to potentially thousands of recipients. Multicast addresses the technical challenge of efficiently delivering data from a single source to multiple recipients simultaneously over a network. Multicast has found its use case in traditional networking, but Kubernetes networking often relies on unicast and broadcast methods.

In data transmission to containers within a Kubernetes cluster, packets are replicated and sent to every container regardless of their need. This approach might not be ideal for some applications with specific requirements and can lead to significant network congestion, high bandwidth, and overhead. #### Muticast the Cloud Native Way Cilium's multicast feature enables efficient network communication. By leveraging multicast, Cilium can efficiently transmit and replicate a single data stream to reach multiple consumer containers in a Kubernetes cluster, reducing the overall network bandwidth and overhead. This approach is particularly beneficial for industries like financial services, media, and entertainment, which typically have multiple services and endpoints that need to communicate simultaneously. #### Bringing the eBPF Revolution to Multicast Cilium's multicast implementation is not just efficient, it's also technically advanced. It's based on eBPF, a technology known for its exceptional efficiency and performance. By leveraging eBPF, Cilium ensures that the same level of optimization is brought to multicast as it does to a variety of other networking use cases. ### Identity-aware L3/L4/DNS Network Flow Logs URL: https://cilium.io/use-cases/network-flow-logs Category: Observability _Holistic view of your network traffic_ **How can you trace traffic to a specific workload in a complex environment?** Traditional network flow logs often lack the necessary level of detail and context needed to monitor and troubleshoot network issues in complex environments making it difficult to trace traffic back to specific workloads. This makes debugging difficult and time-consuming and makes it challenging to identify the source and scope of security incidents. #### Real time visibility for Network Flows By providing real-time visibility into network flows with enhanced metadata, including identity-based information about Kubernetes workloads, Cilium simplifies the process of monitoring and troubleshooting network traffic in Kubernetes clusters. This makes it easier to trace traffic back to specific workloads, simplifying the process of monitoring, troubleshooting, and addressing network issues, and enabling operators to quickly identify and respond to security incidents. #### Kubernetes-aware Network Flow Logs Cilium enhances network flow logs with additional information about the identity of the Kubernetes workloads generating or receiving the traffic. This identity information is based on the Kubernetes labels and annotations assigned to the workloads, as well as any other metadata that can be retrieved from the Kubernetes API server. _Adopters & resources referenced on this page:_ Observability for a highly available multi cluster environment with Hubble; Building Data Sandboxes at Bloomberg. ### Metrics & Tracing Export URL: https://cilium.io/use-cases/metrics-export Category: Observability _Valuable insights for troubleshooting, optimization, and performance monitoring_ **Monitor and analyze the performance and behavior of your Cilium-managed Kubernetes environment** Metrics alone may lack context for effective issue diagnosis. Configuring metrics exporters and integrating them with monitoring systems can be error-prone and manual. Inadequate, inconsistent, or incorrect metrics can be misleading, resulting in incorrect conclusions about the application state. Troubleshooting often requires correlating metrics with traces for a comprehensive system understanding. #### Metrics and Tracing With Cilium Cilium's Metrics and Tracing export feature provides a seamless and integrated solution empowering users to monitor, analyze, and optimize their Kubernetes environments with ease. By leveraging the power of Prometheus metrics, combined with Hubble's network behavior insights, Cilium enables users to gain deep visibility into their applications and network while simplifying the setup and configuration process. Cilium also integrates with various tracing systems, such as Jaeger, Zipkin, and OpenTelemetry, to provide distributed tracing capabilities. Cilium is optimized to handle high data volumes without compromising on performance. #### Comprehensive and Rich Set of Metrics Cilium captures a plethora of metrics, including latency, request rates, and error rates for your applications. These metrics are exported in a standardized Prometheus format, which can be easily integrated with your existing monitoring and visualization tools, enabling you to track your network performance in real-time. #### Distributed Tracing Cilium supports popular distributed tracing frameworks like Jaeger and Zipkin. With this, you can visualize request flow through your services, identify bottlenecks and optimize for efficiency. Cilium’s tracing provides a granular view of service interactions, bringing clarity to complex distributed systems. _Adopters & resources referenced on this page:_ eBPF-powered observability for Kubernetes and cloud native infrastructure; Cilium-powered Enterprise Kubernetes Management for Platform Teams. ### Advanced Network Protocol Visibility URL: https://cilium.io/use-cases/protocol-visibility Category: Observability _Insights into workload communication at the protocol level_ **How can I understand my workload’s communication at the protocol level?** Traditional network observability tools provide packet-level visibility, which can be insufficient in cloud native and other environments with complex communication patterns and diverse application protocols. In such scenarios, troubleshooting network issues can be challenging, and gaining protocol-level visibility becomes critical to ensure observability and security. #### Gain deep insights into your workload communication at the protocol level with Cilium Cilium's protocol-aware visibility provides application owners with deep insights into their workload’s communications at the protocol level. This means that Cilium is capable of native understanding of various application protocols, such as TLS, gRPC, Kafka, DNS, and HTTP, and other ones like SCTP enabling fine-grained observability of API-specific endpoints and DNS-identities for external endpoints. #### Hubble, eBPF-based Observability for Kubernetes Hubble is an eBPF-based observability platform for Kubernetes. Hubble leverages the Cilium CNI and eBPF technology to provide fine-grained visibility into network traffic and application behaviour, without the need to modify applications. With Hubble, administrators to interactively troubleshoot complex network issues and write custom metrics to benefit from eBPF's superpowers without the need to write or understand any kernel code. _Adopters & resources referenced on this page:_ Enhanced observability with Hubble; A more consumable network infrastructure with Cilium at Ikea. ### Service Map URL: https://cilium.io/use-cases/service-map Category: Observability _Detailed visibility into the communication and behavior of your workloads_ **How can I gain detailed visibility into the communication and behavior of my workloads?** When troubleshooting cloud native environments, the issue could be lurking between any layer of the network, environment, or its dependencies. For instance, it may be difficult to determine if DNS is working properly, or if an application is failing due to policy-related issues. Identifying the latest policy-related drops or determining if essential traffic between service components is being blocked can also prove to be challenging. On the other hand, examining logs for answers can be a difficult and time-consuming process. #### Hubble, eBPF powered Network, Service, and Security Observability for Kubernetes Hubble provides a range of monitoring capabilities, including service dependencies and communication maps, network monitoring, application monitoring, and security observability. By relying on eBPF, all visibility is programmable and allows for a dynamic approach that minimizes overhead while providing deep and detailed visibility. #### Service Dependency Graph Simply looking at `kubectl get pods` does not indicate dependencies between each service or external APIs or databases. Hubble offers effortless automatic discovery of service dependencies within Kubernetes Clusters at L3/L4 and L7 levels. This allows for user-friendly visualization and filtering of dataflows as a Service Map, enabling easy management of service dependencies. _Adopters & resources referenced on this page:_ Building a Secure and Maintainable PaaS; Saving Cost and Accelerating Insights with Hubble; Providing Observability to Customers With Hubble; Transforming Scientific Computing Infrastructure for IPv6 with Cilium at ESnet. ### Runtime Security URL: https://cilium.io/use-cases/runtime-security Category: Security _Prevent threats and enforce policies in real-time_ **Achieve threat prevention in cloud native environments while maintaining operational agility** Cloud native environments are often dynamic and distributed, requiring a security approach that encompasses detection and prevention. Observing and filtering events in user space can be resource-intensive and lead to blind spots in security monitoring, leaving systems vulnerable to attacks. #### Security Observability and Runtime Enforcement with Cilium’s Tetragon Tetragon enables transparent security observability and real-time runtime enforcement through its eBPF-based technology. It provides deep visibility without requiring changes to the application and operates with low overhead through in-kernel filtering and aggregation logic built into the eBPF-based kernel-level collector. Tetragon's embedded runtime enforcement layer offers access control capabilities at various enforcement levels, including system call control. #### Kubernetes-aware Real Time Enforcement Tetragon is Kubernetes-aware, meaning it recognizes Kubernetes identities like namespaces and pods. This enables security event detection that can be tailored to individual workloads. Using eBPF, Tetragon can access the Linux kernel state and combine it with Kubernetes awareness and user policy to generate rules that are enforced by the kernel in real-time. This allows for capabilities like process namespace and capabilities annotation and enforcement, process file descriptor to filename association, and socket to process control. _Adopters & resources referenced on this page:_ Don't Get Blown up! Avoiding Configuration Gotchas for Tetragon Newbies; Integrating Tetragon for Secured Build Pipelines; Pollenating Build Attestations on Kubernetes with Tetragon and eBPF; Hubble + Tetragon at Palantir; Who Owns Your Pod? Observing and Blocking Unwanted Behavior at eBay With eBPF. ## Business outcomes ### Zero Trust Networking URL: https://cilium.io/outcomes/zero-trust _Enforce what matters, where it matters._ Traditional network security measures can be ineffective in cloud native systems due to the transient nature of IP addresses, the dynamic nature of workloads, and the rapid growth of east-west traffic. These internal communication routes are undefended by standard firewall-based security, and it becomes next to impossible to maintain static IP rules or network segments across numerous environments. Zero Trust Networking directly addresses these challenges by shifting the focus from trusting the network to explicitly verifying each connection and workload. Instead of assuming anything inside the network is safe, Zero Trust Networking requires all communication to be authenticated and authorized based on what a workload is, not where it runs. Cilium makes this practical in cloud native environments by enforcing identity-aware policies tied to Kubernetes service accounts and labels, applying them efficiently in the kernel with eBPF, supporting multi-cluster and multi-cloud deployments, and providing deep visibility into and security for service-to-service communication. #### Keep internal traffic secure at any scale In modern infrastructure, internal communication is often the largest and most vulnerable attack surface. In the absence of Zero Trust controls, attackers who breach one service have the ability to extend their attacks laterally, gain access to sensitive data, and escalate their attacks. For regulatory frameworks like PCI DSS, GDPR, and HIPAA, protection of internal communication is becoming increasingly necessary in order to comply, and firewall-based controls aren’t enough. Cilium helps you meet these security and compliance demands by enforcing Zero Trust Networking policies that protect every connection, no matter how large or complex your environment becomes. #### Enforcing identity driven policies instead of IP-based rules As workloads scale, restart, or move across nodes and clusters, IP addresses change constantly, creating gaps or needing constant rule updates. Cilium solves this by applying security policies tied to Kubernetes-native identities like service accounts, pod labels, and namespaces. These identities stay consistent even as workloads shift or restart, so policies automatically follow the correct services wherever they run, removing the need to manage static network rules and ensuring reliable Zero Trust Networking enforcement at scale. #### Implement policies in the kernel Typically, enforcing Zero Trust Networking relies on proxies, sidecars, or userspace components to inspect and control traffic. These methods can make things more complicated to run, especially as systems scale. Cilium takes a different approach by using eBPF to apply security policies directly in the Linux kernel. This allows high-performance enforcement at the source of the traffic without extra components in the data path. The result is fast, low-latency security that scales cleanly with your infrastructure. #### Secure at the API and application layer, not just at the network layer In cloud native environments, many microservices communicate through APIs. Traditional security solutions stop at IP addresses and ports, leaving critical API traffic and application-level interactions vulnerable to misuse. This creates blind spots that attackers can exploit once inside the network. Cilium extends Zero Trust Networking to Layer 7, enabling network policies that inspect and control traffic based on API paths, HTTP methods, gRPC calls, DNS queries, and more. This ensures services communicate only as intended and minimizes unnecessary exposure within your environment. #### Built-in distributed firewalling for Zero Trust Networking at scale Rather than relying on centralized firewalls or sidecar proxies, Cilium enforces security policies directly at the source of traffic using eBPF inside the Linux kernel. This distributed model applies identity-aware policies consistently across all nodes, clusters, and environments, without introducing bottlenecks. With visibility and control from Layer 3 to Layer 7, Cilium prevents unauthorized lateral movement and delivers scalable, low-overhead Zero Trust enforcement across cloud native infrastructure. #### Keep Zero Trust enforcement consistent across clusters and clouds Applications rarely run in just one cluster, region, or cloud. As environments grow more distributed, keeping security policies consistent across all of them becomes complex, and any gaps in enforcement between environments creates risk. Cilium makes it simple to define and apply Zero Trust Networking policies uniformly, no matter where your workloads run. Whether you operate in a single Kubernetes cluster, across multiple clouds, or in hybrid setups, Cilium helps ensure security stays consistent without duplication or increased complexity. _Adopters & resources referenced on this page:_ Implementing Zero Trust in highly regulated financial systems; Enforcing Zero Trust isolation in a multi-tenant platform; Building Zero Trust into the Choreo platform; Strengthening security and compliance across multi-cloud HR systems; Enforcing Zero Trust data protection and access controls; Network Policy; Advanced Network Protocol Visibility; Identity-aware L3/L4/DNS Network Flow Logs; Host Firewall. ### Tool Consolidation URL: https://cilium.io/outcomes/tool-consolidation _Simplify your networking stack without sacrificing visibility or control_ As cloud native environments grow in complexity, teams often rely on a patchwork of tools for networking, observability, and security, each with its own learning curve, performance trade-offs, and integration overhead. Cilium replaces this fragmented tooling with a unified platform built on eBPF that provides connectivity, security, and deep visibility all in one. #### Replacing a patchwork of tools with Cilium Managing and integrating multiple tools for service mesh, firewalling, load balancing, ingress, observability, and policy enforcement slows teams down. Cilium helps teams consolidate without compromise with one tool for managing network traffic, service discovery, API-aware security, and real-time network visibility. This reduces operational costs, accelerates onboarding, and improves performance, while maintaining full control. #### Consolidating your networking stack With Cilium, you get high-performance networking, API-aware security, and deep observability in a single tool powered by eBPF. It removes the need for standalone network plugins, sidecar-based service meshes, and third-party observability layers, while integrating natively with Kubernetes. #### Observe traffic in real time without extra tools Cilium’s Hubble brings powerful network visibility directly into your Kubernetes environment, surfacing flow logs, a service map, and protocol-level insights (HTTP, gRPC, Kafka, etc.) without installing separate monitoring or tracing tools. #### Enforce policies at Layer 3 to Layer 7 Unlike traditional firewalls, Cilium enforces identity-aware policies tied to Kubernetes primitives and inspects traffic all the way up to Layer 7. That means you can secure microservices based on actual behavior, from DNS queries to API calls, without additional tooling. _Adopters & resources referenced on this page:_ One CNI to Power Customer and Internal Infrastructure; Unified networking and observability for MetaKube; One Platform to Manage Global Scale; Hubble; Kube-proxy Replacement; Gateway API; Border Gateway Protocol (BGP); Layer 4 Load Balancer; Service Mesh. ### Multi-Cloud Connectivity URL: https://cilium.io/outcomes/multi-cloud-connectivity _Seamless service-to-service communication across clouds, clusters, and regions._ Connecting workloads across multiple clouds is often fragile and complex, introducing issues like overlapping IPs and inconsistent rules. Cilium solves this with a unified, eBPF-powered network that offers native service discovery, identity-aware security, and scalable performance that works wherever your infrastructure lives. #### Unified connectivity and service discovery across clusters Cilium’s Cluster Mesh enables services across multiple clusters in any cloud or on-prem environment to connect and discover each other natively, as if running in the same cluster. Connections are fast, encrypted, and identity-aware by default, with no need for complex networking configurations. #### Trusted across cloud providers Cilium powers the default networking for major Kubernetes platforms like GKE, EKS-A, and AKS, and is trusted by leading organizations operating at scale. Its performance and security model have been validated across a wide range of public clouds, private data centers, and edge environments, making it a reliable foundation for multi-cloud and hybrid infrastructure. Whether you're running in one cloud or many, Cilium makes sure your clusters have consistent connectivity, performance, and security. _Adopters & resources referenced on this page:_ From Network Outages to Seamless Connectivity; Scaling secure payments across regions; Simplifying global service communication at scale; Reliable, flexible connectivity for data automation; Bridging Clouds for smarter operations; High Performance Container Network Interface (CNI); Cluster Mesh. ### Network Automation URL: https://cilium.io/outcomes/network-automation _Automate and simplify Kubernetes networking at scale_ Manual network configuration can’t keep up with the speed of cloud native environments. In Kubernetes, where workloads are dynamic and infrastructure is distributed, traditional approaches to networking create bottlenecks, inconsistencies, and operational risk. Cilium brings automation to the core of Kubernetes networking. Cilium makes it possible to configure, secure, and observe network behavior automatically through identity-aware policies that adapt to workload changes, dynamic service discovery, an eBPF-powered datapath, and seamless integration with CI/CD and GitOps workflows. #### Make your networking configuration as dynamic as your workloads As workloads in cloud native environments scale, shift, and redeploy across clusters and clouds, manual network configuration quickly becomes unsustainable. Engineers are left to manage rigid IP rules, duplicate policies across environments, and react to changes rather than design systems that adapt automatically. Cilium addresses this by making the network programmable and declarative. It allows teams to specify intent once, using workload identity and Kubernetes-native components, and then trust that connectivity, security, and observability will respond in real time as the environment changes. This means less time spent developing and debugging YAML, fewer outages due to misconfigured rules, and increased confidence when deploying infrastructure or adding new services. By removing manual steps from the networking stack, Cilium helps platform and security teams move faster, reduce risk, and operate more reliably in even the most dynamic environments. #### Enforcing identity-driven policies instead of IP-based rules As workloads scale, restart, or move across nodes and clusters, IP addresses change constantly, creating configuration gaps, or a need for continual manual updates. Cilium solves this by applying security policies tied to Kubernetes-native identities like service accounts, pod labels, and namespaces. These identities remain consistent even as workloads shift, so policies follow services automatically without requiring engineers to rewrite or reapply static rules. This keeps network behavior predictable, secure, and in sync with your infrastructure design, with little to no manual intervention. #### Dynamic connectivity without manual updates Services in Kubernetes are always changing, either scaling up, down, or shifting across nodes. Manually updating routing or access rules to stay up-to-date is inefficient and error-prone. Cilium automates this by integrating deeply with Kubernetes. As services come and go, Cilium updates routing and policies in real time, ensuring that communication paths stay correct and secure without any effort. #### Consistent policy across clusters and clouds Cilium’s Cluster Mesh and cluster-wide policies make it possible to apply security rules consistently across namespaces, regions, or even different cloud providers. This unified approach removes the need to duplicate network configurations for each environment, reduces operational overhead, and minimizes the risk of inconsistencies, ensuring reliable protection no matter where workloads run. #### eBPF programs and secures the network in the kernel Rather than relying on centralized firewalls or sidecar proxies, Cilium enforces security policies directly at the source of traffic using eBPF inside the Linux kernel. This distributed model applies identity-aware policies consistently across all nodes, clusters, and environments, without introducing bottlenecks. With visibility and control from Layer 3 to Layer 7, Cilium prevents unauthorized lateral movement and delivers scalable, low-overhead [Zero Trust Networking](https://cilium.io/outcomes/zero-trust/) enforcement across cloud native infrastructure. #### Automated networking built for GitOps and CI/CD Modern infrastructure is managed as code, and your networking should be too. With Cilium, network policies are declarative, version-controlled, and Kubernetes-native, making them easy to integrate into the same pipelines and workflows you use for deploying applications. You can define policies in Git, review them through pull requests, and apply them automatically through CI/CD or GitOps tools. This makes your network configuration more consistent, easier to audit, and easier to automate, while ensuring that your infrastructure stays secure and in sync across all environments. _Adopters & resources referenced on this page:_ Solving latency and scaling network performance; Delivering high-performance cloud networking; Automating scalable networking across KubeSphere; Building a scalable, future-ready networking platform; Automating Kubernetes networking and security at scale; Kube-proxy Replacement; Network Policy. ### Cost and Carbon Savings URL: https://cilium.io/outcomes/cost-and-carbon-savings _Do more with less_ Manual and legacy network systems often come with hidden overhead like inefficient IP usage, many network redirects, and cloud charges that add up fast. Cilium removes these inefficiencies with a streamlined, eBPF-powered network engine, lowering costs while reducing compute waste and carbon dioxide emissions. #### Why Sustainability Starts at the Network Layer ​​In Kubernetes environments, inefficiencies in networking can grow quickly. Traditional solutions are often heavy on resource consumption, requiring extra nodes, IP addresses, and compute power. This not only inflates costs but also increases energy use and carbon emissions. Cilium changes that by optimizing network paths, removing unnecessary components, and providing granular observability, meaning teams can reclaim resources, cut bills, and improve sustainability. #### eBPF-powered dataplanes cut CPU costs Cilium replaces traditional kube-proxy and iptables-based networking with an eBPF-based dataplane. This removes the need for userspace proxies and reduces the overhead of managing long rule chains. By processing traffic closer to the source, Cilium shortens the network path, lowers CPU consumption, and frees up compute resources for actual workloads, saving both money and energy. #### High pod density with lean IP allocation Particularly when used at scale, other CNIs may require large blocks of IP addresses for every node, limiting pod density and resulting in wasted resources. Because Cilium manages IP allocation more efficiently, you can run more pods per node without running out of IPs. This improves resource utilisation and decreases infrastructure and electricity costs by reducing the number of nodes needed. #### Eliminate cloud load balancer charges With Cilium's Cluster Mesh, native pod-to-pod communication between clusters is possible without the need for costly cloud load balancers. This simplifies your architecture and prevents excessive data transfer fees. By removing external dependencies, teams gain more control over traffic, reduce latency, and cut down significantly on cloud networking costs. _Adopters & resources referenced on this page:_ Cutting networking overhead at scale; Lowering network costs while debugging faster; Lower costs with high-performance; Cutting storage costs and cloud networking complexity; Reducing cloud bills and IP footprint; Bandwidth and Latency Optimization; High Performance Container Network Interface (CNI); Kube-proxy Replacement. ## Ecosystem and subprojects ### Hubble URL: https://docs.cilium.io/en/stable/observability/hubble/ Networking and security observability layer built on Cilium and eBPF: flow logs, metrics, and service map. ### Tetragon URL: https://tetragon.io EBPF-based runtime security and observability for process, file, and network events. ### eBPF URL: https://ebpf.io The Linux kernel technology Cilium is built on. ## Key pages ### llms-full.txt URL: https://cilium.io/llms-full.txt Full-text version with the complete prose of every use-case, outcome, and industry page and every blog post inlined. (this file). ### Home URL: https://cilium.io/ The Cilium project home page. ### Get started URL: https://cilium.io/get-started What is Cilium and how to get started. ### Adopters URL: https://cilium.io/adopters Adopters and production users. ### Enterprise URL: https://cilium.io/enterprise Enterprise distributions and training. ### Blog URL: https://cilium.io/blog Full text of all 147 posts published on the cilium.io blog, newest first, followed by an index of posts that link to articles hosted elsewhere. #### Zero-Trust Developer Platforms with Cilium Network Policies URL: https://cilium.io/blog/2026/08/28/zero-trust-developer-platforms-with-cilium-network-policies Date: 2026-08-28 Categories: Technology, Security Every platform team eventually hits the same wall. Security wants zero trust where no workload talks to another unless the connection is explicitly sanctioned. Engineering wants to ship on Friday afternoon without filing a ticket with the platform engineering team to get an IP whitelisted. Both are right, and the network is where the argument plays out. This doesn't have to be a trade-off for a platform team. It's a design problem at the platform layer itself, and it has a known solution: make network policies a _byproduct_ of deployment rather than a prerequisite to it. ##### The limits of IP-based security in Kubernetes Traditional network security assumes an address means something. A firewall rule permitting `10.4.2.17` to reach `10.4.8.9:5432` encodes a real intent, _the orders service may query the orders database_, but it encodes that intent in a fragile form. Kubernetes breaks that form completely. Pods are scheduled, rescheduled, scaled, evicted, and rolled. The IP address that identified your payments service this morning may belong to a batch job by lunchtime. Any security model that depends on addresses staying still is accurate only until the next reschedule. Standard Kubernetes NetworkPolicies improve on this by letting you declare intent with label selectors instead of addresses. But two problems remain. First, even though the intent declaration is by label, enforcement still happens by address. The CNI resolves selectors into concrete pod IPs and programs iptables chains accordingly, reprogramming on every reschedule. On a busy cluster, these rule sets can grow into thousands of sequentially-evaluated entries: a well-documented source of latency and control-plane load. Second, and more limiting, the NetworkPolicy API stops at Layer 4. A policy can allow port 8080 on a workload. However, it cannot say “allow `GET /orders` but not `DELETE /orders`”, or “this workload may reach _`api.stripe.com`_ and nothing else on the internet”. For most real threat models that's too broad; the interesting attacks happen inside connections you already allowed. ##### The shift to identity-based network policies with Cilium Cilium changes the primitive. Instead of translating labels into IP-keyed firewall rules, it assigns every workload a security identity derived from its labels and namespace, and enforces policy on that identity via eBPF programs attached directly to the kernel's networking hooks. This maps naturally onto ephemeral workloads in Kubernetes. When a pod is rescheduled onto a different node with a different IP, nothing about the policy needs to change. The new pod carries the same labels, resolves to the same identity, and inherits the same permissions the moment it starts. Policy stops depending on infrastructure details. Cilium can also reach higher up the OSI stack. For L7 rules, eBPF transparently redirects matched traffic to a per-node Envoy proxy with no sidecar and no application change. CiliumNetworkPolicy expresses application-aware rules: HTTP methods and paths, gRPC services, and DNS/FQDN-based egress. That’s what makes the least-privilege model actually achievable: "this service may call that service" becomes "this service may call exactly this operation on that service." ##### Zero trust in developer platforms Installing Cilium does not give you zero trust. It gives you the mechanism for it; a fast, identity-based enforcement engine that can express the exact rules you want. Orchestrating the policies to enforce zero trust while giving platform teams a way to govern them should come as a property of the developer platform built on top of Cilium. There are several ways to achieve zero trust in a developer platform. - **Developers author their own policies.** Nobody understands a service's dependencies better than the team that built it, so this is the most flexible option, and the policies it produces can be exactly right, at least at first. The difficulty isn't competence. CiliumNetworkPolicy becomes one more thing to learn and maintain, alongside the language and frameworks the service is actually written in. Services gain endpoints, drop dependencies, and get refactored, while the policy sits in a separate file that someone has to remember to update. Some drift open, because nothing breaks when they do. Some are never written at all. Some are written carefully and then quietly rot. - **Platform teams pre-provision isolated environments with policy already applied.** This is a good, common pattern: developers receive an environment that is default-deny from the moment they get it, and they never touch a CiliumNetworkPolicy. The limits are granularity and change. A policy scoped to the whole environment can't know that one component listens on 8080 and another on 9090, so it either permits more than it should inside the boundary, or it needs a request to the platform team for every new endpoint, the exact ticket queue an Internal Developer Platform (IDP) exists to remove. - **The platform derives policy, the platform team governs it.** If a developer states an endpoint's intended reach as part of deploying it, the platform has everything it needs to generate the policy itself. Policy stops being an artifact anyone maintains and becomes an output of deployment, while the platform team keeps control over any exceptions. That third option is what makes a developer platform zero-trust by default. It rests on the following properties, which are not specific to any vendor: - **Policy is derived from declared intent** rather than authored separately, so intent and enforcement cannot disagree. - **Policy is regenerated as the workload changes**, so it cannot drift. - **Default-deny is a byproduct**, not a checklist item. A workload is restricted because it was deployed, not because someone remembered. - **The boundary is owned by the platform**, so it is held by construction rather than by convention. None of that is achievable by just installing a CNI, and none of it requires developers to learn one. It requires abstractions that carry enough intent for the platform to act on. ##### What this looks like in practice: OpenChoreo and Cilium Those four properties are easy to state and harder to build. They require a platform that already knows what a workload is, not just where it's running. OpenChoreo is one example of a developer platform built this way, and it's a useful one to walk through concretely, since it wires the same identity-based model straight into Cilium. [OpenChoreo](https://openchoreo.dev/) is an open-source internal developer platform for Kubernetes, and a CNCF sandbox project. Developers work with a simpler set of Kubernetes-native abstractions (Project, Component, Environment,...) wired to a Backstage-based portal, CI/CD, GitOps, and observability, while platform teams keep full visibility of the underlying cluster. Individual capabilities ship as swappable modules from a growing ecosystem, including a networking module that builds on Cilium as the cluster CNI. Its runtime model and abstractions provide exactly what is needed to have zero trust by default. Each OpenChoreo **Project** becomes a [**Cell**](https://openchoreo.dev/docs/concepts/runtime-model/) at runtime: a secure, isolated runtime boundary that encapsulates all components of an application domain. Concretely, every (project, environment) pair maps to its own dedicated data-plane namespace, and every pod deployed into it is labelled with its full platform identity: which namespace, project, component, and environment. Components inside a cell communicate freely. Anything crossing a cell boundary goes through a defined gateway. The other half of the picture is a single field that developers already fill in. When a developer declares an endpoint on their workload, they state its visibility: | Visibility | Who can reach it | |:---------- |:------------------------------------------------------------------------------------------------------- | | `project` | Only components in the same project, within the same environment _(implicit — every endpoint gets this)_ | | `namespace` | Any project in the same namespace within the same environment | | `internal` | Across all namespaces in the platform | | `external` | Exposed publicly, via the external gateway | That's the entire developer-facing surface. No selectors, no port lists, no CRDs. From there, OpenChoreo's built-in controllers do the translation. When a component is deployed, the platform renders the workload's Kubernetes resources and injects a network policy alongside them, built from the component's pod identity labels and its declared endpoint visibilities. The policy is regenerated on every reconcile, so it tracks the component as it changes rather than drifting from it. For a single HTTP endpoint with `project` visibility, the result is a policy that selects the component by identity and admits traffic only from inside its own cell: ```yaml apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: openchoreo-web-app spec: endpointSelector: matchLabels: openchoreo.dev/component: web-app openchoreo.dev/project: my-project ingress: - fromEndpoints: - {} # any endpoint in this cell's namespace toPorts: - ports: - port: '8080' protocol: TCP rules: http: [{}] # routed via Envoy for L7 visibility ``` This YAML was not written by a developer to allow ingress into their component. It's rendered at deployment time. The important part is what it omits: because a CiliumNetworkPolicy selects this component, everything not listed is denied. Default-deny isn't a separate policy the platform team must remember to apply, it's the consequence of the component having a policy at all. Raise the endpoint to `namespace` visibility and an additional rule appears, scoped to the same namespace and environment. Mark it `external` and a rule admitting ingress from the platform's gateway appears. Neither requires the developer to know any of this happened. > _Fig 1: OpenChoreo’s Backstage portal Kubernetes artifacts view for a deployed component, showing the generated `CiliumNetworkPolicy` listed alongside the Deployment, Service, and HTTPRoute._ For the platform engineer, adopting this is deliberately simple. Install Cilium as the CNI on the data-plane cluster, then annotate the `DataPlane`/`ClusterDataPlane` OpenChoreo custom resource to explicitly mark it as a Cilium-powered data plane. ```shell kubectl annotate clusterdataplanes.openchoreo.dev default \ openchoreo.dev/networkpolicyprovider=cilium --overwrite ``` Every subsequent deployment renders CiliumNetworkPolicies instead of standard Kubernetes NetworkPolicies. Without the annotation, OpenChoreo emits plain NetworkPolicies, so clusters without Cilium still get project isolation, just at L3/L4. Same developer abstraction, different enforcement engine underneath. That's what makes the abstraction worth having: the platform team can upgrade the enforcement model without touching a single application. Currently, the generated policies use Cilium's L7 hook for network observability: an empty HTTP rule allows all requests on the port while routing them through Envoy so Hubble can observe them. They also cover ingress only: OpenChoreo does not yet derive egress rules from a developer-facing abstraction. That doesn't leave egress ungoverned, it just moves the control point from the endpoint to the cell boundary. A `ProjectType` carries a list of resource templates that OpenChoreo renders into the cell namespace of every project of that type, and a template can be any namespace-scoped manifest, including a CiliumNetworkPolicy. The platform engineer writes the policy once and every cell created from that project type inherits it: ```yaml apiVersion: openchoreo.dev/v1alpha1 kind: ClusterProjectType metadata: name: standard-service spec: resources: - id: cell-namespace # Isolated runtime namespace for workloads targetPlane: dataplane template: apiVersion: v1 kind: Namespace metadata: name: ${metadata.namespace} - id: cell-egress # Templated network policy to secure egress from the cell boundary targetPlane: dataplane template: apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: cell-egress namespace: ${metadata.namespace} spec: endpointSelector: {} # every pod in the cell egress: - toFQDNs: # egress denied except for api.stripe.com - matchName: api.stripe.com - toEndpoints: # allow dns resolution - matchLabels: k8s-app: kube-dns k8s:io.kubernetes.pod.namespace: kube-system toPorts: - ports: - port: '53' protocol: UDP - port: '53' protocol: TCP rules: dns: - matchPattern: '*' ``` Because those templates are evaluated with CEL against the project's parameters and per-environment configs, a platform engineer can expose the allowlist as a project parameter, rather than hard-coding it into the template. Developers then declare which hosts they need; the platform engineer controls the shape of the policy those declarations produce, and production can end up stricter than development. It’s the same derive-and-govern split described earlier for ingress, applied to egress using a general-purpose mechanism instead of a purpose-built one. That distinction matters: this is a pattern, not a native abstraction. The platform engineer writes and maintains CiliumNetworkPolicy directly, and unlike endpoint visibility it does not fall back to plain NetworkPolicies on a non-Cilium data plane, since FQDN-based egress is a Cilium-specific capability. A first-class egress abstraction is on the roadmap, and the identity foundation is what makes that addition incremental rather than architectural. ##### Identity that enforces zero trust also makes the network observable Identifying workloads by platform identity instead of IP has a useful side effect: the network observability data arrives labelled with concepts developers actually use. Because Hubble sees every flow and knows each endpoint's project, component, and environment, OpenChoreo can render network behaviour in the developer's own context rather than as a table of IP addresses. The [Cilium networking module](https://openchoreo.dev/ecosystem/item/networking-cilium/) for OpenChoreo surfaces the following network observability features: - A runtime cell diagram showing which components are genuinely talking to each other, derived from live Hubble flows. - Real-time wirelogs: a live stream of Hubble flow events, scoped per component, with source and destination resolved to platform identities rather than pod IPs. - HTTP throughput and latency metrics per component, derived from Hubble's HTTP metrics. > _Fig 2: Live component-to-component traffic within a cell_ > _Fig 3: Streaming network wirelogs for a component_ > _Fig 4: HTTP throughput and latency per component_ Teams often hesitate to lock things down because they can't tell what depends on what. Seeing the actual traffic removes the guesswork, and that's what makes a policy safe to tighten. ##### Conclusion: Secure defaults, full velocity Zero trust doesn't have to mean zero velocity. The two only conflict when security is a task appended to the end of the delivery path instead of a property of the path itself. Identity-based policy makes the enforcement model durable enough to automate; a platform with real abstractions makes the automation invisible. Put them together and a developer declaring an endpoint's visibility produces an eBPF-enforced, default-deny, identity-based network boundary that survives every reschedule their workload will ever experience. All without the developer knowing the complexity underneath. ##### References - [Cilium documentation](https://docs.cilium.io/) — eBPF datapath, identities, and network policy reference - [OpenChoreo Cilium networking module](https://openchoreo.dev/ecosystem/item/networking-cilium/) — installation, configuration, and compatibility matrix - [OpenChoreo runtime model](https://openchoreo.dev/docs/concepts/runtime-model/) — cells, gateway topology, and isolation boundaries - [OpenChoreo repository](https://github.com/openchoreo/openchoreo) #### Troubleshooting Kubernetes Networking URL: https://cilium.io/blog/2026/08/16/troubleshooting-kubernetes-networking Date: 2026-08-16 Categories: Networking, Technology ##### Troubleshooting Kubernetes Networking ##### 1.0 Introduction Networking is notoriously one of the most common failure points encountered in workloads deployed within a Kubernetes environment. Because a cluster consists of hundreds or thousands of ephemeral compute resources (pods, nodes, and services) constantly spinning up, shutting down, and scaling, the underlying network layer bears the immense responsibility of keeping everything connected. When an application breaks in Kubernetes, **_it is probably a network issue_**. Before container orchestration, it was somewhat easy to troubleshoot outages led by networking challenges. Servers had static IP addresses, physical switches had predictable ports, and firewalls relied on static rules. Kubernetes completely shatters this model. The challenges of debugging Kubernetes networks stem directly from its highly dynamic architecture: - **Ephemeral IP Addresses**: Pod IPs change every time a deployment is scaled, restarted, or rescheduled to a new node. Tracking down a connection failure using a raw IP address from an hour-old log file is often useless, as that IP may now belong to a completely different application. - **Complex Abstractions**: Traffic routing relies on overlapping, virtualized abstractions like ClusterIPs, NodePorts, Ingress controllers, and CoreDNS. - **The iptables Black Box**: Historically, Kubernetes relied heavily on kube-proxy and massive, sequential lists of iptables rules to route traffic. When a packet is unexpectedly dropped, tracing it through thousands of generic rules to find the exact misconfiguration is incredibly difficult and completely lacks appliscreen readercation-level context. Misconfiguration is consistently reported as the leading source of Kubernetes incidents [\[Red Hat 2024\]](https://www.redhat.com/en/resources/kubernetes-adoption-security-market-trends-overview), while networking and DNS faults, though less frequent, are disproportionately difficult to localise. ##### 2.0 OSI Stack Kubernetes abstracts away physical infrastructure, but the OSI model does not disappear; it shifts. Every packet sent between pods, services, nodes, or external clients still traverses all seven layers. What changes is who owns each layer: the Linux kernel, the CNI plugin, kube-proxy (or its replacement), CoreDNS, Ingress controllers, and application code. Each operates at different OSI levels, and when something breaks, the layer boundary is usually where you start your investigation. Cilium's datapath is unique because it operates simultaneously at Layers 2-7 through kernel hooks, including TC (traffic control), XDP (Layer 2/3), kprobes, and socket-level filters (Layer 4), as well as Envoy-integrated Layer 7 parsing. This means a single Cilium-equipped cluster can surface and debug issues at every OSI layer through one unified toolchain: Hubble, cilium-dbg, and the BPF map inspection commands. _Figure 1: OSI stack. Image credit: Cloudflare, "What is the OSI Model?" Cloudflare Learning Center. [https://www.cloudflare.com/learning/ddos/glossary/open-systems-interconnection-model-osi/](https://www.cloudflare.com/learning/ddos/glossary/open-systems-interconnection-model-osi/)_ ###### Physical Layer: Node and NIC Failures Although Kubernetes doesn't manage physical hardware directly, L1 failures surface immediately in cluster networking. ###### Symptoms - Node becomes NotReady in `kubectl get nodes` - All pods on the affected node become unreachable - cilium status reports Cluster health: 0/N reachable for the affected node Common causes in cloud and on-prem - MTU mismatch between the host NIC and the overlay tunnel. Cilium's VXLAN encapsulation adds 50 bytes of overhead. If the underlay MTU is 1500 and Cilium uses 1500 for pod traffic, frames are silently dropped during fragmentation. - NIC queue saturation on high-throughput nodes. [Read More about MTU Overhead](https://docs.cilium.io/en/stable/network/concepts/routing/) Cilium Commands `# Inspect the route MTU on the cilium_host interface` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- ip link show cilium_host 4: cilium_host@cilium_net: mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 5e:9d:ba:cf:a2:84 brd ff:ff:ff:ff:ff:ff ``` `# Check MTU configuration used by Cilium` ```shell root@server:~# kubectl -n kube-system exec -it ds/cilium -- cilium status --verbose | grep -i mtu │ ├── mtu │ │ ├── job-endpoint-mtu-updater [OK] Endpoint MTU updated (14m, x1) │ │ └── job-mtu-updater [OK] MTU updated (1500) (14m, x1) ``` `# Verify MTU on the overlay interface (if using tunnel mode)` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- ip link show cilium_vxlan 5: cilium_vxlan: mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default link/ether 3a:0d:29:2d:1f:14 brd ff:ff:ff:ff:ff:ff ``` ###### Data Link: ARP, MAC Resolution, Bridge Issues With symptoms like pods on the same node failing to communicate, and intermittent packet loss between pods on adjacent nodes. Common causes - ARP flux: nodes with multiple interfaces can reply to ARP requests from the wrong interface, causing asymmetric routes. - Bridge netfilter disabled: if net.bridge.bridge-nf-call-iptables is off, kube-proxy-based clusters break at L2/L3 boundary (less relevant with Cilium's full eBPF replacement, but still matters during migration) - Cilium is using veth device mode, where the veth peer goes missing after pod restart, due to race conditions. `# List all endpoints and their MAC / IP state` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg endpoint list ENDPOINT POLICY (ingress) POLICY (egress) IDENTITY LABELS (source:key[=value]) IPv6 IPv4 STATUS ENFORCEMENT ENFORCEMENT 2179 Disabled Disabled 1 reserved:host ready 2216 Disabled Disabled 8 reserved:ingress 10.244.2.108 ready 2450 Disabled Disabled 4 reserved:health 10.244.2.19 ready root@server:~# ``` `# Check if the veth pair for a specific endpoint is intact` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- ip link show | grep lxc 7: lxc_health@if6: mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 root@server:~# ``` ###### Network Layer: IP Routing, IPAM, Overlay Tunnels This is the most frequently hit layer in Kubernetes networking incidents. Most "pod can't reach pod on another node" issues live here. Most of the time, issues in this layer are characterised by a timeout in ping between two pods, an internode traffic drop while intra-node traffic is ok, and CoreDNS unreachable with a timeout. Common causes: - IPAM exhaustion: Cilium's default cluster-pool IPAM allocates pod CIDRs per node. If the CIDR is exhausted, new pods fail to launch with IP assignment errors. - Missing or stale BPF route entries after node restarts. - VXLAN tunnel mismatch: Two nodes on different overlay VTEP configurations can't establish a tunnel. - IP masquerade misconfigured: pods can reach the cluster network but not external services because SNAT rules aren't applied correctly. Cilium Commands `# Check IPAM allocation state` `kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf ipmasq list` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf ipmasq list No entries found. root@server:~# ``` `# Inspect the IP address manager` `kubectl -n kube-system exec ds/cilium -- cilium-dbg ip list` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg ip list IP IDENTITY SOURCE 0.0.0.0/0 reserved:world 10.244.0.0/24 reserved:world 10.244.1.0/24 reserved:world 10.244.0.76/32 reserved:ingress 10.244.0.127/32 reserved:remote-node 10.244.0.139/32 reserved:health 10.244.1.112/32 reserved:remote-node 10.244.1.230/32 reserved:health 10.244.1.251/32 reserved:ingress 10.244.2.17/32 k8s:app=local-path-provisioner custom-resource k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=local-path-storage k8s:io.cilium.k8s.policy.cluster=kind-kind k8s:io.cilium.k8s.policy.serviceaccount=local-path-provisioner-service-account k8s:io.kubernetes.pod.namespace=local-path-storage 10.244.2.72/32 reserved:host 10.244.2.73/32 reserved:ingress 10.244.2.76/32 k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system custom-resource k8s:io.cilium.k8s.policy.cluster=kind-kind k8s:io.cilium.k8s.policy.serviceaccount=coredns k8s:io.kubernetes.pod.namespace=kube-system k8s:k8s-app=kube-dns 10.244.2.127/32 reserved:health 10.244.2.149/32 k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=kube-system custom-resource k8s:io.cilium.k8s.policy.cluster=kind-kind k8s:io.cilium.k8s.policy.serviceaccount=coredns k8s:io.kubernetes.pod.namespace=kube-system k8s:k8s-app=kube-dns 172.18.0.2/32 reserved:remote-node 172.18.0.3/32 reserved:kube-apiserver reserved:remote-node 172.18.0.4/32 reserved:host root@server:~# ``` `# List all BPF routing entries` `kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf ipcache list` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf ipcache list IP PREFIX/ADDRESS IDENTITY 10.244.0.139/32 identity=4 encryptkey=0 tunnelendpoint=172.18.0.3 flags=hastunnel 10.244.1.0/24 identity=2 encryptkey=0 tunnelendpoint=172.18.0.2 flags=hastunnel 10.244.2.72/32 identity=1 encryptkey=0 tunnelendpoint=0.0.0.0 flags= 10.244.0.0/24 identity=2 encryptkey=0 tunnelendpoint=172.18.0.3 flags=hastunnel 10.244.1.112/32 identity=6 encryptkey=0 tunnelendpoint=172.18.0.2 flags=hastunnel 10.244.2.17/32 identity=3388 encryptkey=0 tunnelendpoint=0.0.0.0 flags= 172.18.0.2/32 identity=6 encryptkey=0 tunnelendpoint=0.0.0.0 flags= 172.18.0.3/32 identity=7 encryptkey=0 tunnelendpoint=0.0.0.0 flags= 172.18.0.4/32 identity=1 encryptkey=0 tunnelendpoint=0.0.0.0 flags= 10.244.1.230/32 identity=4 encryptkey=0 tunnelendpoint=172.18.0.2 flags=hastunnel 10.244.2.73/32 identity=8 encryptkey=0 tunnelendpoint=0.0.0.0 flags= 10.244.2.149/32 identity=48339 encryptkey=0 tunnelendpoint=0.0.0.0 flags= 10.244.0.76/32 identity=8 encryptkey=0 tunnelendpoint=172.18.0.3 flags=hastunnel 10.244.0.127/32 identity=6 encryptkey=0 tunnelendpoint=172.18.0.3 flags=hastunnel 10.244.1.251/32 identity=8 encryptkey=0 tunnelendpoint=172.18.0.2 flags=hastunnel 10.244.2.76/32 identity=48339 encryptkey=0 tunnelendpoint=0.0.0.0 flags= 10.244.2.127/32 identity=4 encryptkey=0 tunnelendpoint=0.0.0.0 flags= 0.0.0.0/0 identity=2 encryptkey=0 tunnelendpoint=0.0.0.0 flags= root@server:~# ``` `# Check the ipcache — maps pod IPs to identities and tunnel endpoints` `kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf ipcache get ` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf ipcache get 10.244.1.45 10.244.1.45 maps to identity identity=6026 encryptkey=0 tunnelendpoint=172.18.0.2 flags=hastunnel root@server:~# ``` `# Verify tunnel map (VXLAN/Geneve mode)` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -c cilium-agent -- cilium-dbg node list Name IPv4 Address Endpoint CIDR IPv6 Address Endpoint CIDR Source kind-kind/kind-control-plane 172.18.0.3 10.244.0.0/24 custom-resource kind-kind/kind-worker 172.18.0.4 10.244.2.0/24 local kind-kind/kind-worker2 172.18.0.2 10.244.1.0/24 custom-resource root@server:~# ``` `# Run Cilium's built-in connectivity test` ```shell root@server:~# cilium connectivity test ℹ️ Monitor aggregation detected, will skip some flow validation steps ✨ [kind-kind] Creating namespace cilium-test-1 for connectivity check... ✨ [kind-kind] Deploying echo-same-node service... ✨ [kind-kind] Deploying DNS test server configmap... ✨ [kind-kind] Deploying same-node deployment... ✨ [kind-kind] Deploying client deployment... ✨ [kind-kind] Deploying client2 deployment... ✨ [kind-kind] Deploying client3 deployment... ✨ [kind-kind] Deploying echo-other-node service... ✨ [kind-kind] Deploying other-node deployment... ✨ [host-netns] Deploying kind-kind daemonset... ✨ [host-netns-non-cilium] Deploying kind-kind daemonset... ℹ️ Skipping tests that require a node Without Cilium ⌛ [kind-kind] Waiting for deployment cilium-test-1/client to become ready... ``` Hubble (L3 drops) `# Watch all dropped flows at L3 with reason` ```shell root@server:~# hubble observe --type drop --last 200 -o jsonpb | jq '.flow | {src: .source.pod_name, dst: .destination.pod_name, reason: .drop_reason_desc}' { "src": null, "dst": null, "reason": "UNSUPPORTED_L3_PROTOCOL" } { "src": null, "dst": null, "reason": "UNSUPPORTED_L3_PROTOCOL" } ``` `# Watch traffic between two specific pods` ```shell root@server:~# hubble observe --from-pod default/frontend --to-pod default/backend --follow ``` ###### ###### Transport Layer: TCP/UDP Services Network issues in this layer are characterised by failure in TCP connections despite being able to ping it, NodePort services being reachable from only a few nodes but not others, uneven distribution of traffic in Load Balancer services, and exhausted connections in the nf_conntrack table. Common Causes: - Cilium service map out of sync with Kubernetes Endpoints: endpoints change faster than Cilium's reconciliation loop, especially during rolling deploys. - kube-proxy running alongside Cilium in partial replacement mode, creating conflicting NAT rules. - BPF NAT map full (default 524288 entries) on very high-connection-rate nodes - Session affinity misconfiguration is causing stickiness to terminate pods. Cilium Commands `# List all Cilium-managed services and their backends` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg service list ID Frontend Service Type Backend 1 10.96.0.1:443/TCP ClusterIP 1 => 172.18.0.4:6443/TCP (active) 2 0.0.0.0:30464/TCP NodePort 4 0.0.0.0:30977/TCP NodePort 6 10.96.183.162:80/TCP ClusterIP 7 10.96.183.162:443/TCP ClusterIP 8 10.96.248.144:443/TCP ClusterIP 1 => 172.18.0.3:4244/TCP (active) 9 0.0.0.0:31234/TCP NodePort 1 => 10.244.1.248:4245/TCP (active) 11 10.96.218.16:80/TCP ClusterIP 1 => 10.244.1.248:4245/TCP (active) 12 0.0.0.0:31235/TCP NodePort 1 => 10.244.1.174:8081/TCP (active) 14 10.96.108.211:80/TCP ClusterIP 1 => 10.244.1.174:8081/TCP (active) 15 10.96.0.10:53/TCP ClusterIP 1 => 10.244.1.82:53/TCP (active) 2 => 10.244.1.102:53/TCP (active) 16 10.96.0.10:53/UDP ClusterIP 1 => 10.244.1.82:53/UDP (active) 2 => 10.244.1.102:53/UDP (active) 17 10.96.0.10:9153/TCP ClusterIP 1 => 10.244.1.82:9153/TCP (active) 2 => 10.244.1.102:9153/TCP (active) 18 172.18.255.200:80/TCP LoadBalancer 19 172.18.255.200:443/TCP LoadBalancer 20 10.96.141.89:80/TCP ClusterIP 1 => 10.244.2.163:80/TCP (active) root@server:~# ``` `# Check a specific service's backend health` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg service list ID Frontend Service Type Backend 1 10.96.0.1:443/TCP ClusterIP 1 => 172.18.0.4:6443/TCP (active) 2 0.0.0.0:30464/TCP NodePort 4 0.0.0.0:30977/TCP NodePort 6 10.96.183.162:80/TCP ClusterIP 7 10.96.183.162:443/TCP ClusterIP 8 10.96.248.144:443/TCP ClusterIP 1 => 172.18.0.3:4244/TCP (active) 9 0.0.0.0:31234/TCP NodePort 1 => 10.244.1.248:4245/TCP (active) 11 10.96.218.16:80/TCP ClusterIP 1 => 10.244.1.248:4245/TCP (active) 12 0.0.0.0:31235/TCP NodePort 1 => 10.244.1.174:8081/TCP (active) 14 10.96.108.211:80/TCP ClusterIP 1 => 10.244.1.174:8081/TCP (active) 15 10.96.0.10:53/TCP ClusterIP 1 => 10.244.1.82:53/TCP (active) 2 => 10.244.1.102:53/TCP (active) 16 10.96.0.10:53/UDP ClusterIP 1 => 10.244.1.82:53/UDP (active) 2 => 10.244.1.102:53/UDP (active) 17 10.96.0.10:9153/TCP ClusterIP 1 => 10.244.1.82:9153/TCP (active) 2 => 10.244.1.102:9153/TCP (active) 18 172.18.255.200:80/TCP LoadBalancer 19 172.18.255.200:443/TCP LoadBalancer 20 10.96.141.89:80/TCP ClusterIP 1 => 10.244.2.163:80/TCP (active) root@server:~# ``` `# Inspect the BPF load balancer map (frontend VIP → backends)` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf lb list SERVICE ADDRESS BACKEND ADDRESS (REVNAT_ID) (SLOT) 10.96.218.16:80/TCP (1) 10.244.1.248:4245/TCP (11) (1) 10.96.248.144:443/TCP (1) 172.18.0.3:4244/TCP (8) (1) 10.96.141.89:80/TCP (1) 10.244.2.163:80/TCP (20) (1) 10.96.0.10:53/TCP (0) 0.0.0.0:0 (15) (0) [ClusterIP, non-routable] 10.96.108.211:0/ANY (0) 0.0.0.0:0 (0) (0) [ClusterIP, non-routable] 0.0.0.0:31235/TCP (1) 10.244.1.174:8081/TCP (12) (1) 10.96.141.89:0/ANY (0) 0.0.0.0:0 (0) (0) [ClusterIP, non-routable] 172.18.0.3:31234/TCP (0) 0.0.0.0:0 (10) (0) [NodePort] 172.18.0.3:31235/TCP (1) 10.244.1.174:8081/TCP (13) (1) .... ``` `# Check BPF NAT table (active SNAT mappings)` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf nat list TCP OUT 172.18.0.3:34178 -> 54.234.221.194:443 XLATE_SRC 172.18.0.3:34178 Created=408sec ago NeedsCT=1 TCP IN 54.234.221.194:443 -> 172.18.0.3:34178 XLATE_DST 172.18.0.3:34178 Created=408sec ago NeedsCT=1 TCP IN 172.18.0.4:6443 -> 172.18.0.3:58624 XLATE_DST 172.18.0.3:58624 Created=667sec ago NeedsCT=1 TCP OUT 172.18.0.3:59112 -> 172.18.0.4:4240 XLATE_SRC 172.18.0.3:59112 Created=297sec ago NeedsCT=1 TCP OUT 172.18.0.3:54010 -> 13.249.228.49:443 XLATE_SRC 172.18.0.3:54010 Created=406sec ago NeedsCT=1 ``` `# Check connection tracking table` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf ct list global TCP OUT 172.18.0.3:58624 -> 172.18.0.4:6443 expires=19466 Packets=0 Bytes=0 RxFlagsSeen=0x18 LastRxReport=11461 TxFlagsSeen=0x1a LastTxReport=11461 Flags=0x0010 [ SeenNonSyn ] RevNAT=0 SourceSecurityID=0 BackendID=0 NatPort=0 TCP OUT 10.244.2.148:38566 -> 10.244.0.34:4240 expires=19462 Packets=0 Bytes=0 RxFlagsSeen=0x1a LastRxReport=11462 TxFlagsSeen=0x1a LastTxReport=11462 Flags=0x0010 [ SeenNonSyn ] RevNAT=0 SourceSecurityID=0 BackendID=0 NatPort=0 ``` `# Compare Kubernetes services with what Cilium has programmed` `# (discrepancies = sync lag or bug)` ```shell root@server:~# kubectl get svc --all-namespaces NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default backend-service ClusterIP 10.96.141.89 80/TCP 10m default kubernetes ClusterIP 10.96.0.1 443/TCP 3h11m kube-system cilium-envoy ClusterIP None 9964/TCP 15m kube-system cilium-ingress LoadBalancer 10.96.183.162 172.18.255.200 80:30977/TCP,443:30464/TCP 15m kube-system hubble-metrics ClusterIP None 9965/TCP 15m .... root@server:~# ``` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg service list ID Frontend Service Type Backend 1 10.96.0.1:443/TCP ClusterIP 1 => 172.18.0.4:6443/TCP (active) 2 0.0.0.0:30464/TCP NodePort 4 0.0.0.0:30977/TCP NodePort 6 10.96.183.162:80/TCP ClusterIP 7 10.96.183.162:443/TCP ClusterIP 8 10.96.248.144:443/TCP ClusterIP 1 => 172.18.0.3:4244/TCP (active) 9 0.0.0.0:31234/TCP NodePort 1 => 10.244.1.248:4245/TCP (active) 11 10.96.218.16:80/TCP ClusterIP 1 => 10.244.1.248:4245/TCP (active) 12 0.0.0.0:31235/TCP NodePort 1 => 10.244.1.174:8081/TCP (active) 14 10.96.108.211:80/TCP ClusterIP 1 => 10.244.1.174:8081/TCP (active) 15 10.96.0.10:53/TCP ClusterIP 1 => 10.244.1.82:53/TCP (active) 2 => 10.244.1.102:53/TCP (active) ... ``` Hubble for L4 Drops `# Watch TCP-specific drops` ```shell root@server:~# hubble observe --type drop --protocol TCP --follow ``` `# Filter by specific port` ```shell root@server:~# hubble observe --to-port 80 --follow ``` `# Check policy verdicts at L4` ```shell root@server:~# hubble observe --type policy-verdict --follow ``` ###### Session Layer: Connection Tracking and Keep-Alive Issues Kubernetes doesn't surface a dedicated session layer, but TCP session management is a real operational concern in long-lived microservice connections. Connections appear active in the application but not in BPF ConTrack Maps. **Common Causes:** - BPF connection tracking idle timeout (default 300s for TCP established) terminates long-lived connections silently. - NAT timeout is too aggressive for idle database connections. - TCP keep-alive is not configured at the application level, and connections silently close mid-stream. Cilium Commands `# View CT timeouts and current CT table` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf ct list global | head -50 TCP IN 10.244.1.46:56068 -> 10.244.2.219:4240 expires=11750 Packets=0 Bytes=0 RxFlagsSeen=0x1b LastRxReport=11740 TxFlagsSeen=0x1b LastTxReport=11740 Flags=0x0413 [ RxClosing TxClosing SeenNonSyn FromTunnel ] RevNAT=0 SourceSecurityID=6 BackendID=0 NatPort=0 TCP OUT 10.244.2.148:44772 -> 10.244.1.106:4240 expires=11711 Packets=0 Bytes=0 RxFlagsSeen=0x1b LastRxReport=11701 TxFlagsSeen=0x1b LastTxReport=11701 Flags=0x0013 [ RxClosing TxClosing SeenNonSyn ] RevNAT=0 SourceSecurityID=0 BackendID=0 NatPort=0 ``` `# Check Cilium config for current CT settings` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg config | grep -i conntrack ConntrackAccounting : Disabled root@server:~# ``` ###### Presentation Layer: TLS, mTLS, Certificate Issues This is normally characterised by TLS handshake timeout or certificate verification failed; mTLS between pods fails after certificate rotation. Common Causes - Cilium WireGuard encryption is enabled on some nodes but not all (mixed encryption state). - certificate expiry in the SPIFFE/SPIRE integration causes identity verification failures. - Ingress TLS secret missing or expired, causing 503 from the Ingress controller. Commands `# Check WireGuard encryption status on all nodes` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg encrypt status Encryption: Disabled root@server:~# ``` `# Check node-to-node encryption state` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg node list Name IPv4 Address Endpoint CIDR IPv6 Address Endpoint CIDR Source kind-kind/kind-control-plane 172.18.0.4 10.244.0.0/24 custom-resource kind-kind/kind-worker 172.18.0.3 10.244.2.0/24 local kind-kind/kind-worker2 172.18.0.2 10.244.1.0/24 custom-resource root@server:~# ``` Hubble for TLS Drops ```shell # Watch flows with encryption status hubble observe --follow -o jsonpb | jq 'select(.flow.is_reply == false) | {src: .flow.source.pod_name, dst: .flow.destination.pod_name, encrypted: .flow.traffic_direction}' { "src": null, "dst": "hubble-relay-5bbf66658c-k6958", "encrypted": "INGRESS" } { "src": null, "dst": "hubble-relay-5bbf66658c-k6958", "encrypted": "INGRESS" } ``` ###### Application Layer: HTTP, gRPC, DNS, FQDN Policies This is where Cilium visibly exceeds. Cilium extends network policy enforcement to Layers 3, 4, and 7, enabling more granular control over ingress and egress traffic based on application behavior, including DNS support and mTLS. The following are the common challenges in the application layer. - Misconfigured Network Policies are a common issue - DNS resolution failure Symptoms - HTTP 403/404 responses that only affect specific paths, not the whole service - DNS resolution fails for external FQDNs, but pod IPs are reachable - gRPC calls time out on specific methods but not others - CiliumNetworkPolicy with HTTP rules is blocking traffic that should be allowed `# List all endpoints with L7 policy` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg endpoint list ENDPOINT POLICY (ingress) POLICY (egress) IDENTITY LABELS (source:key[=value]) IPv6 IPv4 STATUS ENFORCEMENT ENFORCEMENT 180 Disabled Disabled 10064 k8s:app=frontend 10.244.2.199 ready k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default k8s:io.cilium.k8s.policy.cluster=kind-kind k8s:io.cilium.k8s.policy.serviceaccount=default k8s:io.kubernetes.pod.namespace=default ``` `# Inspect FQDN cache (is the DNS entry resolved and cached?)` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg fqdn cache list Endpoint Source FQDN TTL ExpirationTime IPs root@server:~# ``` `# Watch all HTTP flows cluster-wide (requires L7 visibility enabled)` ```shell root@server:~# hubble observe --protocol http --follow ``` `# Watch DNS queries and responses` ```shell root@server:~# hubble observe --protocol dns --follow ``` `# Trace a specific pod's HTTP traffic` ```shell root@server:~# hubble observe --from-pod default/frontend --protocol http --follow ``` `# Watch TCP specifically` ```shell root@server:~# hubble observe --protocol tcp --follow Jun 24 23:10:00.032: 172.18.0.3:58624 (host) -> 172.18.0.4:6443 (kube-apiserver) to-network FORWARDED (TCP Flags: ACK, PSH) Jun 24 23:10:00.286: 172.18.0.3:58636 (host) -> 172.18.0.4:6443 (kube-apiserver) to-network FORWARDED (TCP Flags: ACK, PSH) Jun 24 23:10:00.669: 10.244.0.99:37982 (world) -> kube-system/hubble-relay-5bbf66658c-k6958:4245 (ID:14331) to-overlay FORWARDED (TCP Flags: ACK, PSH) ``` `# Show L7 policy verdicts (ALLOW vs DENY with path detail)` ```shell root@server:~# hubble observe --type policy-verdict --protocol http --follow ``` ###### Cross-layer Challenges Common in Kubernetes These challenges often happen when failures occur across different layers of the stack. - MTU Cascade: Incorrect MTU settings can result in packet drops and performance degradation. This is particularly difficult to diagnose, as it might only happen when transferring large payloads. To detect this in your cluster, prioritise using Hubble to monitor and analyse your network traffic. It is important to verify Cilium MTU configuration. - Policy Drift: This occurs when the current state of your cluster configuration deviates from the defined state as specified in code templates. To detect this in your cluster, prioritise using Hubble to monitor. ##### 2.0 The Cilium Diagnostic Toolkit Cilium provides a comprehensive set of built-in troubleshooting tools that leverage its eBPF data plane to expose information that is impossible to obtain with traditional networking tools. When a pod can't connect to a service, traceroute and tcpdump provide incomplete answers because they operate outside the kernel eBPF context where Cilium performs its work. `# Overall Healthcheck` ```shell root@server:~# cilium status --verbose /¯¯\ /¯¯\__/¯¯\ Cilium: OK \__/¯¯\__/ Operator: OK /¯¯\__/¯¯\ Envoy DaemonSet: OK \__/¯¯\__/ Hubble Relay: OK \__/ ClusterMesh: disabled DaemonSet cilium Desired: 3, Ready: 3/3, Available: 3/3 DaemonSet cilium-envoy Desired: 3, Ready: 3/3, Available: 3/3 Deployment cilium-operator Desired: 1, Ready: 1/1, Available: 1/1 Deployment hubble-relay Desired: 1, Ready: 1/1, Available: 1/1 Deployment hubble-ui Desired: 1, Ready: 1/1, Available: 1/1 Containers: cilium Running: 3 cilium-envoy Running: 3 cilium-operator Running: 1 clustermesh-apiserver hubble-relay Running: 1 hubble-ui Running: 1 ``` `# Check all Cilium pods` ```shell root@server:~# kubectl get pods -n kube-system -l k8s-app=cilium NAME READY STATUS RESTARTS AGE cilium-5pks9 1/1 Running 0 8m50s cilium-rl6n5 1/1 Running 0 8m50s cilium-wdvhp 1/1 Running 0 8m50s root@server:~# ``` `# Perform endpoint inspection` ```shell root@server:~# kubectl exec -n kube-system cilium-6vxzs -- cilium-dbg endpoint list ENDPOINT POLICY (ingress) POLICY (egress) IDENTITY LABELS (source:key[=value]) IPv6 IPv4 STATUS ENFORCEMENT ENFORCEMENT 126 Disabled Disabled 8 reserved:ingress 10.244.0.14 ready 839 Disabled Disabled 4 reserved:health 10.244.0.196 ready 2424 Disabled Disabled 1 k8s:node-role.kubernetes.io/control-plane ready k8s:node.kubernetes.io/exclude-from-external-load-balancers reserved:host root@server:~# root@server:~# kubectl exec -n kube-system cilium-6vxzs -- cilium-dbg endpoint get 839 [ { "id": 839, "spec": { "label-configuration": {}, "options": { "ConntrackAccounting": "Disabled", "Debug": "Disabled", "DebugLB": "Disabled", "DebugPolicy": "Disabled", "DropNotification": "Enabled", "MonitorAggregationLevel": "Medium", "PolicyAccounting": "Enabled", "PolicyAuditMode": "Disabled", "PolicyVerdictNotification": "Enabled", "SourceIPVerification": "Enabled", "TraceNotification": "Enabled" } }, ... ``` `# Running Connectivity Test` ```shell root@server:~# cilium connectivity test ℹ️ Monitor aggregation detected, will skip some flow validation steps ✨ [kind-kind] Creating namespace cilium-test-1 for connectivity check... ✨ [kind-kind] Deploying echo-same-node service... ✨ [kind-kind] Deploying DNS test server configmap... ✨ [kind-kind] Deploying same-node deployment... ✨ [kind-kind] Deploying client deployment... ✨ [kind-kind] Deploying client2 deployment... ✨ [kind-kind] Deploying client3 deployment... ✨ [kind-kind] Deploying echo-other-node service... ✨ [kind-kind] Deploying other-node deployment... ✨ [host-netns] Deploying kind-kind daemonset... ✨ [host-netns-non-cilium] Deploying kind-kind daemonset... ℹ️ Skipping tests that require a node Without Cilium ✨ [kind-kind] Deploying Ingress resource... ``` _Figure 2: Cilium connectivity troubleshooting decision tree_ Policy Troubleshooting Cilium offers command-line utilities to interact with and troubleshoot network policies. The infrastructure team can simulate the policy decision for a specific source or destination port combination and show exactly which rule is permitting or denying the flow, without sending real traffic. `# Get an effective policy for an endpoint` ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg policy get [] Revision: 1 root@server:~# ``` Log Inspection Logs are the audit trail for everything the agent tried and failed to do. Cilium agent logs are verbose by default; the key is filtering for actionable signals rather than reading every line. `# Get Cilium logs` ```shell root@server:~# kubectl -n kube-system logs -f ds/cilium -c cilium-agent Found 3 pods, using pod/cilium-6th6g time=2026-06-27T14:00:11.756428436Z level=info msg="Memory available for map entries (0.250% of 8322646016B): 20806615B" time=2026-06-27T14:00:11.756524087Z level=info msg="option bpf-ct-global-tcp-max set by dynamic sizing to 131072" time=2026-06-27T14:00:11.756538881Z level=info msg="option bpf-ct-global-any-max set by dynamic sizing to 65536" ... ``` Endpoint regeneration log lines are particularly useful. Every time a pod's policy changes (new NetworkPolicy, label update, pod restart), Cilium regenerates the endpoint's eBPF programs. A regeneration failure means the pod's policy is stale. ##### 3.0 Cluster Network State One of the most dangerous failure modes in Kubernetes networking is the one that looks like nothing. Pods schedule, nodes appear Ready, **_kubectl get pods_** shows green, but traffic silently fails, DNS resolutions time out, or cross-namespace calls drop without a clear error. Silence in Cilium can mean: - A controller is reconciling but silently erroring. Controllers retry on failure and don't surface errors unless you explicitly check controller status. Run **_cilium-dbg status \--verbose_** and look for controllers with a non-zero failure count. - Hubble flows are missing. If Hubble shows no flows for a pod that should be receiving traffic, the eBPF program may not be loaded on that node, or the endpoint hasn't been picked up by the agent. Check the cilium-dbg endpoint list and verify the pod's endpoint exists. - eBPF programs aren't attached. The agent may be running but failing to attach programs to a new interface. This produces no obvious error in kubectl get pods, but traffic will bypass Cilium entirely. Verify with cilium-dbg bpf metrics list. - KVStore lag. If you're using etcd as the KVStore, a lagging or partitioned etcd means node identities and policies are stale. Traffic may still flow based on cached state until the cache expires. ###### Cilium Agent Health Check The Cilium agent runs as a DaemonSet pod. A pod in Running state doesn't guarantee the agent is fully functional; it means the container started. True health requires checking what the agent reports about itself. **Check agent status across all nodes.** ```shell root@server:~# kubectl -n kube-system get pods -l k8s-app=cilium -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES cilium-9p44h 1/1 Running 0 86s 172.18.0.4 kind-worker2 cilium-hlntk 1/1 Running 0 86s 172.18.0.2 kind-worker cilium-jzkj4 1/1 Running 0 86s 172.18.0.3 kind-control-plane root@server:~# ``` Look for OOMKill events, failed readiness probes, and init container failures. Cilium's init container (cilium-init) is responsible for setting up the host network before the main agent starts. Failures here mean the agent never reached a healthy state. **Check the Cilium operator.** ```shell root@server:~# kubectl -n kube-system get pods -l name=cilium-operator NAME READY STATUS RESTARTS AGE cilium-operator-57f4d55695-gvhln 1/1 Running 0 5m19s root@server:~# root@server:~# kubectl -n kube-system logs deployment/cilium-operator --tail=100 time=2026-06-27T15:15:04.847030224Z level=info msg="Start hook executed" module=operator function=*job.groupHooks.Start duration=645ns time=2026-06-27T15:15:04.847041107Z level=info msg="Start hook executed" module=operator function=*job.groupHooks.Start duration=572ns ``` The operator manages cluster-scoped resources, CiliumNode objects, IPAM pools, and CRD reconciliation. An unhealthy operator can leave nodes unable to acquire IP addresses, even when agent pods themselves look fine. ###### Node Readiness A node being Ready from Kubernetes' perspective and a node being fully operational from Cilium's perspective are different things. Kubernetes marks a node ready when its kubelet is healthy; Cilium readiness depends on the eBPF datapath being set up correctly. ```shell root@server:~# kubectl get ciliumnode kind-worker2 -o yaml apiVersion: cilium.io/v2 kind: CiliumNode metadata: creationTimestamp: "2026-06-27T15:15:03Z" generation: 1 labels: beta.kubernetes.io/arch: amd64 beta.kubernetes.io/os: linux kubernetes.io/arch: amd64 kubernetes.io/hostname: kind-worker2 kubernetes.io/os: linux ... ``` The CiliumNode resource represents the node from Cilium's perspective. Its status section contains the IPAM state, including which IP addresses are allocated, which are available, and whether the node has successfully registered with the Cilium operator. A CiliumNode that hasn't been created, or whose spec diverges from the actual node's configuration, is a strong signal of an operator or RBAC problem. **Verifying eBPF programs are loaded.** ```shell root@server:~# kubectl -n kube-system exec cilium-jzkj4 -c cilium-agent -- bpftool prog list | head -n 5 61: cgroup_device tag 3918c82a5f4c0360 loaded_at 2026-06-27T13:19:14+0000 uid 0 xlated 64B jited 45B memlock 4096B 64: cgroup_device tag 3918c82a5f4c0360 loaded_at 2026-06-27T13:19:14+0000 uid 0 root@server:~# ``` ##### 4.0 Pod Connectivity Problems ###### When the Pod Is Not Running A pod that hasn't reached the running state has a networking problem that happens before networking can be verified. Don't reach for Hubble yet; the issue is earlier in the lifecycle. Start with kubectl describe pod. ```shell root@server:~# kubectl describe pod nginx | head -n 5 Name: nginx Namespace: default Priority: 0 Service Account: default Node: kind-worker2/172.18.0.4 root@server:~# ``` In the Events section, confirm the following details: **FailedScheduling**: the pod was never placed on a node. This is a scheduler problem, not a network problem. But if it's failing due to IPAM exhaustion, it will appear here. **NetworkPluginNotReady**: the CNI plugin (Cilium) hasn't signaled readiness to the kubelet yet. The Cilium DaemonSet pod on that node may be crashing or not yet fully initialized. **Failed to create pod sandbox**: the container runtime couldn't set up the network namespace. This usually means the CNI binary isn't present at /opt/cni/bin/ or the CNI config at /etc/cni/net.d/ is malformed. ###### When the Pod Is Running but Unreachable A running pod that doesn't respond to traffic is one of the most common Cilium troubleshooting scenarios. The most likely causes are: NetworkPolicy blocking the traffic, the pod's eBPF endpoint not being regenerated after a policy change, or the pod's IP not being correctly advertised. _First: Confirm the pod has an endpoint._ ```shell root@server:~# kubectl -n kube-system exec cilium-vnwrl -- cilium-dbg endpoint list | grep 10.244.2.57 2043 Disabled Disabled 64004 k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default 10.244.2.57 ready root@server:~# ``` The endpoint should be in a ready state. If it's not-ready, regenerating, or disconnected, the datapath isn't set up for that pod yet. Give it 10 \- 15 seconds; if it doesn't transition, check agent logs for regeneration errors. ###### Second: Check Hubble for dropped flows ```shell root@server:~# hubble observe --to-pod default/nginx --verdict DROPPED --follow ``` Then attempt to connect to the pod from a source. If drops appear in Hubble, the output will include the drop reason, typically **_Policy denied_** or **_CT: missing entry_**. A Policy denied drop means a NetworkPolicy is blocking the traffic. An **_CT: missing entry_** drop means the connection tracking table doesn't have a return-path entry, which suggests asymmetric routing. _Third: Trace the policy._ ```shell root@server:~# kubectl exec -n kube-system ds/cilium -c cilium-agent -- cilium endpoint list ENDPOINT POLICY (ingress) POLICY (egress) IDENTITY LABELS (source:key[=value]) IPv6 IPv4 STATUS ENFORCEMENT ENFORCEMENT 381 Disabled Disabled 54455 k8s:app=client 10.244.1.83 ready k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default k8s:io.cilium.k8s.policy.cluster=kind-kind k8s:io.cilium.k8s.policy.serviceaccount=default k8s:io.kubernetes.pod.namespace=default .... root@server:~# kubectl exec -n kube-system ds/cilium -c cilium-agent -- cilium policy get 1994 [] Revision: 1 root@server:~# ``` The trace output shows you the exact policy decision. If no ingress rule matches, Cilium will tell you. This is far faster than reading NetworkPolicy YAML and mentally evaluating label selectors. _Fourth: Verify Service routing_ If you're hitting the pod through a Service, it’s important to check the BPF service map. ```shell root@server:~# CILIUM_AGENT_POD=$(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[0].metadata.name}') kubectl -n kube-system exec $CILIUM_AGENT_POD -- cilium-dbg bpf lb list | grep 10.96.194.145 10.96.194.145:80/TCP (0) 0.0.0.0:0 (20) (0) [ClusterIP, non-routable] 10.96.194.145:0/ANY (0) 0.0.0.0:0 (0) (0) [ClusterIP, non-routable] root@server:~# ``` A Service that has no backend entries in the BPF load balancer table will silently drop traffic even if the pod itself is healthy. ###### Cross-Node Pod Connectivity Cross-node failures are network-topology failures. When a pod on **Node A** can't reach a pod on **Node B**, the problem is usually in one of three layers: the underlay (physical or cloud routing), the Cilium tunnel or native routing configuration, or the eBPF programs on the receiving node. ```shell root@server:~# kubectl -n kube-system exec ds/cilium -c cilium-agent -- cilium-dbg status --verbose | grep -E "Routing|Tunnel" KubeProxyReplacement: True [eth0 172.18.0.2 fc00:f853:ccd:e793::2 fe80::b4cd:bdff:fe8f:95db (Direct Routing)] Routing: Network: Tunnel [vxlan] Host: Legacy Devices: eth0 172.18.0.2 fc00:f853:ccd:e793::2 fe80::b4cd:bdff:fe8f:95db (Direct Routing) root@server:~# ``` Cilium supports two modes: - **VXLAN / Geneve (tunnel mode);** pod traffic is encapsulated between nodes. Node-to-Node UDP connectivity on port 8472 (VXLAN) or 6081 (Geneve) must be allowed. - **Native routing:** pod CIDR routes must be present in the underlay (via BGP, cloud routing tables, or static routes). No encapsulation means any routing gap in the underlay creates a black hole. A missing route means the pod CIDR for the destination node hasn't been advertised. In BGP mode, check that the Cilium BGP control plane has established a session and is advertising prefixes: ```shell kubectl -n kube-system exec -- cilium-dbg bgp peers ``` ###### Running Connectivity Tests with Cilium Rather than constructing test traffic manually, Cilium includes a built-in connectivity test suite that validates the entire network stack end-to-end. It's the fastest way to confirm that a cluster's networking is fully operational after installation, an upgrade, or a configuration change. _Run the full connectivity test._ ```shell cilium connectivity test ``` This deploys a set of test pods across your cluster and runs a structured battery of tests, including: - Pod-to-pod connectivity within the same node - Pod-to-pod connectivity across nodes - Pod-to-Service connectivity - Pod-to-external connectivity (egress) - NetworkPolicy enforcement (allow and deny cases) - DNS resolution - L7 policy enforcement (if Hubble and Envoy are enabled) _Run a subset of tests._ ```shell # Only pod-to-pod tests cilium connectivity test --test pod-to-pod # Exclude tests requiring external access cilium connectivity test --test '!external-1.1.1.1' ``` The test name tells you the scenario. The flow line tells you the exact src/dst. From here, use **_hubble observe \--verdict DROPPED_** filtered to those pods to identify the drop cause. _Use connectivity tests as a regression gate._ After any change to NetworkPolicy, Cilium configuration, or cluster topology, run the connectivity tests before marking the change complete. A clean pass means the full network stack datapath, policy engine, identity system, DNS, and Service load balancing are working as expected across all nodes. ##### 5.0 Service and Load Balancing Connectivity Problems Service failures in Kubernetes are deceptive. The pod may be healthy, the deployment may show all replicas ready, and yet traffic never arrives. With Cilium’s kube-proxy replacement, service load balancing runs entirely in the eBPF datapath, no iptables rules, no kube-proxy chains. That means the debugging path is different and faster than with traditional CNIs. [Read More About Service Load Balancing](https://cilium.io/blog/2026/04/25/understanding-kubernetes-load-balancing/) ###### Is the Service Selecting Any Pod? The first question when a Service doesn't work is whether it has any backends at all. A Service with no matching pods will accept connections and immediately drop them silently, from the caller's perspective. ```shell root@server:~# kubectl get endpoints nginx-service Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice NAME ENDPOINTS AGE nginx-service 10.244.1.112:80 17s root@server:~# ``` If the **_ENDPOINTS_** column is empty or shows **_\_**, the selector isn't matching any pods. Cross-check the Service's **_spec. selector_** against actual pod labels. ```shell root@server:~# kubectl get svc nginx-service -o jsonpath='{.spec.selector}' {"run":"nginx"} root@server:~# root@server:~# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx 1/1 Running 0 2m19s run=nginx root@server:~# ``` A single mismatched label, a typo, a version suffix, or a missing key is enough to produce zero backends. The Service exists, the pods exist, but they never find each other. Also, verify pods are actually running and passing readiness probes. A pod in Running but failing its readiness check will be excluded from EndpointSlices automatically. ```shell root@server:~# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx 1/1 Running 0 2m19s run=nginx ``` ###### ClusterIP Not Responding You can validate the correct datapath state by running cilium-dbg bpf lb list to inspect the contents of the eBPF load balancing maps. [Read More About Cilium Troubleshooting](https://docs.cilium.io/en/stable/operations/troubleshooting/) ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf lb list | grep 10.96.69.57 10.96.69.57:80/TCP (1) 10.244.1.112:80/TCP (20) (1) 10.96.69.57:80/TCP (0) 0.0.0.0:0 (20) (0) [ClusterIP, non-routable] 10.96.69.57:0/ANY (0) 0.0.0.0:0 (0) (0) [ClusterIP, non-routable] root@server:~# ``` If the ClusterIP appears in the table with no backends listed, the endpoint hasn't been programmed into the BPF map. Check the Cilium operator logs and verify EndpointSlices are in sync. If the ClusterIP doesn't appear at all, the Service hasn't been picked up by Cilium's service reconciler. Run **_cilium-dbg debuginfo_** and look for the section **_k8s-service-cache_**. In that section, you will find the contents of the service correlation cache. This cache is what Cilium uses to reconcile Kubernetes Services into BPF map entries. A stale or missing entry here explains why the datapath isn't programmed correctly. ###### NodePort Not Reachable Externally With the help of the cilium-dbg service list command, you can validate that Cilium's eBPF kube-proxy replacement created the NodePort service. Services with the NodePort will have entries for each device on every node. [Read More About Kube Proxy Replacement](https://docs.cilium.io/en/stable/network/kubernetes/kubeproxy-free/) ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg service list | grep NodePort 1 0.0.0.0:31234/TCP NodePort 1 => 10.244.2.211:4245/TCP (active) 4 0.0.0.0:31235/TCP NodePort 1 => 10.244.2.123:8081/TCP (active) 12 0.0.0.0:30452/TCP NodePort 14 0.0.0.0:32142/TCP NodePort root@server:~# ``` If NodePort entries are missing for a node interface, the \--devices configuration may not include that interface. Check the Cilium ConfigMap: ```shell root@server:~# kubectl -n kube-system get cm cilium-config -o jsonpath='{.data.devices}' eth0 root@server:~# ``` The device list must include the interface on which external traffic arrives. If your nodes have multiple network interfaces (common in cloud environments), an interface not listed here will not have NodePort BPF programs attached, and external traffic arriving there will be ignored. For external traffic specifically, it’s important to verify that your cloud provider’s security groups or firewall rules allow the NodePort default range (30000-32767 TCP/UDP) from external sources. If the container runtime in your cluster is running in cgroup namespace mode, Cilium's kube-proxy replacement-based load balancing may not be effective, leading to connectivity issues. Verify cgroup attachment. ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- bpftool cgroup tree /run/cilium/cgroupv2/ CgroupPath ID AttachType AttachFlags Name /run/cilium/cgroupv2 734 cgroup_inet_sock_release multi cil_sock_release 731 cgroup_inet4_post_bind multi cil_sock4_post_bind 735 cgroup_inet6_post_bind multi cil_sock6_post_bind 745 cgroup_inet4_connect multi cil_sock4_connect ... ``` ###### Debugging EndpointSlices Cilium consumes EndpointSlices directly; it doesn't rely on the older Endpoints API. If EndpointSlices are missing, stale, or out of sync, the BPF load balancing table will not reflect the current backend state. ```shell # List EndpointSlices for a service root@server:~# kubectl get endpointslices -l kubernetes.io/service-name=nginx-service NAME ADDRESSTYPE PORTS ENDPOINTS AGE nginx-service-krzb2 IPv4 80 10.244.1.112 15m root@server:~# # Inspect a specific slice root@server:~# kubectl describe endpointslice nginx-service-krzb2 Name: nginx-service-krzb2 Namespace: default Labels: endpointslice.kubernetes.io/managed-by=endpointslice-controller.k8s.io kubernetes.io/service-name=nginx-service run=nginx Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2026-07-19T12:25:21Z AddressType: IPv4 Ports: Name Port Protocol ---- ---- -------- 80 TCP Endpoints: - Addresses: 10.244.1.112 ``` The following details must be present in the output - addressType: should be IPv4 or IPv6 for dual stack. - conditions. ready: only ready endpoints will be picked up. - targetRef: should point to an existing pod in the expected namespace. ```shell root@server:~# kubectl get endpointslices -l kubernetes.io/service-name=nginx-service -o jsonpath='{range .items[*]}{"addressType: "}{.addressType}{"\n"}{range .endpoints[*]}{" - targetRef: "}{.targetRef.kind}{"/"}{.targetRef.name}{"\n ready: "}{.conditions.ready}{"\n"}{end}{end}' addressType: IPv4 - targetRef: Pod/nginx ready: true root@server:~# ``` ###### The Load Balancer Service Is Stuck in Pending A LoadBalancer Service showing _\_ in the EXTERNAL-IP column means no external IP has been assigned. The cause depends on your environment. On bare metal or on-premise clusters using Cilium LB IPAM: The ExternalIP field having a value of _\_ means no LB IPs have been assigned. When LB IPAM is unable to allocate or assign IPs for the service, it will update the service conditions in the status. To check for service status conditions: ```shell root@server:~# kubectl describe svc nginx-service Name: nginx-service Namespace: default Labels: run=nginx Annotations: Selector: run=nginx Type: ClusterIP IP Family Policy: SingleStack IP Families: IPv4 IP: 10.96.69.57 IPs: 10.96.69.57 Port: 80/TCP TargetPort: 80/TCP Endpoints: 10.244.1.112:80 Session Affinity: None Internal Traffic Policy: Cluster Events: root@server:~# ``` A reason for no_pool means no **_CiliumLoadBalancerIPPool_** has been created, or the pool's **_serviceSelector_** doesn't match this service. LB IPAM is always enabled but dormant. The controller is only activated when the first IP Pool is added to the cluster. Create a pool if none exists [Read More About LB IPAM](https://docs.cilium.io/en/stable/network/lb-ipam/) ###### Session Affinity Session affinity ensures that repeated connections from the same client are routed to the same backend pod. Without it, stateful applications or anything maintaining in-memory session state will behave erratically when connections are distributed across replicas. Cilium implements session affinity natively in eBPF. The source for the affinity depends on the origin of a request. If a request is sent from outside the cluster to the service, the request's source IP address is used for determining the endpoint affinity. If a request is sent from inside the cluster, the client's network namespace cookie is used as the source when socket-LB is in use. This allows affinity to be implemented at the socket layer, where the endpoint selection happens before a network packet has been built. [Read More About Cilium Session Affinity](https://docs.cilium.io/en/stable/network/kubernetes/kubeproxy-free/#session-affinity) ##### 6.0 DNS Resolution Failures DNS is a common cause for outages and incidents in Kubernetes clusters. When errors occur during DNS resolution, they are typically referred to as DNS resolution errors or DNS issues. Errors during connection to the returned IP are generally referred to as network connectivity issues. Keeping that distinction sharp saves significant debugging time; the symptoms can look identical at the application layer. ###### Running DNS Resolution Tests inside Pods When DNS issues occur, they often go unnoticed until significant damage has been done. The first ideal step is to check whether nslookup is working properly. ```shell root@server:~# kubectl run dnsutils --image=gcr.io/kubernetes-e2e-test-images/dnsutils:1.3 --command -- sleep 3600 pod/dnsutils created root@server:~# kubectl exec -i -t dnsutils -- nslookup kubernetes.default Server: 10.96.0.10 Address: 10.96.0.10#53 Name: kubernetes.default.svc.cluster.local Address: 10.96.0.1 root@server:~# ``` The following are common issues associated with DNS in Kubernetes 1. Delayed response: the DNS server is slow to respond due to congestion or server overload. 2. Incorrect DNS resolutions: usually because of out-of-date or incomplete records. 3. DNS records conflict: multiple pods or services use the same name or IP. 4. DNS lookup failures: When a lookup fails, it is most often due to the server being unreachable. 5. NXDOMAIN errors: the server can't find a request domain within its records. 6. External domain failures: Kubernetes DNS can’t resolve the external domain name, likely due to failure to connect to the external DNS server. _Figure3:DNS resolution queries_ ###### Checking DNS Logs Logs can be checked using the following command: ```shell kubectl logs --namespace=kube-system -l k8s-app=kube-dns ``` Warnings or error messages in the logs may help you hone in on the source of your DNS problem, especially if the root of the issue lies with kube-dns itself as opposed to the network. ###### Check kube-dns Resource Utilization Checking the CPU utilization of the kube-DNS service can help you determine whether the server is simply overloaded. To view real-time CPU metrics, run: ```shell root@server:~# kubectl logs --namespace=kube-system -l k8s-app=kube-dns maxprocs: Leaving GOMAXPROCS=8: CPU quota undefined .:53 [INFO] plugin/reload: Running configuration SHA512 = 61c4e97fd46a540ac8dda919cc898bd4e91207731b7b08b141e56fbd76fd591d82a4524df658474b8e3d867076fc7ba04e95992926333c1bcfaa75c46969808c CoreDNS-1.12.0 linux/amd64, go1.23.3, 51e11f1 maxprocs: Leaving GOMAXPROCS=8: CPU quota undefined .:53 [INFO] plugin/reload: Running configuration SHA512 = 61c4e97fd46a540ac8dda919cc898bd4e91207731b7b08b141e56fbd76fd591d82a4524df658474b8e3d867076fc7ba04e95992926333c1bcfaa75c46969808c CoreDNS-1.12.0 linux/amd64, go1.23.3, 51e11f1 root@server:~# ``` ##### 7.0 Network Policy Drops Network policy changes are among the most frequent operations in a Kubernetes cluster. They are also among the most delicate, as even a small mistake can lead to widespread traffic disruption. This section walks through several methods to make policy management safer, especially in Day 2 operations or brownfield deployments where clusters already run critical workloads. It shows how to test and validate changes before enforcing them, helping teams adopt a more reliable approach to policy rollout. An endpoint can be put into default deny mode at ingress or egress if a rule selects the endpoint and contains the respective rule section. Any rule selecting the endpoint will have this effect. Understanding that default-deny is triggered implicitly, not by a dedicated deny rule, is the foundation of everything that follows. Cilium network policies build upon Kubernetes NetworkPolicy, extending it with deeper visibility and more flexible rule types. Policies are used to allow or deny traffic based on defined rules, which can apply to ingress, egress, or both. These rules are evaluated at the datapath level, meaning enforcement takes place directly in the kernel through eBPF. [Read More About Safely Managing Cilium Network Policies](https://www.cncf.io/blog/2025/11/06/safely-managing-cilium-network-policies-in-kubernetes-testing-and-simulation-techniques/) ###### Identifying Policy-Denied Drops The fastest way to identify a policy drop is through Hubble. Unlike iptables-based CNIs, where you parse iptables \-L output and mentally trace rule ordering, Cilium surfaces every policy decision as an observable flow event, including the direction and reason for each drop. _Watch for drops in real time:_ ```shell # All policy-denied drops in the cluster root@server:~# hubble observe --verdict DROPPED --follow # Filter to a specific destination hubble observe --verdict DROPPED \ --to-pod default/backend --follow # Filter by source pod root@server:~# hubble observe --verdict DROPPED \ --to-pod default/nginx --follow # Show only policy-verdict events (broader than just drops) root@server:~# hubble observe -t policy-verdict --follow ``` Using cilium-dbg monitor for low-level drop events: When Hubble is not available, or you need lower-level detail: ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg monitor --type drop Listening for events on 8 CPUs with 64x4096 of shared memory Press Ctrl-C to quit ``` ###### Policy Tracing Policy tracing simulates the policy decision for a specific traffic flow without sending any real traffic. It's the most direct way to answer the question: "Should this traffic be allowed right now, given the policies in effect?" ```shell # Trace by pod name kubectl -n kube-system exec ds/cilium -- \ cilium-dbg policy trace \ --src-k8s-pod default/frontend \ --dst-k8s-pod default/backend \ --dport 8080/TCP # Trace by label selectors kubectl -n kube-system exec ds/cilium -- \ cilium-dbg policy trace \ --src-identity k8s:app=frontend,k8s:io.kubernetes.pod.namespace=default \ --dst-identity k8s:app=backend,k8s:io.kubernetes.pod.namespace=default \ --dport 8080/TCP ``` ###### Rendering the Effective Policy The policy in effect for an endpoint is not simply the sum of kubectl get networkpolicy output. Cilium computes a realized policy per endpoint by evaluating all matching rules from Kubernetes NetworkPolicies, CiliumNetworkPolicies, and CiliumClusterwideNetworkPolicies and merging them into a single enforcement state. The realized policy is what actually runs in the datapath. To determine which policy rules are currently in effect for an endpoint, the data from cilium-dbg endpoint list and cilium-dbg endpoint get can be paired with the data from cilium-dbg policy get. cilium-dbg endpoint get will list the labels of each rule that applies to an endpoint. Step 1: Find the endpoint ID ```shell root@server:~# # 1. Find the Cilium pod handling your nginx pod TARGET_NODE=$(kubectl get pod nginx -o jsonpath='{.spec.nodeName}') CILIUM_POD=$(kubectl -n kube-system get pods -l k8s-app=cilium --field-selector spec.nodeName=$TARGET_NODE -o jsonpath='{.items[0].metadata.name}') # 2. Extract the Endpoint ID EP_ID=$(kubectl -n kube-system exec $CILIUM_POD -- cilium-dbg endpoint list | grep nginx | awk '{print $1}') # 3. Verify it found the ID echo "Your Nginx Endpoint ID is: $EP_ID" Your Nginx Endpoint ID is: k8s:run=nginx root@server:~# ``` Note the endpoint ID and the security identity from the output. Step 2: Check policy enforcement state ```shell root@server:~# kubectl -n kube-system exec ds/cilium -- cilium-dbg endpoint list ENDPOINT POLICY (ingress) POLICY (egress) IDENTITY LABELS (source:key[=value]) IPv6 IPv4 STATUS ENFORCEMENT ENFORCEMENT 98 Disabled Disabled 8 reserved:ingress 10.244.0.12 ready 1050 Disabled Disabled 1 k8s:node-role.kubernetes.io/control-plane ready k8s:node.kubernetes.io/exclude-from-external-load-balancers reserved:host 2314 Disabled Disabled 4 reserved:health 10.244.0.227 ready root@server:~# ``` The POLICY (ingress) and POLICY (egress) columns show Enabled or Disabled for each endpoint. An endpoint with 'Disabled' on both means no policy is selecting it; it's in default-allow mode. The moment a policy is selected, the selected direction becomes the enforced default-deny. If you see Disabled when you expect Enabled, check whether the policy's endpointSelector actually matches the pod's labels. ###### Policymap Pressure Each Cilium-managed endpoint has its own BPF policy map, a fixed-size hash table in kernel memory that holds all allowed traffic rules for that endpoint. The default maximum number of entries in the endpoint policy map is 16,384 per endpoint, configured via \--bpf-policy-map-max. In large clusters with complex policies, especially those using many CIDR rules, fine-grained label selectors, or toFQDNs, this map can fill up. When it does, policy entries can't be added, and traffic that should be allowed gets dropped. Common Pitfalls 1\. Implicit default-deny on first policy application The most common surprise in Cilium policy management: the moment you apply the first NetworkPolicy or CiliumNetworkPolicy that selects a pod, all traffic not explicitly permitted by that policy is denied. Applying the first network policy triggers the default-deny behavior, which may unintentionally block traffic not yet accounted for in your policy definitions. The fix is to apply audit mode first, observe all traffic, then write policies that cover every observed flow before enforcing. 2\. Forgetting to allow egress DNS Any policy restricting egress must explicitly allow DNS on port 53\. Without it, the pod loses service discovery. This is the single most common policy-related incident in production Cilium clusters. Always include this egress rule in any policy applied to a namespace: 3\. Policy is per-direction, not per-endpoint A policy that allows egress from Pod A to Pod B does not automatically allow ingress at Pod B. Note that while an egress rule may allow traffic from an endpoint, the receivers of that egress traffic may have ingress rules that deny it. Policy must be configured on both sides, the sender and the receiver. If both pods have policies applied, you need matching egress rules on the sender and ingress rules on the receiver. 4\. Label selector scope and namespace boundaries Network policies imported directly with the Cilium API apply to all namespaces unless a namespace selector is specified. A CiliumClusterwideNetworkPolicy without a namespace selector applies globally. A regular CiliumNetworkPolicy scopes to its own namespace. Getting this wrong produces either overly permissive or unexpectedly restrictive behavior. Always check the namespace context of your policy resource type. 5\. toServices and toPorts cannot be combined You cannot create an egress rule that simultaneously specifies a service and restricts ports. You must choose between defining traffic by service identity or by port. Attempting to combine toServices with toPorts in the same egress rule produces a policy that silently ignores one of the two constraints, leading to unexpected behavior. 6\. The cluster entity does not span ClusterMesh A common misunderstanding when configuring entity-based L3 policies is that the cluster entity includes only endpoints in a local cluster and does not include other clusters in a ClusterMesh. If you're running ClusterMesh and your toEntities: cluster rule isn't allowing cross-cluster traffic, you need explicit selectors for the remote cluster's identities. 7\. toFQDNs rules without a DNS inspection rule As covered in section 6.0, a toFQDNs rule does nothing without a companion L7 DNS rule that tells Cilium to intercept DNS responses. The traffic will be denied because Cilium never learned the IP mapping for the FQDN. 8\. Policy revision mismatch after rollout After applying a new policy, verify that the agent has picked it up on every node. [Read More About Cilium Network Policy Troubleshooting](https://docs.cilium.io/en/stable/security/policy/troubleshooting/) ##### 8.0 Summary Reactive troubleshooting, diagnosing a problem after it's already impacting production, is expensive. The gap between a network misconfiguration and its detection is often measured in minutes or hours, not seconds. The goal of this section is to close that gap by building a detection layer that surfaces issues before users notice them. ###### Troubleshooting Hierarchy Every Cilium networking problem falls into one of four layers. Working top-down through this order eliminates entire categories of causes quickly | Layer | Check first | |:----------------- |:--------------------------------------------- | | Agent health | cilium status all subsystems OK? | | Endpoint state | cilium-dbg endpoint list all endpoints ready? | | Traffic visibility | hubble observe \--verdict DROPPED any drops? | | Datapath state | cilium-dbg bpf \* maps reflect expected state? | It is also important to utilise Prometheus metrics for alerting as an early warning on every major failure. #### How k0rdent and Cilium Turn Kubernetes Sprawl into a Platform URL: https://cilium.io/blog/2026/07/08/how-k0rdent-and-cilium-turn-kubernetes-sprawl-into-a-platform Date: 2026-07-08 Categories: Technology If you have spent time running Kubernetes in the real world, you know the catch: standing up one cluster is the easy part. The hard part starts when one cluster becomes ten, then a hundred, spread across cloud providers, bare metal, and on-prem environments. That is where k0rdent and Cilium fit together very well. **k0rdent** gives platform teams a single control plane to provision, template, and manage fleets of clusters declaratively and consistently. **Cilium**, built on eBPF, provides the networking, identity-based security, and observability those clusters need for production. Together, they help turn cluster sprawl into a repeatable platform pattern. Instead of bolting on networking, policy, and visibility one cluster at a time, teams can make them part of the cluster definition from the start. In this post, we will look at why platform teams pair k0rdent and Cilium, then walk through a hands-on example using a k0rdent `ClusterDeployment` with Cilium as the CNI. Let's dig in. ##### Built Once, But is it Consistent Everywhere? If you run a platform team, you're already juggling a growing fleet, workloads that need management, and a list of things that must stay consistent across every cluster. k0rdent and Cilium work well together because they address both sides of that problem: how clusters get built and how they behave once they are running. The drift usually shows up in small but painful ways. One cluster has Cilium configured differently, another is missing a policy that exists everywhere else, and another has incomplete visibility when a service-to-service call starts failing. Those differences are easy to create by hand and hard to debug at 2 a.m. k0rdent's answer is to treat the cluster as a template, and Cilium fits into that model directly. Cilium is available in the k0rdent catalog as a validated service template, meaning it can be attached to a cluster as a reusable add-on. Define it once, and every cluster k0rdent provisions can come up with the same Cilium foundation: CNI, policies, and observability included from the start. Visibility is also a factor. "Service A can't reach service B" is easy or hard depending entirely on what you can see. Cilium ships with Hubble, which gives you L3 through L7 flow visibility without sidecars by leveraging eBPF, and k0rdent helps make that visibility part of the standard cluster template rather than something enabled one cluster at a time. When something breaks, you can see where the traffic was dropped and why, and on which cluster it happened. Put it together and the practical result is that the platform team can run a much larger fleet, because the clusters are built the same way and behave predictably. ##### From Template to Running Cluster With the why out of the way, let's see what this actually looks like in practice. In this section we'll walk through deploying a k0rdent `ClusterDeployment` that uses Cilium as its CNI, so that the cluster comes up already networked the way we want rather than waiting for someone to wire it in afterward. A quick note on assumptions before we start. This walkthrough assumes you already have a k0rdent Management cluster up and running. If you don't, the [official quickstart](https://docs.k0rdent.io/latest/quickstarts/quickstart-1-mgmt-node-and-cluster/#install-a-kubernetes-cluster-as-the-management-cluster) walks you through setting one up. We'll also be deploying onto bare metal hosts, which means we'll be using the `remote-cluster` `ClusterTemplate` to bring those existing machines under management. A `ClusterTemplate` is k0rdent's reusable definition for how a cluster should be created. The `remote-cluster` template is useful when the infrastructure already exists, as it lets k0rdent connect to those machines over SSH and bootstrap them into a managed child cluster.. ###### Deploying the Remote Cluster Template For this example we're working with three Linux machines on the same network. One is the k0rdent node running our Management cluster. The other two, `worker1` and `worker2`, are the bare metal hosts that will become our child cluster. Because k0rdent provisions bare metal remote machines over SSH, the first thing we need is root SSH access to both workers. Let's generate a dedicated key pair for this so we're not reusing anything else, then copy it out to each host. ```shell ssh-keygen -f ~/.ssh/idk0r ssh-copy-id -i ~/.ssh/idk0r.pub root@worker1 ssh-copy-id -i ~/.ssh/idk0r.pub root@worker2 ``` Next, k0rdent needs a credential object so it knows how to authenticate against those workers. We install the `remote-credential` chart, then base64-encode the private key we just created and patch it into the secret k0rdent expects. ```shell helm install remote-credential oci://ghcr.io/k0rdent/catalog/charts/remote-credential -n kcm-system REMOTE_SSH_KEY_B64=$(cat ~/.ssh/idk0r | openssl base64 -A) kubectl patch secret remote-ssh-key -n kcm-system -p='{"data":{"value":"'$REMOTE_SSH_KEY_B64'"}}' ``` Here's where the pairing actually comes together. We install Cilium into k0rdent as a service template, which is what makes it something we can reference from a `ClusterDeployment` later. ```shell helm upgrade --install cilium oci://ghcr.io/k0rdent/catalog/charts/kgst \ --set "chart=cilium:1.19.0" -n kcm-system ``` Once it's installed, a quick check confirms the template is registered and valid. ```shell kubectl get servicetemplates -A | grep cilium ``` Now, we set up the cluster we want. We can do this with a `ClusterDeployment` that references the `remote-cluster` template for the bare metal hosts and the `cilium` service template for the CNI. Create a file called `remote-cld-cilium.yaml`: ``` apiVersion: k0rdent.mirantis.com/v1beta1 kind: ClusterDeployment metadata: name: remote namespace: kcm-system labels: type: remote spec: template: remote-cluster-1-0-22 credential: remote-credential propagateCredentials: false config: controlPlaneNumber: 1 k0smotron: service: type: NodePort machines: - name: worker1 address: 192.168.1.5 user: root port: 22 - name: worker2 address: 192.168.1.6 user: root port: 22 k0s: version: v1.35.3+k0s.0 network: # prepare for cilium calico: null provider: custom kubeProxy: disabled: true serviceSpec: services: - template: cilium-1-19-0 name: cilium namespace: kube-system values: | cilium: cluster: name: cilium hubble: tls: enabled: false auto: method: helm certManagerIssuerRef: {} ui: enabled: false ingress: enabled: false relay: enabled: false ipv4: enabled: true ipv6: enabled: false envoy: enabled: false egressGateway: enabled: false kubeProxyReplacement: "true" serviceAccounts: cilium: name: cilium operator: name: cilium-operator localRedirectPolicy: true ipam: mode: cluster-pool operator: clusterPoolIPv4PodCIDRList: - "192.168.224.0/20" - "192.168.210.0/20" clusterPoolIPv6PodCIDRList: - "fd00::/104" tunnelProtocol: geneve k8sServiceHost: "{{ .Cluster.spec.controlPlaneEndpoint.host }}" k8sServicePort: "{{ .Cluster.spec.controlPlaneEndpoint.port }}" ``` A couple of things worth calling out. We're disabling `kubeProxy` and setting `calico: null` because Cilium is going to take over that job with its eBPF datapath, and `kubeProxyReplacement` is set to `"true"` to make that explicit. Now, we can apply the `remote-cld-cilium.yaml` file, creating the cluster. ```shell kubectl apply -f remote-cld-cilium.yaml ``` From there, k0rdent takes over, reaching out to the workers over SSH, bootstraps k0s, and rolls out Cilium as the CNI as part of the same process. We can get the status of the `ClusterDeployment` with: ```shell kubectl get cld -A ``` Once you see the status of "READY" being "True", the cluster is ready to go\! ```shell NAMESPACE NAME READY SERVICES TEMPLATE MESSAGES AGE kcm-system remote True 1/1 remote-cluster-1-0-22 Object is ready 15m ``` ###### Running a Cilium Test Once the `ClusterDeployment` reports ready, we can pull the child cluster's kubeconfig straight from the secret k0rdent created and have a look around. Extract the secret, decode it, and save it to a file: ```shell kubectl get secret remote-kubeconfig -n kcm-system -o=jsonpath={.data.value} | base64 -d > kcfg_remote.yaml ``` Verify Cilium is up and running: ```shell kubectl --kubeconfig kcfg_remote.yaml get pods -A -l app.kubernetes.io/part-of=cilium ``` The output should show the Cilium pods running in the `kube-system` namespace: ```shell NAMESPACE NAME READY STATUS RESTARTS AGE kube-system cilium-mgw7b 1/1 Running 0 4h42m kube-system cilium-operator-758fc644d7-jjq8h 1/1 Running 0 4h43m kube-system cilium-operator-758fc644d7-nhdr4 1/1 Running 0 4h43m kube-system cilium-rxcfw 1/1 Running 0 4h38m ``` Now that we verified that Cilium is running, we can do a quick `CiliumNetworkPolicy` test. First, we'll deploy a small sample workload: a `webapp` that serves both a `/public` and a `/private` endpoint, along with a `client` pod we can use to reach it. ```shell kubectl --kubeconfig kcfg_remote.yaml \ apply -f \ https://gist.githubusercontent.com/christianh814/0d4c0d9529fe630775fa3f54f1725f80/raw/8e89d8d5d89f014e3d7899e32b4d71fe6498e93d/sample-workload.yaml ``` With no policy in place, the `client` pod can reach both endpoints. Both of these calls return data: ```shell $ kubectl --kubeconfig kcfg_remote.yaml exec -it client-pod -- curl http://webapp/public [ { "id": 1, "body": "public information" } ] $ kubectl --kubeconfig kcfg_remote.yaml exec -it client-pod -- curl http://webapp/private [ { "id": 1, "body": "secret information" } ] ``` That `/private` endpoint handing back "secret information" to anyone who asks is exactly the kind of thing we'd want to lock down. So let's write a `CiliumNetworkPolicy` that only allows the `client` to issue an HTTP `GET` against `/public`, and nothing else. ```shell kubectl --kubeconfig kcfg_remote.yaml apply -f -<