Cilium架构 (Cilium 2)
Cilium架构
译自:http://docs.cilium.io/en/stable/architecture/
本文档描述了Cilium的架构。它通过记录BPF数据路径(datapath)的钩子来实现Cilium数据路径,那么Cilium数据路径是如何与容器编排层继承,以及如何在各层(如BPF数据路径和Cilium代理)之间更新对象的?
数据路径
Linux内核在网络栈中支持一个BPF钩子集,使用这些勾子可以允许BPF程序(即使用回调函数运行)。Cilium数据路径使用这些钩子加载BPF程序,当一起使用时,这些程序会创建更高级别的网络结构。
下面是Cilium使用的钩子列表以及简要概述。更详细的介绍可以参见BPF and XDP Reference Guide
XDP:XDP BPF钩子最早可以在网络驱动中使用,在报文接收时触发BPF程序。由于BPF程序能够(在进行其他处理前)直接作用于报文数据,因此能够获取最好的报文处理性能。该钩子可用于过滤程序丢弃恶意的或非期望的流量,以及其他常见的DDOS防护机制。
Ingress/Egress流控:与XDP相同,附加到tc(traffic control) ingress钩子的BPF程序会附加到网络接口上,但是在网络栈完成初始的报文处理之后运行。该钩子在协议栈的L3层之前运行,但可以访问与报文相关的大多数元数据,适用于本地节点的处理,如配置L3/L4 endpoint策略以及限制达到endpoints的流量。对于面向设备的网络,tc ingress钩子可以与上面的XDP钩子耦合。完成该操作后,可以合理地假设此时的大多数流量是合法的,并且目的地是主机。
容器通常会使用一个虚拟设备,称为veth对,可以看作是连接容器和主机的虚拟线路。通过连接到这对veth的主机侧的TC ingress钩子,Cilium可以监控和对一个容器中存在的所有流量强制执行制订的策略(在主机侧监控和限制本机的容器的流量)。通过将一个BPF程序附加到与每个容器关联的veth对上,然后使用另外一个附加到tc ingress钩子上的BPF程序将所有网络流量路由到主机侧的虚拟设备上,这样Cilium也可以监控和对到达本节点或节点中存在的流量强制执行制订的策略(在容器侧监控和限制本机的流量)。
根据场景的需要,容器也可能使用ipvlan设备进行连接。这种模式下,主机的物理设备作为ipvlan的master,容器中的虚拟ipvlan设备被设置为slave模式。使用ipvlan而不是veth对的好处是可以减少网络栈将报文推送到位于另一个网络命名空间中的ipvlan slave所需要的资源,因此可以获得更好的延迟结果。为了使用Cilium配置L3/L4 endpoint策略,需要将用于tc的BPF程序附加到容器网络命名空间中的ipvlan slave设备的tc egress钩子上。例如,与在ipvlan master的tc ingress钩子上运行的另一个BPF程序相结合,这样也可以限制节点上的传入流量。
socket操作:socket操作钩子附加到一个特定的cgroup上,根据TCP时间运行。Cilium将BPF socket操作程序附加到根cgroup上,并使用该程序监控TCP状态变更,特别是对ESTABLISHED 状态变更。当一个socket转换为ESTABLISHED 状态,如果TCP socket的对端位于本地节点上(可能是本地代理),则会附加socket 发送/接受程序。
socket 发送/接收:当一个TCP socket执行发送操作时会运行socket 发送/接受钩子。此时,钩子或检查消息,最终会丢弃该消息,会将该消息发送到TCP层,会直接将该消息重定向到另外一个socket。如下所述,Cilium使用它来加速数据路径的重定向。
将上述钩子与虚拟接口(cilium_host, cilium_net),可选的overlay接口(cilium_vxlan),Linux内核加密支持以及用户空间代理(Envoy)相结合,Cilium可以创建如下网络对象。
预过滤(prefilter):预过滤对象会运行一个XDP程序,并提供一组预过滤规则来过滤网络上的流量来达到更好的性能。特别使用一组Cilium agent提供的CIDR映射来查找报文,如在目的地不是一个有效的endpoint时丢弃报文,或允许网络栈处理该报文。可以很容易通过扩展来构建一个新的预过滤标准/能力。
endpoint策略:endpoint策略对象实现了Cilium endpoint的执行方式。它使用一个映射来查找与身份相关的报文,且该层(layer)可以很好地扩展到多个endpoint。取决于本层的策略,可能会丢弃报文,转发到本地的endpoint或服务对象,或转发到L7策略对象,用于后续L7规则。它是Cilium数据路径中负责报文和身份映射以及执行L3和L4策略的主要对象。
服务(service):服务对象会根据该对象接收到的每个报文的目的IP(可能包含目的端口)来进行映射查找。如果找到一个匹配的表项,则将该报文转发到一个配置到的L3/L4 endpoint上。服务块可以使用TC ingress钩子在任何接口上实现一个独立的负载均衡,或集成到endpoint策略对象中。
L3加密:在ingress上,可以使用L3加密对象标识需要解密的报文,然后将报文传递到Linux xfrm(转换)层进行解密,在解密报文后,该对象会接受报文,然后将报文传递到网络栈,后续给其他对象进行处理。根据网络的模式(直接路由或overlay),可能是BPF尾部调用或将数据包传递到下一个对象的Linux路由栈。解密需要的密钥编码在IPsec首部,这样我们不需要在ingress上使用映射查找来定位解密密钥。
在egress上,会首先对目的地址执行映射查找来缺点该报文是否被加密,如果被加密,则找出目的节点上可用的密钥。在选出的节点上挑选最近使用的可用的密钥,并将报文标记为加密。然后改报文会传递到Linux xfrm层执行加密。当接收到现在加密的报文时,它被传递到下一层,或通过发送到Linux 栈进行路由,或(如果正在使用overlay)直接执行尾部调用。
socket层强制(Enforcement):socket层强制会使用两个钩子,socket 操作钩子和socket 发送/接收钩子来监控并附加到所有与Cilium管理的endpoint相关的TCP socket,包括L7代理。socket操作钩子会识别要加速的候选套接字,这些候选套接字包括所有的本地节点连接(endpoint到endpoint)以及所有到Cilium代理的连接。这些标识的连接将会包含所有由socket 发送/接收钩子处理的消息,并且使用sockmap快速重定向进行加速。快速重定向保证Cilium中实现的所有策略对于关联的socket/endpoint映射均有效,并假设它们会直接向对端socket发送消息。sockmap send/recv钩子确保消息不会被上面提到的任何对象处理。
L7策略:L7策略对象将代理的流量重定向到一个Cilium用户空间代理实例中。Cilium使用一个Envoy作为它的用户空间代理。Envoy要么转发流量,要么会根据配置的L7策略生成拒绝消息。
Cilium通过连接这些组件实现了灵活高效的数据路径。下面将展示连接单个节点上的endpoint可能存在的数据流(进入一个endpoint以及endpoint到网络设备)。在每种情况下,都会通过一个额外的图显示启用socket层强制时的可用的TCP加速路径。
Endpoint到Endpoint
首先展示的是本地endpoint到endpoint的数据流,在engress和ingress上使用了L7策略。紧跟着展示了启用socket层强制下相同endpoint到endpoint的数据流走向。通过对TCP流量启用socket层强制,发起连接的握手将遍历endpoint策略对象,直到TCP的状态变为ESTABLISHED。最后只有L7策略对象允许之后,连接状态才能变为ESTABLISHED。
从Endpoint出站(Egress from Endpoint)
下面展示了本地endpoint使用overlay网络进行出站的场景。overlay网络流量通过与overlay对应的Linux网络接口进行转发。默认的overlay接口称为cilium_vxlan。与上面类似,通过启用socket层强制并使用L7代理可以避免在TCP通信的endpoint和L7策略之间运行endpoint策略块。L3加密块可以在启用时加密报文。
入站到Endpoint(Ingress to Endpoin)
最后展示了使用overlay网络时入站到endpoint的场景。与上面类似,通过启用socket层强制可以避免在代理和endpoint socket之间遍历策略集。如果接收到的报文被加密,则首先需要进行解密,并使用正常流程处理。
基于veth的数据路径和基于ipvlan的数据路径的对比
|基于ipvlan的数据路径目前仅在技术预览中,用于实验目的。该限制会在后续的Cilium发布中移除。
默认的Cilium CNI运行在基于veth的数据路径模式下,由于所有的BPF程序都由Cilium在主机网络命名空间之外进行管理,因此使用该模式可以获得更大的灵活性,这样容器就可以被授予其命名空间(如CAP_NET_ADMIN)的特权,而不会影响安全性(因为容器无法访问主机中的BPF强制点)。鉴于BPF程序是从主机的网络名称空间附加的,BPF也能够接管并有效地管理本地容器到主机之间的转发逻辑。但由于veth模式下,网络栈内部在处理从一个veth设备到位于另一个网络命名空间中的对端设备时需要重新遍历网络栈,因此会造成延迟。当在本地Cilium endpoint间进行通信时,这种出站到入站的转变需要执行两次,对于正在到达或从主机发送出去的数据包,则为一次。
对于更具延迟优化的数据路径,Cilium CNI还支持ipvlan L3/L3S模式,但存在大量限制。为了支持老的且不存在ipvlan发夹模式的内核,Cilium会在tc egress层将BPF程序附加到位于容器的网络命名空间内的slave设备上,意味着这种数据路径模式只能用于使用非CAP_NET_ADMIN 和CAP_NET_RAW特权运行的容器。ipvlan使用内部转发逻辑直接进行slave-to-slave或slave-to-master的重定向,因此BPF程序本身不会执行到设备的转发。由于网络栈不需要像基于veth的数据路径一样在处理外部报文时重新遍历,因此能够更有效地切换命名空间。主机到容器网络命名空间的切换直接发生在L3层,在后续的ingress处理中无需排队和重新调度。在本地endpoint之间通信的情况下,会执行一次egress-to-ingress的且华北,而不必执行两次。
目前的实现中,Cilium的ipvlan模式还有很多限制需要在接下来的工作中解决:目前还无法启用NAT64以及通过代理启用L7策略强制。当前未启用到本地endpoint的服务负载平衡以及容器到主机的本地通信。如果需要使用这些功能,仅以使用基于veth的数据路径模式。
Cilium的CNI ipvlan模式运行在Cilium daemon中,例如--datapath-mode=ipvlan --ipvlan-master-device=bond0
,后者通常指定了物理网络设备,同时也作为ipvlan的master设备。注意在ipvlan 数据路径模式在kubernetes中部署在L3S模式下。确保有一个稳定运行内核,包括以下ipvlan修复:d5256083f62e。
更多BPF的特性参见 BPF and XDP Reference Guide,可以在 Envoy 章节了解如何扩展L7策略。
BPF 映射的限制
所有创建的BPF映射都有上限限制。超出限制的插入将会失败,从而限制了数据路径的可伸缩性。下表展示了映射的默认值。每个限制都可以在源代码中进行修改,如果需要,可以根据请求添加配置选项。
Map Name | Scope | Default Limit | Scale Implications |
---|---|---|---|
Connection Tracking | node or endpoint | 1M TCP/256K UDP | Max 1M concurrent TCP connections, max 256K expected UDP answers |
Endpoints | node | 64k | Max 64k local endpoints + host IPs per node |
IP cache | node | 512K | Max 256K endpoints (IPv4+IPv6), max 512k endpoints (IPv4 or IPv6) across all clusters |
Load Balancer | node | 64k | Max 64k cumulative backends across all services across all clusters |
Policy | endpoint | 16k | Max 16k allowed identity + port + protocol pairs for specific endpoint |
Proxy Map | node | 512k | Max 512k concurrent redirected TCP connections to proxy |
Tunnel | node | 64k | Max 32k nodes (IPv4+IPv6) or 64k nodes (IPv4 or IPv6) across all clusters |
kubernetes集成
下图显示了kube-proxy安装的iptables规则和Cilium安装的iptables规则的集成。
Cilium架构 (Cilium 2)的更多相关文章
- Cilium使用 (Cilium 3)
使用k3s测试Cilium,安装步骤可以参见官方文档 Cilium安装使用 docker安装 使用如下命令安装最新版本的docker yum install -y yum-utils \ device ...
- Cilium 1.11 发布,带来内核级服务网格、拓扑感知路由....
原文链接:https://isovalent.com/blog/post/2021-12-release-111 作者:Cilium 母公司 Isovalent 团队 译者:范彬,狄卫华,米开朗基杨 ...
- eBPF Cilium实战(1) - 基于团队的网络隔离
在 Rainbond 集群中,每个团队对应于底层 Kubernetes 的一个 Namespace ,由于之前使用的底层网络无法进行 Namespace 级别的网络管理,所以在 Rainbond 同一 ...
- eBPF Cilium实战(2) - 底层网络可观测性
在之前的平台中,对于组件之间的网络流向不具备直接的可观测性,用户组件间通信出现问题,只能通过传统命令行工具进行手动排查,而 cilium 的 Hubble 服务可以提供 UI 界面向用户展示实时的流量 ...
- 腾讯云TKE-基于 Cilium 统一混合云容器网络(下)
前言 在 腾讯云TKE - 基于 Cilium 统一混合云容器网络(上) 中,我们介绍 TKE 混合云的跨平面网络互通方案和 TKE 混合云 Overlay 网络方案.公有云 TKE 集群添加第三方 ...
- 使用containerlab搭建cilium BGP环境解析
使用 Containerlab + Kind 快速部署 Cilium BGP 环境一文中使用Containerlab和Cilium实现了模拟环境下的Cilium BGP网络.它使用Containerl ...
- kubernetes-整体概述和架构
1.Kubernetes是什么 Kubernetes是一个轻便的和可扩展的开源平台,用于管理容器化应用和服务.通过Kubernetes能够进行应用的自动化部署和扩缩容.在Kubernetes中,会将组 ...
- kubernetes架构和组件
一.Kubernetes整体架构 Kubernetes属于主从分布式架构,主要由Master Node和Worker Node组成,以及包括客户端命令行工具kubectl和其它附加项. Master ...
- k8s-整体概述和架构
1.Kubernetes是什么 Kubernetes是一个轻便的和可扩展的开源平台,用于管理容器化应用和服务.通过Kubernetes能够进行应用的自动化部署和扩缩容.在Kubernetes中,会将组 ...
随机推荐
- scrapy框架Request函数callback参数为什么是self.parse而不是self.parse( )
加括号是调用函数,不加括号是指的是函数地址,此处只需要传入函数的地址,等待程序到时调用即可
- Journal of Proteome Research | Single-Shot Capillary Zone Electrophoresis−Tandem Mass Spectrometry Produces over 4400 Phosphopeptide Identifications from a 220 ng Sample (分享人:赵伟宁)
Title: Single-Shot Capillary Zone Electrophoresis−Tandem Mass Spectrometry Produces over 4400 Phosph ...
- Gogs
Deploy Gogs(node2) 1 create gogs account sudo adduser git su git cd /home/git mkdir /home/git/.ssh 2 ...
- 第十五周java实验作业
实验十五 GUI编程练习与应用程序部署 实验时间 2018-12-6 1.实验目的与要求 (1) 掌握Java应用程序的打包操作: Java程序的打包,程序编译完成后,程序员将.class文件压缩打 ...
- CF1324A Yet Another Tetris Problem 题解
原题链接 简要题意: 再简要一波: 每次可以把一个数增加 \(2\),问最后能不能让所有数相等.(也就是抵消掉) 什么?题意变成这样子还做个啥? 你会发现,必须所有数的奇偶性都相同,才可以:反之就不可 ...
- C#面向对象--索引器
一.索引器(Indexer)允许类和结构的实例像数组一样通过索引取值,可以看做是对[]运算符的重载,索引器实际上就是有参数的属性,也被称为有参属性或索引化属性,其声明形式与属性相似,不同之处在于索引器 ...
- 《JavaScript 模式》读书笔记(5)— 对象创建模式2
这一篇,我们主要来学习一下私有属性和方法以及模块模式. 三.私有属性和方法 JavaScript并没有特殊的语法来表示私有.保护.或公共属性和方法,在这一点上与Java或其他语言是不同的.JavaSc ...
- IO多路复用(IO Multiplexing)
什么是IO多路复用 为什么要有IO多路复用 作者总结 遵循学习新知识的三部曲:是什么?为什么?怎么用? 作者前言:IO多路复用本质上是网络通信过程中的一个技术名词. 什么是IO多路复用 一个用机场管理 ...
- Jupyter Notebook自动补全
大多数程序员都非常熟悉不同的自动补全工具.然而,我注意到许多数据科学家还没有使用它.如果你是他们中的一员,是时候开始使用这个提高效率的工具了 什么是自动补全? 它是你的编程环境提供的一种功能,用于完成 ...
- 在Fedora中安装OpenCV-Python | 二
目标 在本教程中 我们将学习在你的Fedora系统中设置OpenCV-Python.针对Fedora 18(64位)和Fedora 19(32位)进行以下步骤. 介绍 可以通过两种方式在Fedora中 ...