Cilium 是一种开源的云原生网络解决方案,基于革命性的内核技术 eBPF ,为工作负载提供高性能、安全、可观测的网络连接。eBPF 技术通过提供附加自定义程序到内核中的事件为应用程序提供超能力,Cilium 项目利用 eBPF 的能力开发了多个程序,通过这些程序可以有效地管理容器集群。
目前Clilium项目包含三个项目:Cilium、Hubble、Tetragon。
解决了容器网络云面临的三大挑战:连接、可观测性、安全。
Cilium最初由Isovalent创建,并于2015年开源,非常受欢迎。有14000+ Github star,500+贡献者,以及14000+用户注册了Cilium社区Slack。更重要的是,Cilium 被媒体、金融和搜索等各种垂直行业的组织广泛部署在生产环境中,AWS、微软、google三大云提供商现在都在其 Kubernetes 服务产品中支持 Cilium。Cilium 于2021年10月加入CNCF孵化,并于2022年10月毕业。毕业状态是任何 CNCF 项目的一个重要里程碑,表明该项目拥有可持续的贡献者社区,被广泛采用,并且正在成为任何云规模堆栈的预期部分。
Kubernetes 的最大优势在于其动态特性,这使其能够按需扩展服务,并在出现问题时将 Pod 和服务协调到所需的状态。例如,如果一个节点出现故障,Kubernetes 将自动重启集群中另一个节点上的 pod,以弥补其损失。但是,这种动态性给传统网络带来了麻烦,因为IP地址在整个集群中被重新分配和重用。对于人工操作员,存在可观测性问题,因为您无法再对与特定工作负载匹配的 IP 地址做出假设。在底层网络堆栈中,某些组件不是为不断重用 IP 地址而设计的,从而导致大规模性能问题。
Cilium 在 Linux 内核的不同点注入 eBPF 程序,提供适合云原生时代的连接层,该层使用 Kubernetes identities 而不是 IP 地址,并允许绕过部分网络堆栈以获得更好的性能。
在 Kubernetes 中,Pod 通常运行自己的网络命名空间,这意味着数据包必须经历网络堆栈两次——一次在 Pod 命名空间中,一次在主机中。Cilium 允许绕过主机堆栈的重要部分,从而显著提高性能。就像闪电侠一样,它快如闪电。
从上图可以看出,Cilium 可以绕过网络堆栈中的 iptables。这是一个在设计时没有考虑到 Kubernetes 行为的组件,并且由于 Kubernetes 的动态性质,iptables 的性能通常会大规模下降。在节点、Pod 和服务较多的大型集群中,通常有大量的 iptables 过滤器和转发规则,需要随着 Pod 的来来去去进行更新。更糟糕的是,对于iptables,更改一个规则意味着整个表被重写。随着部署的增长,每次创建或销毁 Pod 时,规则需要越来越长的时间来收敛,从而导致大规模正确操作的严重延迟。
Cilium 不是 iptables,而是在 eBPF maps 中跟踪 pod endpoints。这些是存储在内核中的数据结构,Cilium 的 eBPF 程序可以访问这些数据结构,以便就每个网络数据包的发送位置做出高效的决策。
传统的 Kubernetes 网络策略基于 iptables filters,这些 filters 也存在相同的规模问题。Cilium 采用了不同的方法,使用 Kubernetes 标签为 Pod 分配安全身份(类似于 Kubernetes 使用标签识别分配给每个服务的 Pod 的方式)。网络策略以 eBPF maps 表示,并允许在网络流量进入或离开 Cilium 管理的节点时从这些映射进行超快速查找,以决定是否允许或拒绝数据包。这些eBPF程序非常小,速度超快。
使用 Cilium,您可以编写应用程序感知的 L7 策略!例如,您可以编写一个策略来限制 Pod 之间的访问,以仅允许特定 API 端点上的特定 HTTP REST 方法。您还可以根据完全限定的域名或 IP 地址筛选流量,以便在流量需要在群集外部通信时进行通信。
策略实施并不是 Cilium 提供的网络安全的唯一方面。零信任网络已迅速成为最佳实践,透明加密可能是确保所有网络流量都加密的最简单方法。您可以轻弹开关,让 Cilium 创建流量通过的 IPsec 或 WireGuard 连接。通过 eBPF 的魔力,这发生在内核级别,因此您的应用程序不需要任何更改即可加密其流量。
借助 Cilium,您可以轻松地将容器化客户端和服务与旧式基础架构连接起来。来自 Kubernetes Pod 的网络流量最终看起来像是从伪随机 IP 地址到在数据中心服务器机架中的虚拟机上运行的传统服务。您的传统防火墙基础设施非常希望处理静态 IP 地址,以便它可以区分朋友和敌人。Cilium 具有出口网关概念,可通过具有固定 IP 地址的特定出口节点路由用于传统服务的流量。另一方面,Cilium 还支持边界网关协议 (BGP),以便更轻松地将 Kubernetes 服务的路由宣布到集群外部的网络基础设施。Cilium 在与您的外部服务集成时为您提供来来往往。
我们已经讨论过将 Cilium 与外部遗留工作负载集成,但是多个 Kubernetes 集群呢?是否需要将从一个群集到另一个群集的连接视为另一个外部服务?您可以将多个支持 Cilium 的 Kubernetes 集群组合在一起,并以非常酷的方式利用 Cilium 的身份模型来帮助多集群服务配置。Cilium 将这种多集群支持称为 ClusterMesh。
使用 Cilium ClusterMesh,您可以使用 Kubernetes annotations 指定全局服务,并且 Cilium 将对与存在于多个集群中的全局服务关联的服务端点的访问进行负载平衡 - 如果需要,可以使用加密流量。可以将这些全局服务的服务相关性指定为首选在本地发送请求(如果终结点运行正常),并在需要时故障转移到其他群集中的远程服务终结点。
简化跨集群故障转移只是一个好处:有各种实际的多集群用例,在 Cilium ClusterMesh 中更容易实现。设置 ClusterMesh 只是让启用 Cilium 的集群相互感知的问题,而 cilium cli 工具使这个过程非常简单。事实上,我能够使用 Cilium 项目的快速入门指南,在短短几分钟内在 Azure AKS 中启动跨越美国东部和西部区域的全局服务故障转移 Cilium ClusterMesh,在第一次尝试之前,我对 Azure AKS 一无所知。
到目前为止,我一直专注于网络连接和安全性,但 Cilium 也可以帮助实现大规模的网络可观测性。
Kubernetes集群内部的网络可观测性变得非常复杂。由于 Pod 不断来来去去,并且在扩展和缩减时跨不同工作负载重新分配内部 IP 地址,因此很难观察数据包流。尝试按群集内的 IP 地址跟踪数据包是徒劳的。即使在节点上运行 eBPF 驱动的 tcpdump 也是不够的,因为 IP 地址和端口很难与工作负载匹配,尤其是当 Kubernetes 本身可能通过快速重新调试 pod 来尝试解决您正在诊断的问题时。当其中一个微服务或我们的网络策略出现问题时,我们如何获得可观测性?
是时候向您介绍Cilium的超级朋友 Hubble 了。Hubble 过滤了动态IP寻址的噪声,将网络流与其Kubernetes身份呈现在一起,因此您可以清楚地看到Pod和服务如何相互通信以及与外部世界进行通信。Hubble建立在Cilium的基础上,创建了一个一流的容器网络可观测性平台,不仅能够向你显示网络第3层和第4层的流的详细信息,还可以在第7层向你显示协议流的细节,如HTTP和gRPC。
Hubble UI 更进一步,提供了服务依赖关系图的图形描述以及网络流详细信息。
Cilium 和 Hubble 共同揭示了各种各样的指标、跟踪和日志,这些指标、跟踪和日志对于观察您的网络和诊断问题非常宝贵。您可以将这些数据提取到Grafana中以便于可视化,轻松回答有关您的网络的各种问题。例如,如果您想知道特定服务或所有集群的 4xx HTTP 响应速率,或者如果您想知道性能最差的服务之间的请求/响应延迟,Hubble 指标可以满足您的需求。
但容器安全性不仅与网络策略有关,容器运行时也受益于安全策略。Tetragon专注于使用eBPF进行运行时安全可观察性和实施。Tetragon 检测并可以报告一系列安全重要事件,例如:
Tetragon并不是第一个出现的eBPF驱动的安全工具,但它为容器安全带来了许多新功能。如果其他项目在表面上挂接到系统调用,则它们受到检查时间到使用时间漏洞的影响,在该漏洞中,系统调用的参数可能在到达内核之前被覆盖。Cilium 工程师利用他们对内核内部的了解,在不受此问题影响的点上挂钩到事件中。
Tetragon的跟踪策略允许您配置要观察的内核事件,并定义匹配条件并采取行动。更重要的是,Tetragon提供基于Kubernetes身份的上下文信息。例如,如果要检测对特定文件或目录的访问,则可以配置一个 TracingPolicy,该策略将发出日志,准确告诉您哪个进程(运行哪个可执行文件)、哪个 pod 访问了该文件。您甚至可以将策略配置为在文件访问完成之前终止违规进程。这非常强大,并为容器安全增加了一种全新的方法,以帮助您限制容器暴露的攻击面。像沙赞一样,Tetragon被赋予所罗门的智慧,拥有丰富的知识和对如何采取行动的判断技巧。
Tetragon可以独立使用,独立于Cilium的网络功能。但是想象一下,你可以用一个Tetragon&Cilium超级英雄的团队来做什么,结合网络和运行时安全超能力,这样你就可以,例如,看到启动可疑网络连接的完整进程祖先。
您已经看到 Cilium 不仅实现了 Kubernetes 服务之间的连接,而且还提供了可观测性和安全性功能,并且能够在第 7 层采取行动。这不是与服务网格非常相似吗?是的!现在,Cilium 项目可以提供服务网格功能,而无需将边车注入每个 pod,从而提高服务网格效率。进步有多大?让我们看一下对同一节点上容器之间的 HTTP 延迟处理的影响。使用 HTTP 代理总是会有成本的,但是,当您使用sidecar模式时,您可能会支付两倍的代价,因为微服务相互通信并且流量同时通过ingress和egress sidecar HTTP 代理。减少网络路径中的代理数量并选择 HTTP filter 的类型会对性能产生重大影响。
下面是一个基准比较,来自一篇深入探讨 Cilium 服务网格如何工作的博客文章,它说明了运行 Cilium Envoy filter(棕色)的单个节点范围的 Envoy 代理与运行 Istio Envoy filter(蓝色)的双边车 Envoy 模型的 HTTP 处理的典型延迟成本。黄色是没有代理且未执行 HTTP 处理的基线延迟。
Cilium Service Mesh 通过使用 Envoy 网络代理来实现这种延迟改进,该代理作为 agent 的一部分在每个节点上运行,而不是作为 sidecar 附加到每个 Pod。但这种改进也不全面的,是因为Cilium在将网络流量重定向到节点范围的Envoy代理之前尽可能多地使用eBPF。这是一个令人印象深刻的一两拳组合,值得野猫,利用时机和技术而不是蛮力来获得您想要的结果。
这不是一种新方法——Envoy 已经在 Cilium 中用于实施第 7 层感知网络策略多年。为了实现其无 sidecar 服务网格,Cilium 扩展了对完全兼容的 Kubernetes 入口和网关 API 实现的支持,以及一个较低级别的 CRD,该 CRD 在 Cilium 中公开了 Envoy 的全部功能。如果您现在正在使用基于sidecar 的服务网格,并且开始感到与在每个 Pod 中部署服务网格sidecar相关的资源成本紧张,那么现在是将 Cilium Service Mesh 视为资源效率更高的替代品的好时机。
虽然一直在 Kubernetes 集群的背景下谈论 Cilium,但 Cilium 不仅限于 Kubernetes。Cilium 为连接性、可观测性和安全性带来的好处也可以在 Kubernetes 之外的工作负载中实现。例如,Cilium 可以用作独立的负载均衡器,并在实际生产环境中显示出令人印象深刻的优势。