Skip to content

1cilium概念核心组件和功能支持

Cilium 是什么?

我们直接切入主题,Cilium 是什么?简单来说,它是一个开源软件,专门用来透明地保护在像 Kubernetes 这样的容器平台上运行的应用服务之间的网络连接。它的核心是 Linux 内核的一个新特性,叫做 e B P F,这使得我们能在内核层面动态地插入强大的安全可见性和控制逻辑。最棒的是,因为是在内核里跑,所以你不需要改动任何应用代码,也不用调整容器配置,就能轻松应用和更新安全策略。

Cilium 的核心武器就是 eBPF。你可以把它想象成一把内核级的瑞士军刀。它允许我们动态地在 Linux 内核里插入各种安全策略和监控逻辑。为什么这很重要?因为它在内核里运行,性能损耗极低,几乎感觉不到它的存在。而且,它非常灵活,我们可以通过编写 BPF 程序来精确控制网络流量,实现各种精细化的策略。这就像给你的网络加了一层智能的、高性能的内核级防火墙。

有了Cilium这个强大的网络代理,我们还需要一个工具来观察和理解这个网络世界。这就引出了Hubble。Hubble是一个完全分布式的设计,它是一个网络和安全的可观测性平台。它不是凭空出现的,而是建立在Cilium和eBPF的基础之上。通过利用eBPF,Hubble能够提供前所未有的深度可见性,让我们能够洞察服务之间的通信、行为,以及整个网络基础设施的运行状态,而且这一切都是完全透明的。可以说,Hubble是Cilium的千里眼和顺风耳。

Hubble到底能帮我们回答什么问题呢?

  • 首先,它能帮你绘制出清晰的服务依赖关系图。哪些服务在互相通信?频率有多高?整个服务依赖关系图长什么样?这些都能一目了然。更进一步,比如你想知道服务之间到底发生了哪些HTTP调用?或者某个服务订阅了哪些Kafka topic?这些应用层面的信息,Hubble也能帮你挖掘出来。
  • 网络监控和告警是运维的重中之重。Hubble在这方面同样表现出色。它能告诉你:有没有网络通信失败?失败的原因是什么?是DNS解析问题?还是应用本身出了问题?或者网络层面的问题?是TCP层的问题还是HTTP层的问题?比如,最近五分钟,哪些服务遇到了DNS解析失败?哪些服务最近有TCP连接中断或超时?甚至还有未响应的TCP SYN请求速率,这些细节都能捕捉到。
  • 除了网络层面,Hubble还能深入到应用层面。比如,某个特定服务的HTTP请求,有多少响应码是5xx或者4xx?整个集群的平均情况如何?请求的延迟怎么样?95th和99th百分位的延迟是多少?哪些服务表现最差?两个服务之间的交互延迟是多少?在安全方面,哪些服务因为网络策略被阻止了?哪些服务被外部访问了?哪些服务解析了某个特定的DNS名称?这些都是Hubble能提供的宝贵信息。

eBPF

那么,为什么我们要选择Cilium和Hubble呢?关键就在于eBPF。eBPF正在开启一个全新的维度,让我们能够以前所未有的粒度和效率来观察和控制系统和应用程序。它最大的优点就是透明,完全不需要你修改应用代码,就能实现强大的安全和监控功能。而且,eBPF的适用性非常广,无论是现代的容器化工作负载,还是传统的虚拟机,甚至是标准的Linux进程,它都能很好地应对。现代数据中心应用普遍采用微服务架构。

这种架构带来了巨大的灵活性和可扩展性,但也带来了新的挑战。微服务环境高度动态,容器频繁启动、销毁,IP地址也跟着变化。传统的基于IP地址和端口的防火墙,在这种环境下就显得力不从心了。你想想象一下,如果每次容器启动都要更新成百上千条规则,那得有多崩溃?而且,端口也变得模糊不清,比如TCP 80端口,可能同时跑着好几个服务。再加上IP地址的生命周期可能只有几秒,传统的追踪方式也失效了。这就是微服务架构给安全和监控带来的巨大挑战。面对这些挑战,Cilium是如何应对的呢?关键在于它基于身份的策略。它不再依赖于飘忽不定的IP地址,而是给服务、Pod或者容器赋予一个身份标识,然后基于这个身份来制定安全策略。这就像给每个用户发了ID卡,而不是只看他们的IP地址。

