该博客描述了 Cilium 如何在不使用 Sidecar 的情况下提供服务网格。在这篇博客中,我们将扩展 mTLS 的主题,并研究 Cilium 如何提供具有出色安全性和性能特征的基于 mTLS 的无边车身份验证。
相互身份验证一直是安全的基石,我们每天都在使用 SSH、mTLS 或 IPsec 等协议和技术来解决安全问题。最近的一个发展是希望使用强大的相互身份验证来保护 Kubernetes 和云原生基础架构中的服务到服务通信。在这篇博文中,我们将研究 Cilium 和 Cilium Service Mesh 如何利用 eBPF 为具有高性能数据平面的服务提供基于身份的相互身份验证的新方法,该数据平面可以支持任何网络协议、进程、二进制文件,而无需更改应用程序或注入 sidercar。
相互身份验证是发送方和接收方两方的过程,它们相互验证对方的身份,以确保他们都在与他们打算与之通信的一方交谈。这不应与完整性和机密性相混淆。完整性确保交换的消息没有被篡改。机密性确保消息保持机密。人们通常认为“加密”可以保证这三个方面,但它们可以而且确实是分开来的。事实上,我们每天都使用 TLS 来实现机密性、完整性和服务器身份验证,但通常不依赖相互身份验证,即 TLS 会话确保我们与正确的服务器通信,但我们随后依赖密码或不同的顶部的身份验证形式,以使用 Web 服务对自己进行身份验证。
相互身份验证通常使用公钥和私钥对或单个共享密钥来实现。两种形式都依赖于使用加密消息执行握手。下面是 TLS 1.3 握手的示例:
通过握手建立通信任一端的身份后,将设置加密通道以在 TLS 会话期间在这两个身份之间传输数据。
Mutual TLS 或 mTLS 是一种众所周知的实现相互身份验证的加密流量的方法,但它不是唯一的方法。IPsec 使用 IKE(Internet 密钥交换)作为握手,对通信任一端的节点端点进行身份验证,然后在它们之间创建加密数据连接。
相互认证的一个关键方面是身份的粒度,即分发身份和证书的粒度。例如,考虑身份证件(如护照)的示例,可以为每个家庭成员分发单独的护照,为居住在同一家庭的每个人合办一本护照,甚至可以识别居住在同一城镇的每个人的单一护照. 根据您为识别选择的粒度,可以执行不同级别的身份验证。
网络通信基于映射粒度的概念,我们可以看到执行相互认证的两种典型模式:会话认证和基于网络的认证。
如果我们将身份验证握手与负载传输分开,我们可以使用 TLS 1.3 作为握手协议,同时依赖 IPsec 或 WireGuard 作为性能更好、更透明的负载通道:
我们获得了这两种模型的好处并实现了许多出色的特性:
上图并排显示了两个模型。左边是传统的基于 sidecar 的 mTLS 方法,依靠 sidecar 将 TLS 注入每个连接。右侧显示了无边车方法,有效负载连接保持不变,而 TLS 身份验证由 Cilium 单独驱动,同时借助 eBPF 控制有效负载连接。
Cilium 用于识别服务和实施网络策略的内置身份概念是集成高级身份和证书管理(如 SPIFFE、Vault、SMI、cert-manager 或 Istio)的完美基础。这允许这些现有的身份和证书管理层用于管理服务身份和生成证书。然后,这些证书用于执行代表 pod 或外部工作负载(VM、金属机器等)的 Cilium 身份之间的相互身份验证。
让我们从配置的角度看一下上面的样子。我们将使用即将到来的 SPIFFE 与 Cilium 集成的示例。这允许在创建网络策略时使用 SPIFFE 身份来选择工作负载。
apiVersion: 'cilium.io/v2'
kind: CiliumNetworkPolicy
metadata:
name: 'auth-rule-spiffe-app1'
spec:
endpointSelector:
- matchLabels:
- spiffe://mycluster/app1: ''
ingress:
- fromEndpoints:
- matchLabels:
- spiffe://mycluster/app2: ''
如上例所示,网络策略通过 SPIFFE 身份指定允许的端点集。这使得采用基于端点选择器的现有策略变得非常简单,并强化它们以使用基于证书的身份。
值得注意的是,服务层面的相互认证并不是简单地取代网络层的网络策略。它增加了额外的安全层。Cilium 仍然像今天一样识别单个端点,并且网络分段仍然适用于这些单个端点。如果网络策略同时指定 SPIFFE 身份和端点选择器,这能够有效阻断恶意流量负载。
所有这些额外的安全性将如何影响性能?以下是在 GKE 上运行的 Cilium 与 nighthawk 在不同模型中进行 HTTP 基准测试的测量结果:
所有流量的加密都需要计算成本。更少的计算可用于创建和处理请求,因此延迟会受到影响。但是,使用 sidecar 模型注入 mTLS 对延迟的影响要大得多。在 sidecar 模型中,TCP 连接必须终止并重新启动两次——每个代理一次——这对整体延迟有很大影响。基于 WireGuard 的完整性和机密性实施可提供 3.5 倍的延迟。
关于可以实现的请求数/秒,可以看到类似的影响。使用 WireGuard 的 Cilium 比使用 Istio 部署的 mTLS sidecar 模型高出约 2 倍。
可以在这个 github https://github.com/jtaleric/cilium-testplan-proposal/blob/master/test-plans/performance/draft-servicemesh-performance.md
中找到重现性能基准的脚本。
由于 Cilium 服务网格在 1.12 版本中被标记为稳定版,这种相互认证架构是 Cilium 服务网格关注的下一个关注点。我们相信,我们不仅可以与现有的身份管理解决方案(如 SPIFFE、cert-manager 甚至 Istio 作为控制平面)实现高度集成,而且还可以提供更优雅、更高性能和更安全的身份验证实现以及出色的数据路径属性。与 NetworkPolicy 的紧密集成提供了一种简单易用但高度安全的通信模式,可防止网络模拟和服务身份盗用。鉴于我们已经具备了所有基础,我们预计这种相互身份验证功能将在 1.13 中可用。