你好,我是qmwneb946,一位热衷于探索技术深度的博主。在当今这个瞬息万变的数字化时代,云原生技术,尤其是以Kubernetes为核心的容器编排,已经彻底颠覆了我们构建、部署和运行应用程序的方式。微服务架构的兴起,让应用变得更加敏捷、可伸缩,但也随之带来了前所未有的网络挑战。
传统网络模型在面对成千上万个瞬时变化的容器实例时显得力不从心。我们需要一种全新的网络范式,它不仅能提供高性能、高可伸缩性,还要具备强大的安全性、可观测性和L7应用层可见性。正是在这样的背景下,eBPF(extended Berkeley Packet Filter)技术异军突起,并催生了像Cilium这样划时代的云原生网络解决方案。
Cilium不仅仅是一个CNI(Container Network Interface)插件,它是一个基于eBPF构建的全面网络和安全平台,旨在解决云原生环境中微服务间通信的所有复杂性。它承诺提供线速的性能、细粒度的安全控制以及无与伦比的可见性,而这一切都得益于eBPF在Linux内核中的魔法。
在这篇深度文章中,我将带你一同踏上这段探索之旅。我们将首先理解云原生环境下的网络痛点,然后深入剖析eBPF这一强大技术的奥秘,最后聚焦于Cilium,详细解读它的核心功能、工作原理及其在实际应用中的巨大潜力。无论你是运维工程师、开发人员还是架构师,我相信这篇文章都将为你揭示云原生网络未来的方向。
云原生时代的网络挑战
随着云计算和容器化技术的普及,应用程序的架构正从传统的单体应用向分布式微服务转型。Kubernetes作为容器编排的事实标准,使得应用程序的部署、扩展和管理变得前所未有的便捷。然而,这种变革也给网络基础设施带来了巨大的压力和挑战。
传统网络模型的局限性
在传统的IT基础设施中,网络通常是静态且基于IP地址和端口号进行配置的。防火墙规则、负载均衡策略都是预先定义的,并且变动频率较低。但在云原生环境中,情况则大相径庭:
- 动态性与瞬时性: 容器实例的生命周期极短,Pod可能在几秒内创建、销毁、迁移。它们的IP地址也是动态分配的。传统的基于IP地址的防火墙规则和ACL(Access Control List)难以适应这种高速变化。
- 高密度: 单台宿主机上可能运行数十甚至上百个Pod。这意味着需要处理大量的网络连接和流量,对网络性能提出高要求。
- 扁平化网络: Kubernetes的Pod之间默认是扁平的网络,任何Pod都可以与集群中的任何其他Pod通信。这虽然简化了网络配置,但也带来了安全挑战,例如“零信任”原则的实施变得复杂。
- 缺乏应用层可见性: 传统的网络工具主要关注L3/L4(IP、TCP/UDP)层面的流量。但在微服务架构中,L7(HTTP、gRPC、Kafka等)应用层协议的可见性对于故障排查、性能优化和安全策略(例如API级别的授权)至关重要。
- 运维复杂性: 随着微服务数量的爆炸式增长,手动管理网络策略、排查网络故障变得异常复杂,极大地增加了运维负担。
Kubernetes网络模型概览及其痛点
Kubernetes通过CNI(Container Network Interface)规范抽象了底层网络,允许不同的网络插件集成到集群中。典型的Kubernetes网络模型包括:
- Pod-to-Pod通信: 每个Pod拥有独立的IP地址,Pod之间的通信可以直接进行,无需进行NAT转换。
- Service: Kubernetes Service提供了一种稳定的、抽象化的方式来访问一组Pod。Service通过Kube-proxy组件来实现负载均衡和转发。
- NetworkPolicy: Kubernetes的NetworkPolicy API允许用户定义Pod之间的流量规则,以增强安全性。
然而,这些机制在实际应用中仍存在一些痛点:
- Kube-proxy的性能瓶颈: 默认情况下,Kube-proxy使用
iptables
来为Service实现负载均衡和DNAT。对于拥有大量Service和Endpoint的集群,iptables
规则链会变得非常庞大且复杂,导致性能下降、同步延迟增加,并且难以调试。 甚至 的规则查找复杂度在规模化集群中是不可接受的。 - NetworkPolicy的局限性: 默认的Kubernetes NetworkPolicy仅支持L3/L4层的流量过滤。它们无法理解HTTP请求头、gRPC方法或Kafka主题,这使得在微服务层面实施细粒度的安全策略变得困难。
- 可观测性不足: 尽管可以从Pod的日志中获取应用层信息,但缺乏一个统一的、实时的网络流可见性工具,无法清晰地看到服务间的调用关系、流量模式和延迟等关键指标。排查“黑盒”问题变得异常困难。
- 安全身份缺失: 传统的网络策略基于IP地址,但IP地址在云原生环境中是动态的且不具备业务含义。我们需要一种基于Pod身份(如标签、ServiceAccount)的安全策略,这样无论Pod的IP地址如何变化,其安全属性都能保持一致。
- 多集群/混合云连接: 随着业务发展,单个Kubernetes集群可能无法满足需求,多集群或混合云部署成为常态。如何高效、安全地连接这些分散的集群,是又一个挑战。
这些挑战促使我们寻找更先进、更灵活、更高性能的网络解决方案。而答案,就藏在Linux内核深处的eBPF中。
eBPF:重新定义内核可编程性
要理解Cilium的强大,我们必须首先理解eBPF。eBPF不仅仅是一项技术,它代表着Linux内核可编程性的一次革命性飞跃。
什么是eBPF?
eBPF,全称extended Berkeley Packet Filter(扩展的伯克利包过滤器),它起源于经典的BPF,最初用于网络包过滤。然而,现代的eBPF已经远远超出了其原始的边界。它不再仅仅是包过滤器,而是一个在Linux内核中运行的通用且安全的虚拟机。
你可以将eBPF想象成一个在内核中运行的沙盒环境,允许用户态程序在不修改内核代码的情况下,安全地运行自定义的、事件驱动的程序。这些eBPF程序可以附加到内核中的各种“hook点”,例如:
- 网络事件: 数据包的接收(XDP)、发送(Traffic Control/TC)、socket操作等。
- 系统调用: 进程调用系统时的事件。
- 内核探测点 (kprobes): 内核函数入口或出口。
- 用户空间探测点 (uprobes): 用户空间函数入口或出口。
- 跟踪点 (tracepoints): 内核中预定义的稳定API,用于调试和跟踪。
当相应的事件发生时,eBPF程序就会被触发执行。
eBPF的核心能力
eBPF之所以如此强大,源于其几个核心特性:
- 可编程性: eBPF程序由用户编写(通常是C语言,然后编译成eBPF字节码),可以在内核中执行复杂的逻辑。这使得我们能够对内核的行为进行高度定制,而无需重新编译内核或加载内核模块。
- 安全性: 这是eBPF最重要的特性之一。eBPF程序在被加载到内核之前,会经过一个严格的**eBPF验证器(Verifier)**的检查。验证器确保程序不会访问无效内存、不会陷入无限循环、不会崩溃内核,并且在有限的时间内完成执行。这使得eBPF程序比传统的内核模块更加安全和稳定。
- 高性能:
- 内核态执行: eBPF程序直接在内核中运行,避免了用户态和内核态之间的数据拷贝和上下文切换,从而显著提高了性能。
- JIT编译: eBPF字节码在加载时会被即时(JIT)编译成本地机器码,以接近原生代码的速度运行。
- eBPF Maps: eBPF程序可以通过“eBPF Maps”与其他eBPF程序或用户空间程序共享数据。Map是内核中的高效键值存储,允许eBPF程序快速查找和存储状态,支持哈希表、数组、队列等多种数据结构。
- 可观测性: eBPF天生就具备强大的可观测性。它可以深入到内核的各个层面,收集细粒度的运行时数据,包括网络流量、系统调用、函数执行等。这些数据可以被导出到用户空间进行分析、可视化,为故障排查、性能监控提供了前所未有的洞察力。
- 原子性操作: eBPF程序可以在内核中执行原子性操作,这对于在并发环境中维护数据一致性至关重要。
eBPF在网络中的应用
eBPF在网络领域的应用尤其引人注目,因为它能以极高的效率处理数据包。传统上,许多网络功能(如防火墙、负载均衡、流量整形)都是通过iptables
或内核模块实现的。但iptables
随着规则数量的增加,性能会急剧下降,且缺乏应用层可见性。内核模块则存在安全性和兼容性问题。
eBPF通过以下方式革新了网络:
- XDP (eXpress Data Path): XDP允许eBPF程序在数据包到达网络协议栈之前,也就是在网络驱动层直接处理数据包。这意味着可以在数据包进入Linux内核网络栈的早期阶段就进行过滤、转发或修改,极大地降低了延迟并提升了吞吐量。它通常用于DDoS缓解、高性能负载均衡等场景。
- Traffic Control (TC): TC子系统允许eBPF程序在数据包进入或离开网络接口时被附加。它比XDP更晚介入,但可以访问更多的协议栈信息。TC eBPF程序常用于流量整形、策略路由、网络策略强制执行等。
- Socket过滤: eBPF程序可以附加到socket上,用于过滤或修改socket传输的数据。
- Sockmap: 通过eBPF Sockmap,可以直接在内核中将数据从一个socket重定向到另一个socket,而无需经过完整的网络协议栈,极大地提高了本地进程间通信的效率。
正是这些强大的能力,使得eBPF成为构建高性能、高安全、高可观测的云原生网络的理想基石。Cilium正是充分利用了eBPF的这些特性。
Cilium:基于 eBPF 的云原生网络利器
Cilium是一款开源的CNI插件,但它的功能远超传统的CNI插件。Cilium的核心理念是利用eBPF在Linux内核中提供L3/L4层的连接和安全,以及L7层的策略强制和可见性,而无需修改应用程序代码或使用代理(如Envoy Sidecar)。
Cilium 简介
Cilium由Isovalent公司开发,并已成为云原生计算基金会(CNCF)的孵化项目。它的主要目标是为云原生工作负载提供:
- 高性能网络连接: 通过eBPF实现接近线速的数据转发和负载均衡。
- 细粒度安全策略: 基于Pod身份和L7协议定义网络策略。
- 深度可观测性: 提供实时的网络流可见性、服务依赖图和性能指标。
Cilium与Kubernetes紧密集成,通过Kubernetes API(特别是Custom Resource Definitions,CRDs)来管理和配置其网络及安全策略。
Cilium 核心特性
Cilium的强大之处在于其一系列基于eBPF构建的核心特性:
1. 身份感知安全 (Identity-aware Security)
这是Cilium与传统网络解决方案最显著的区别之一。传统网络安全策略基于IP地址和端口,而Cilium则基于工作负载身份(Workload Identity)。在Kubernetes中,这个身份通常是Pod的标签(Labels)、ServiceAccount名称。
- 如何工作: 当Pod启动时,Cilium会根据Pod的标签(例如
app=backend
,env=prod
)为其分配一个全局唯一的安全身份(Security Identity)。这个身份会附加到所有由该Pod发出的网络数据包上。当数据包到达目标Pod时,Cilium会检查源Pod和目标Pod的安全身份以及预定义的网络策略,来决定是否允许通信。 - L3/L4/L7 策略强制执行:
- L3/L4: 像传统的NetworkPolicy一样,基于IP地址、CIDR、端口号。
- L7: 这是Cilium的独有优势。Cilium可以直接在内核中解析和理解L7协议,例如HTTP、gRPC、Kafka、DNS等。这意味着你可以编写策略,允许或拒绝特定HTTP路径、gRPC方法调用或Kafka主题的访问。
例如,一个微服务只能调用另一个微服务的/api/v1/users
路径,而不能访问/admin
路径。这种细粒度的控制能力极大地增强了微服务架构的安全性,实施了真正的“零信任”网络。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: allow-l7-http
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: "GET"
path: "/api/v1/items/{id}" # 允许获取商品详情
- method: "POST"
path: "/api/v1/orders" # 允许提交订单
egress:
- toEndpoints:
- matchLabels:
k8s:app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
rules:
dns:
- matchPattern: "*.cluster.local." # 允许解析集群内部DNS
- CiliumNetworkPolicy (CRDs): Cilium通过Kubernetes CRDs扩展了NetworkPolicy API,允许用户定义更丰富的策略。
2. 高性能负载均衡 (High-Performance Load Balancing)
Cilium可以作为Kube-proxy的完全替代方案,通过eBPF在内核中实现高性能的服务负载均衡。
- eBPF Kube-proxy Replacement: Cilium利用eBPF在数据平面直接处理Service流量。当数据包到达Service ClusterIP时,eBPF程序会直接将数据包转发到后端Pod,避免了
iptables
的复杂查找和CPU开销。这显著提高了Service流量的处理速度,并降低了延迟。 - DSR (Direct Server Return): 对于某些Service类型(如LoadBalancer Service),Cilium可以配置为使用DSR模式。在这种模式下,响应流量可以直接从后端Pod返回给客户端,无需再次经过负载均衡器,从而进一步提高性能。
- Maglev / Consistent Hashing: Cilium支持Maglev一致性哈希负载均衡算法,确保在后端Pod数量变化时,已建立的连接能够尽可能地保持在同一个后端Pod上,减少连接中断。
- Egress Gateway / Load Balancing: Cilium也支持出站流量的负载均衡和策略控制,可以定义特定命名空间或Pod的流量通过特定的Egress Gateway离开集群,实现出站IP地址的统一管理或流量审计。
3. 高级可观测性 (Advanced Observability) - Hubble
Cilium自带了一个强大的可观测性平台——Hubble。Hubble充分利用eBPF在内核中捕获到的所有网络流事件,提供实时的、细粒度的网络流量可见性。
- 实时流可视化: Hubble能够以直观的方式展示Pod之间、Service之间甚至L7应用层协议的实时流量。你可以看到哪些Pod正在与哪些Service通信,流量的协议、端口、延迟、HTTP状态码等。
- 服务依赖图: Hubble可以自动构建和可视化集群中的服务依赖关系,帮助你理解微服务架构中的数据流。
- 故障排查: 当网络出现问题时,Hubble能提供详细的事件日志,例如哪些连接被安全策略拒绝,哪个请求失败了,帮助你快速定位问题。
- 分布式跟踪: 与传统APM(应用性能管理)工具不同,Hubble在网络层进行流量追踪,可以与OpenTelemetry等标准集成,提供从网络到应用栈的端到端可见性。
- Prometheus集成: Hubble数据可以导出为Prometheus指标,方便与现有的监控系统集成。
- Hubble CLI 和 UI: 提供命令行工具
hubble observe
用于实时查看流量,以及一个Web UI界面hubble ui
用于图形化展示。
4. IP 地址管理 (IPAM)
Cilium支持多种IPAM模式,包括:
- Cluster Pool: 从一个预定义的CIDR范围分配Pod IP。
- Kubernetes Host Scope: 从节点CIDR中分配IP。
- AWS VPC CNI 集成: 与AWS VPC CNI无缝集成,直接使用AWS VPC的IP地址,无需叠加网络,性能更优。
- Azure VNET 集成: 类似地,与Azure VNET集成。
Cilium的IPAM能够高效地为Pod分配和管理IP地址,支持IPv4和IPv6。
5. 多集群/混合云连接 (Multi-Cluster/Hybrid Cloud Connectivity)
Cilium Cluster Mesh允许你连接多个Kubernetes集群,形成一个逻辑上的大网络。Pod可以在不同的集群之间透明地通信,Service也可以被跨集群访问,就像它们都在同一个集群中一样。这对于构建高可用、多地域部署的应用程序至关重要。
6. 带宽管理 (Bandwidth Management)
Cilium可以使用eBPF在网络接口上实现基于Pod或命名空间的带宽限制,确保关键应用的服务质量(QoS)。
7. 加密 (Encryption)
Cilium支持基于WireGuard或IPsec的节点间流量加密,确保数据在传输过程中的安全性,即使是在不信任的网络环境中。
与 iptables 的对比
Cilium基于eBPF构建,相较于Kube-proxy和传统CNI插件依赖的iptables,具有显著优势:
特性/功能 | iptables (Kube-proxy) |
Cilium (eBPF) |
---|---|---|
性能 | 规则数量多时性能下降显著 ( 或 ) | 高性能,接近线速,规则查找 或 |
规则复杂度 | 规则链复杂,难以调试和管理 | 简单,基于Identity和eBPF Map查找 |
L7可见性与策略 | 无,仅L3/L4 | 有,支持HTTP, gRPC, Kafka等应用层策略 |
安全身份 | 基于IP地址,动态且无业务含义 | 基于Pod标签/身份,与IP无关,更稳定和业务化 |
可观测性 | 缺乏深度网络流可见性 | Hubble提供深度可观测性,实时流,服务图,L7可见性 |
Kube-proxy替代 | Kube-proxy的核心 | 可完全替代Kube-proxy,性能更优,功能更丰富 |
内存/CPU消耗 | 大量规则占用内存,CPU用于规则匹配 | 内存效率高,CPU开销低,因为在内核中高效执行 |
调试 | 复杂且耗时 | Hubble提供强大的调试工具 |
内核依赖 | Linux内核的netfilter模块 | 需要较新版本的Linux内核(例如 4.9+,推荐 5.x+)支持eBPF |
Cilium利用eBPF直接在内核中处理数据包,避免了传统iptables
的性能瓶颈和复杂性,同时提供了iptables
无法实现的应用层可见性和细粒度安全控制。
Cilium 的工作原理深度解析
Cilium的强大能力来源于其精巧的架构设计,它将控制平面和数据平面通过eBPF紧密结合。
数据平面:eBPF的魔力
Cilium的数据平面完全由eBPF程序驱动,这些程序被加载到Linux内核中,并在数据包经过网络接口时被执行。
- eBPF程序加载点:
- XDP (eXpress Data Path): 在网络驱动层处理入站(ingress)数据包。Cilium利用XDP实现高性能的Ingress负载均衡、DDoS缓解和早期丢弃无效流量。
- Traffic Control (TC): 在数据包进入或离开网络协议栈时处理。Cilium的绝大部分策略强制、L7协议解析、Service负载均衡和Egress Gateway功能都是通过TC eBPF程序实现的。
- 数据包的生命周期:
- 当一个数据包进入宿主机的网络接口时,首先可能被XDP eBPF程序处理。
- 如果数据包继续进入网络栈,TC eBPF程序会在网络接口的入口(ingress hook)和出口(egress hook)处被触发。
- 身份映射: eBPF程序会从数据包中提取Pod的IP地址,并将其映射到Cilium的安全身份(Security Identity)。这个映射关系存储在eBPF Maps中。
- 策略查找与强制: 根据数据包的源身份、目标身份以及L7协议信息,eBPF程序会在eBPF Maps中快速查找预编译好的安全策略。如果策略允许,数据包将被转发;如果策略拒绝,数据包将被丢弃并记录事件。由于eBPF Map的查找是 复杂度,因此即使有成千上万条策略,性能依然极高。
- 负载均衡: 如果数据包是针对某个Service ClusterIP的,eBPF程序会从eBPF Maps中获取Service的后端Endpoint列表,并根据负载均衡算法(如加权轮询、一致性哈希)选择一个后端Pod,然后直接修改数据包的目标地址并转发。
- L7协议解析: 对于需要L7策略的数据包,Cilium会将这些数据包重定向到用户空间的一个特殊代理(例如Envoy),进行L7解析和策略强制。处理完成后,再将数据包返回给eBPF程序继续处理。这个代理是动态按需创建的,并且只处理需要L7策略的流量,避免了对所有流量都进行代理的开销。
- 数据包转发: 经过所有eBPF程序的处理后,数据包被转发到正确的Pod或外部目标。
- eBPF Maps 的关键作用: eBPF Maps是Cilium高性能的基石。它们存储了:
- IP地址与安全身份的映射。
- 安全策略规则。
- Service Endpoint信息。
- 统计数据和流信息(供Hubble使用)。
Cilium Agent负责维护和更新这些eBPF Maps,而eBPF程序则高效地查询它们。
控制平面:Cilium Agent与Kubernetes的协作
Cilium的控制平面主要由cilium-agent
和cilium-operator
组成。
-
Cilium Agent (DaemonSet):
- 每个Kubernetes节点上都运行一个
cilium-agent
Pod。 cilium-agent
是Cilium的核心大脑。它通过Kubernetes API Server监听集群中的资源变化,包括:- Pod: 监听Pod的创建、更新、删除,为Pod分配IP地址和安全身份。
- Service: 监听Service和Endpoint的变化,更新Service的后端信息到eBPF Maps中。
- NetworkPolicy / CiliumNetworkPolicy: 监听这些策略资源,将其转换为eBPF字节码和eBPF Maps中的数据结构,并加载到内核。
- 编译和加载eBPF程序: 当网络策略或网络拓扑发生变化时,
cilium-agent
会动态地生成、编译并加载新的eBPF程序或更新eBPF Maps。 - IPAM: 负责节点的IP地址管理,与Kubernetes API交互以分配Pod IP。
- 健康检查与报告: 监控eBPF程序的状态和性能,并向Kubernetes报告节点健康状态。
- Hubble数据出口: 从内核的eBPF Maps中收集网络流事件,并通过Unix域套接字提供给Hubble服务。
- 每个Kubernetes节点上都运行一个
-
Cilium Operator:
cilium-operator
通常作为一个单独的Pod在集群中运行(通常是高可用部署)。- 它处理集群范围内的、与节点无关的任务,例如:
- CIDR分配: 在Cluster Pool IPAM模式下,为节点分配Pod CIDR块。
- 身份管理: 维护和管理全局安全身份,确保身份的唯一性。
- 垃圾回收: 清理不再使用的资源。
-
与Kube-apiserver交互:
cilium-agent
和cilium-operator
通过Watch机制持续监控Kubernetes API Server的资源变化。当它们检测到Pod、Service、Endpoint或策略资源有更新时,会相应地调整eBPF程序和eBPF Maps,从而动态地响应集群的网络和安全需求。
整个架构使得Cilium能够提供一个高度自动化、高性能、安全且可观测的云原生网络解决方案。
Hubble 的内部机制
Hubble利用了eBPF的事件驱动特性和eBPF Maps。
- eBPF事件生成: Cilium的eBPF程序在处理数据包时,会生成各种网络流事件,例如连接建立、数据包丢弃(由于策略拒绝)、L7请求/响应等。
- 事件存储: 这些事件被存储在内核的特殊eBPF Maps中。
- Hubble Relay:
hubble-relay
服务从每个节点上的cilium-agent
那里收集这些事件。 - Hubble CLI/UI:
hubble observe
命令行工具或hubble ui
的Web界面通过hubble-relay
获取实时或历史的网络流数据,并进行聚合、过滤、可视化展示。
这使得Hubble能够提供前所未有的网络可见性,帮助用户理解和调试复杂的微服务交互。
部署与实践
了解了Cilium的原理,现在让我们来看看如何在Kubernetes集群中部署和使用它。
安装 Cilium
推荐使用Helm来安装Cilium,因为它提供了灵活的配置选项。
-
添加Cilium Helm仓库:
1
2helm repo add cilium https://helm.cilium.io/
helm repo update -
选择你的Linux内核版本: Cilium对eBPF有最低内核版本要求,通常建议使用Linux 4.9及以上版本,但要充分发挥所有特性,例如XDP、BPF Sockmap等,推荐使用5.x或更高版本。你可以通过
uname -r
查看当前内核版本。 -
安装Cilium:
以下是一个常用且推荐的安装命令,它启用了一些关键特性:kubeProxyReplacement=strict
: 完全替代Kube-proxy,使用eBPF实现Service负载均衡。这是Cilium的强大卖点。bpf.masquerade=true
: 使用eBPF进行IP地址伪装(SNAT),替代iptables。ipam.mode=clusterPool
: Cilium管理Pod的IP地址,从一个预定义的池中分配。hubble.enabled=true
: 启用Hubble可观测性。hubble.ui.enabled=true
: 启用Hubble UI。
1
2
3
4
5
6
7
8
9
10
11helm install cilium cilium/cilium --version 1.15.0 \
--namespace kube-system \
--set kubeProxyReplacement=strict \
--set bpf.masquerade=true \
--set ipam.mode=clusterPool \
--set cluster.name=my-kubernetes-cluster \
--set egressMasqueradeInterfaces=eth0 \
--set hubble.enabled=true \
--set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,http}" \
--set hubble.ui.enabled=true \
--set operator.replicas=1 # 生产环境建议2个以上请根据你的集群和需求调整
--version
和--set
参数。例如,如果你在AWS EKS上使用Cilium,你可能会配置ipam.mode=aws-vpc-cni
来集成AWS VPC CNI。 -
验证安装:
1
2
3kubectl get pods -n kube-system -l k8s-app=cilium
kubectl get ciliumnode # 查看Cilium节点状态
cilium status # 检查Cilium服务状态和eBPF程序加载情况
Cilium NetworkPolicy 示例
一旦Cilium安装完毕,你就可以开始定义基于身份和L7的策略了。
1. 简单的L3/L4策略:允许frontend访问backend的80端口
1 | apiVersion: "cilium.io/v2" |
解释:
endpointSelector
: 选择该策略应用的目标Pod,这里是所有带有app: backend
标签的Pod。ingress
: 定义入站流量规则。fromEndpoints
: 允许来自所有带有app: frontend
标签的Pod的流量。toPorts
: 允许流量到达目标Pod的TCP 80端口。
应用此策略:kubectl apply -f allow-frontend-to-backend.yaml
2. L7 HTTP策略:允许frontend访问backend的/api/v1/data
路径
假设你的backend服务在8080端口提供HTTP API。
1 | apiVersion: "cilium.io/v2" |
解释:
- 在
rules
下添加http
规则块。 - 你可以精确控制HTTP方法(
method
)和路径(path
)。path
支持正则表达式匹配。
这展示了Cilium在应用层进行精细控制的强大能力。
使用 Hubble 进行可观测性
Hubble是Cilium的另一个明星功能,它提供了无与伦比的网络流量可见性。
-
安装Hubble CLI:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15CILIUM_CLI_VERSION=$(curl -s https://api.github.com/repos/cilium/cilium-cli/releases/latest | grep ".tag_name" | cut -d'"' -f4)
CLI_ARCH=amd64
if [ $(uname -m) = "aarch64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar -C /usr/local/bin -xzf cilium-linux-${CLI_ARCH}.tar.gz
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
HUBBLE_VERSION=$(curl -s https://api.github.com/repos/cilium/hubble/releases/latest | grep ".tag_name" | cut -d'"' -f4)
HUBBLE_ARCH=amd64
if [ $(uname -m) = "aarch64" ]; then HUBBLE_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/hubble/releases/download/${HUBBLE_VERSION}/hubble-linux-${HUBBLE_ARCH}.tar.gz{,.sha256sum}
sha256sum --check hubble-linux-${HUBBLE_ARCH}.tar.gz.sha256sum
sudo tar -C /usr/local/bin -xzf hubble-linux-${HUBBLE_ARCH}.tar.gz
rm hubble-linux-${HUBBLE_ARCH}.tar.gz{,.sha256sum} -
启用Hubble Relay (如果安装时未启用):
1
cilium hubble enable
-
查看实时网络流:
1
2
3hubble observe # 实时显示所有网络流
hubble observe -f pod-name # 过滤特定Pod的流
hubble observe --type policy-verdict # 查看被策略允许或拒绝的流输出示例(简化):
1
2
3Mar 28 10:30:00.123 default/frontend:8080 -> default/backend:80 (TCP_SYN) FORWARDED
Mar 28 10:30:00.125 default/frontend:8080 -> default/backend:80 (HTTP/1.1 GET /api/v1/data) FORWARDED
Mar 28 10:30:01.456 default/internal-app -> default/db:5432 (TCP_SYN) DENIED (Policy) -
使用Hubble UI:
首先,通过端口转发暴露Hubble UI服务:1
cilium hubble ui
然后访问
http://localhost:12000
(或控制台输出的地址)。Hubble UI将以图形化的方式展示集群内的服务通信图,你可以点击服务查看详细的流量统计和L7事件。
常见问题与最佳实践
- Linux内核版本: 确保你的集群节点运行的Linux内核版本足够新(推荐 5.x 及以上),以支持Cilium的所有eBPF特性。旧版本内核可能会导致某些功能无法使用或性能不佳。
- 资源限制: 为Cilium Agent和Operator Pod设置适当的CPU和内存资源限制,以确保它们稳定运行。
- IPAM模式选择: 根据你的云环境和需求选择合适的IPAM模式。对于公有云,集成云服务商的VPC CNI(如AWS VPC CNI)通常是性能最佳的选择。
- 调试:
cilium status
: 快速检查Cilium Agent的健康状态、eBPF程序的加载情况、策略数量等。cilium monitor
: 实时查看Cilium在数据平面上的活动,包括数据包的接受、处理、转发、丢弃等事件。cilium policy get
: 查看已加载的CiliumNetworkPolicy的内部表示。cilium endpoint get <pod-name>
: 查看特定Pod的Cilium内部状态,包括其安全身份、已应用的策略等。
- L7策略的开销: 虽然Cilium的L7策略非常强大,但它确实需要在数据平面中引入L7代理。对于不需要L7过滤的流量,Cilium会绕过代理,直接通过eBPF处理,从而最小化开销。只对必要流量使用L7策略,可以平衡安全性和性能。
- 多集群连接: 如果你有多个Kubernetes集群,探索Cilium Cluster Mesh可以实现无缝的跨集群通信和安全策略。
通过合理配置和利用Cilium的这些特性,你可以构建一个既安全又高性能的云原生网络。
结论
云原生技术的飞速发展,对底层网络基础设施提出了前所未有的挑战。传统基于IP地址和端口的网络模型在面对动态、瞬时和高密度的微服务时,显得力不从心。我们渴望一种能够提供细粒度控制、高性能、以及深度可观测性的网络解决方案。
eBPF,作为Linux内核可编程性的一次革命,为解决这些挑战提供了坚实的基础。它允许我们以安全、高效的方式在内核中运行自定义程序,从而在数据包层面实现复杂的网络和安全逻辑,同时避免了传统方法的性能瓶颈和运维复杂性。
Cilium正是eBPF理念的杰出实践者。它不仅仅是一个CNI插件,更是一个基于eBPF构建的全面云原生网络和安全平台。通过身份感知安全、高性能的eBPF负载均衡、以及强大的Hubble可观测性,Cilium彻底改变了我们构建和运营云原生应用网络的方式。它让微服务间的通信变得更加安全、可控和透明,为实施零信任网络架构提供了坚实的基础,并极大地简化了网络故障的排查。
展望未来,eBPF无疑将继续在云原生领域发挥越来越重要的作用。随着eBPF生态系统的不断成熟和Cilium功能的持续演进,我们可以期待更智能、更自动化、更高效的云原生网络解决方案。Cilium所代表的,不仅仅是一种技术选择,更是云原生网络发展的必然方向。
如果你正在构建或管理Kubernetes集群,并面临着网络性能、安全和可观测性的挑战,那么我强烈推荐你深入了解并尝试Cilium。它将是你探索云原生网络未来道路上的得力助手。现在就开始你的Cilium之旅吧!