更进一步,Cilium还能在应用层进行过滤,比如HTTP协议,这大大增强了隔离能力。再加上eBPF的加持,Cilium能够轻松应对大规模环境下的高动态性。我们来看Cilium和Hubble的核心功能。首先是透明API保护。这意味着我们可以直接保护像REST、HTTP、gRPC、Kafka这些现代应用协议。这可不是简单的Layer 3或4防火墙,而是Layer 7的策略。你可以根据具体的HTTP请求方法、路径、Kafka topic,甚至是HTTP头来设置规则。比如,只允许GET请求访问/public目录,其他一律拒绝;或者只允许特定的服务向Kafka topic生产消息,其他服务禁止访问。甚至可以强制要求所有REST请求都必须带某个Token头。这灵活性,传统防火墙根本没法比。

基于身份的微服务通信安全

第二个核心功能是基于身份的微服务通信安全。还记得微服务环境里IP地址变化快的问题吗?Cilium的解决办法是,为那些共享相同安全策略的容器组分配一个唯一的身份标识,这个标识会随着数据包一起发送。接收端收到数据包后,会验证这个身份标识是否合法。这样,即使IP地址变了,只要身份不变,策略就能继续生效。这个身份的管理,通常是通过一个键值存储来实现的,保证了高效性和一致性。

对于外部服务的访问,Cilium也提供了相应的安全机制。虽然标签基策略在集群内部访问控制中是主力,但有时候我们需要更传统的基于IP地址的控制。比如,限制容器只能访问特定的外部IP地址范围。这时候,Cilium的CIDR基安全策略就派上用场了。你可以用它来设置入口和出口的规则,精确地控制容器对外部网络的访问权限。网络连接方面,Cilium力求简单。它提供了一个扁平的Layer 3网络,把所有应用容器连接起来,甚至可以跨集群。IP地址分配也很简单,每个节点自己管自己的,不用互相协调。

多节点通信和带宽管理

对于多节点网络,Cilium支持两种主流模式:Overlay模式,基于封装,比如VXLAN和Geneve,这是最通用的,对底层网络要求很低,只要有IP可达就行。另一种是Native Routing模式,直接利用Linux主机的路由表,这种方式更适合那些对网络有深入了解的高级用户。负载均衡方面,Cilium也实现了分布式的能力,可以直接替代像kube-proxy这样的组件。它的负载均衡是用eBPF实现的,利用高效的哈希表,理论上可以扩展到非常大的规模。对于南北向的流量,比如从外部访问服务,Cilium的实现经过优化,性能很高,还能支持XDP、DSR直接服务器返回和Maglev一致性哈希。对于东西向的流量,比如服务内部通信,Cilium在内核socket层就完成了服务到后端的转换,避免了NAT带来的开销。

带宽管理也很重要。Cilium使用了基于eBPF的EDT最早出发时间算法来进行速率限制。这种方法的好处是,相比传统的HTB、TBF等令牌桶算法,能显著降低应用的传输延迟,尤其是在处理尾部数据包时,效果更明显。而且,它在多队列网卡上也能避免锁竞争,性能更稳定。

最后,我们来谈谈监控和故障排除。虽然tcpdump、ping这些老朋友我们依然爱,但Cilium和Hubble提供了更强大的工具。比如,当一个包被丢弃时,它不仅告诉你源IP和目的IP,还会提供发送者和接收者的完整标签信息,以及其他元数据。关键指标可以通过Prometheus导出,方便集成到现有的监控面板。

Hubble

当然,最核心的还是Hubble本身,它提供了一个专门针对Cilium设计的可观测性平台,包括服务依赖图、运维监控告警、以及基于流日志的应用和安全可见性。

Cilium和Hubble的核心组件

我们快速过一下Cilium和Hubble的主要组件。

  • 首先是Cilium Agent,这是每个节点上运行的核心组件。它负责接收来自Kubernetes或API的配置,包括网络、负载均衡、安全策略、监控需求等等。它还会监听Kubernetes事件,知道哪些容器启动了、停止了。最重要的是,它负责管理内核里的eBPF程序,真正控制着网络流量的进出。
  • Cilium Operator 是一个负责集群级管理任务的组件。它处理那些需要在整个集群范围内执行一次的任务,而不是每个节点都重复一遍。比如,IP地址分配、KVStore心跳更新等。需要注意的是,Operator本身并不在数据转发或策略决策的关键路径上,所以即使它暂时挂了,集群通常也能继续运行。但长时间不可用可能会导致一些问题,比如IP地址分配延迟,或者KVStore心跳失败导致Agent重启。
  • CNI Plugin,也就是Cilium CNI。这是Kubernetes调用的插件,当一个Pod被调度到某个节点,或者被终止时,Kubernetes就会调用这个插件。它的作用是触发Cilium Agent,为这个Pod配置好网络、负载均衡和网络策略。简单来说,它是Kubernetes和Cilium Agent之间的桥梁。
  • Hubble Server 是Hubble的核心组件之一,它运行在每个节点上,嵌入在Cilium Agent里面。这样做的好处是性能高,开销低。它的主要职责是从Cilium那里获取基于eBPF的可见性数据,然后通过gRPC服务提供给客户端。你可以把它看作是Hubble的本地数据收集器和提供者。
  • Hubble Relay 是一个独立的组件,它负责连接集群中所有运行的Hubble Server。你可以把它想象成一个中央调度站。它会连接到每个节点的Hubble Server,聚合来自各个节点的数据,然后提供一个统一的API接口,让你能够从集群全局视角查看网络和安全事件。
  • 最后是Hubble的客户端工具。Hubble CLI,也就是hubble,是一个命令行工具,你可以用它来连接Relay或者直接连接本地的Hubble Server,获取流事件和指标。
  • 还有一个图形化界面,Hubble GUI,它利用Relay提供的数据,为你展示一个直观的服务依赖关系图和连接图,让你对整个网络拓扑一目了然。

EBPF

我们再稍微深入一点,聊聊eBPF。它最初是Linux内核里一个用来过滤网络数据包的字节码解释器,比如tcpdump和socket filters就用到了。后来,它被大大扩展,增加了各种数据结构,比如哈希表、数组,以及更多的动作,比如数据包处理、转发、封装等等。内核里还内置了一个验证器,确保你写的eBPF程序不会搞砸系统。JIT编译器则负责把字节码翻译成CPU能直接执行的指令,效率很高。eBPF程序可以在内核的很多地方运行,比如数据包的入站和出站钩点。

Cilium很聪明,它能自动检测内核支持的最新eBPF特性,并加以利用。在Cilium集群中,各个节点上的Agent需要同步状态信息,比如安全策略、IP地址分配等。这需要一个数据存储。Cilium默认使用Kubernetes CRDs来存储这些数据,这也是最方便的方式。当然,如果你追求极致的扩展性,也可以选择使用Key-Value Store,比如etcd,来优化状态同步和变更通知。不过,对于大多数场景来说,CRDs已经足够用了。

安装Cilium其实很简单。这里介绍的是快速安装指南,它会自动检测你的Kubernetes环境,选择最佳配置,并且默认使用CRDs来存储状态。这非常适合大多数用例。如果你是大型集群,或者有特殊的数据路径需求,比如要跑在裸金属上,或者有特定的网络拓扑,那就需要参考更详细的Getting Started指南了。安装过程中遇到问题,别慌,文档里有Troubleshooting章节,或者去Cilium Slack社区求助。安装之前,你需要确保你的Kubernetes集群已经准备好。你可以自己搭一个本地的,比如用minikube、kind,或者使用云厂商提供的托管服务,比如GKE、AKS、EKS、OpenShift等等。然后,你需要安装Cilium CLI。这个工具很重要,它可以帮助你安装、检查Cilium的状态,以及启用或禁用某些特性,比如Hubble、ClusterMesh等。对于大多数Kubernetes集群,使用默认配置安装Cilium就足够了。安装命令会自动帮你配置好一切,包括使用CRDs来管理状态,以及采用Overlay网络模式。如果你在AWS上,还可以选择集成AWS ENI模式,这能进一步简化网络配置,提高性能。当然,安装时可能会遇到一些小插曲,比如需要重启一些之前运行的Pod,这是正常的,安装程序会自动处理。

安装完成后,怎么验证呢?最简单的方法就是运行 cilium status --wait。这个命令会等待Cilium完全安装完成,然后输出一个状态报告。你会看到Cilium、Operator、Hubble、ClusterMesh的状态是否OK,以及相关的Pod和容器状态。仔细检查一下,确保一切正常。如果看到什么异常,比如某个Pod状态是CrashLoopBackOff,那就需要检查对应的日志,看看问题出在哪里。为了让大家更直观地理解Cilium的应用,