Istio Ambient 成熟度:跨各种 Kubernetes 提供商和 CNI 的兼容性

工作负载 Pod 和 ztunnel 之间创新的流量重定向机制。

2024 年 1 月 29 日 | 作者:Ben Leggett - Solo.io,Yuval Kohavi - Solo.io,Lin Sun - Solo.io

Istio 项目于 2022 年宣布了 Ambient Mesh——其新的无 Sidecar 数据面模式,并在 2023 年初发布了 Alpha 版本的实现

我们的 Alpha 版本专注于在有限的配置和环境下证明 Ambient 数据面模式的价值。但是,当时的条件非常有限。Ambient 模式依赖于在工作负载 Pod 和ztunnel之间透明地重定向流量,而我们最初使用的实现机制与多类第三方容器网络接口 (CNI) 实现存在冲突。通过 GitHub 问题和 Slack 讨论,我们了解到用户希望能够在minikubeDocker Desktop上使用 Ambient 模式,并与CiliumCalico等 CNI 实现配合使用,以及在使用内部 CNI 实现的服务上使用,例如OpenShiftAmazon EKS。要实现 Ambient Mesh 进入 Beta 阶段,最关键的要求是获得广泛的 Kubernetes 支持——人们已经习惯了 Istio 能够在任何 Kubernetes 平台上与任何 CNI 实现配合使用。毕竟,Ambient 只有在你周围无处不在时才称得上是 Ambient!

在 Solo,我们一直在将 Ambient 模式集成到我们的 Gloo Mesh 产品中,并为此问题找到了一个创新的解决方案。我们决定在 2023 年底将我们的更改提交到上游,以帮助 Ambient 更快地进入 Beta 阶段,以便更多用户可以在 Istio 1.21 或更高版本中运行 Ambient,并在其平台上享受 Ambient 无 Sidecar 网格带来的好处,而无论其现有或首选的 CNI 实现是什么。

我们是如何走到这一步的?

服务网格和 CNI:情况复杂

Istio 是一个服务网格,并且严格意义上讲,所有服务网格都不是CNI 实现——服务网格需要每个 Kubernetes 集群中都存在符合规范的主 CNI 实现,并且建立在其之上。

此主 CNI 实现可以由您的云提供商提供(AKS、GKE 和 EKS 都自带自己的 CNI),也可以由 Calico 和 Cilium 等第三方 CNI 实现提供。某些服务网格也可能捆绑了自己的主 CNI 实现,并且明确要求其正常运行。

基本上,在您执行诸如使用 mTLS 保护 Pod 流量并在服务网格层应用高级身份验证和授权策略等操作之前,必须拥有一个功能齐全的 Kubernetes 集群和一个功能齐全的 CNI 实现,以确保设置了基本的网络路径,以便数据包可以在集群中的一个 Pod 与另一个 Pod 之间(以及一个节点与另一个节点之间)传输。

尽管某些服务网格也可能附带并需要其自己的内部主 CNI 实现,并且有时可以在同一个集群中并行运行两个主 CNI 实现(例如,一个由云提供商提供,另一个由第三方提供),但在实践中,这会引入大量兼容性问题、异常行为、功能集减少以及由于每个 CNI 实现内部可能采用的机制差异巨大而导致的某些不兼容性。

为了避免这种情况,Istio 项目选择不附带或要求我们自己的主 CNI 实现,甚至不要求“首选”的 CNI 实现——而是选择支持与尽可能广泛的 CNI 实现生态系统进行 CNI 链式操作,并确保与托管产品、跨供应商支持以及与更广泛的 CNCF 生态系统的可组合性。

Ambient Alpha 中的流量重定向

istio-cni组件是 Sidecar 数据面模式中的可选组件,通常用于消除用户将 Pod 部署到网格中时对 NET_ADMINNET_RAW 功能的需求istio-cni 是 Ambient 数据面模式中的必需组件。istio-cni 组件不是主 CNI 实现,它是一个节点代理,扩展了集群中已存在的任何主 CNI 实现。

每当将 Pod 添加到 Ambient 网格时,istio-cni 组件都会通过节点级网络命名空间配置所有传入和传出流量在 Pod 和 Pod 节点上运行的ztunnel之间的流量重定向。Sidecar 机制和 Ambient Alpha 机制之间的关键区别在于,在后者中,Pod 流量会从 Pod 网络命名空间重定向到与其位于同一节点的 ztunnel Pod 网络命名空间——必然会通过主机网络命名空间,而实现此目的的大部分流量重定向规则都实现在此处。

当我们在多个现实世界的 Kubernetes 环境中进行更广泛的测试时(这些环境具有自己的默认 CNI),很明显,像我们在 Alpha 开发期间那样在主机网络命名空间中捕获和重定向 Pod 流量将无法满足我们的要求。使用这种方法在这些不同的环境中以通用的方式实现我们的目标根本不可行。

在主机网络命名空间中重定向流量的根本问题在于,这正是集群的主 CNI 实现必须配置流量路由/网络规则的位置。这会导致不可避免的冲突,最关键的是

虽然我们可以针对某些主 CNI 实现逐个案例进行设计,但我们无法持续地实现通用 CNI 支持。我们考虑过 eBPF,但意识到任何 eBPF 实现都将存在相同的基本问题,因为目前还没有标准化的方法可以安全地链式操作/扩展任意 eBPF 程序,并且使用这种方法,我们仍然可能难以支持非 eBPF CNI。

应对挑战

需要一种新的解决方案——在节点的网络命名空间中执行任何类型的重定向都会导致不可避免的冲突,除非我们降低兼容性要求。

在 Sidecar 模式下,配置 Sidecar 和应用程序 Pod 之间的流量重定向非常简单,因为两者都在 Pod 的网络命名空间中运行。这让我们灵光一闪:为什么不模仿 Sidecar,并在应用程序 Pod 的网络命名空间中配置重定向呢?

虽然这听起来像是一个“简单”的想法,但它怎么可能实现呢?Ambient 的一个关键要求是 ztunnel 必须在应用程序 Pod 之外,在 Istio 系统命名空间中运行。经过一番研究,我们发现一个在某个网络命名空间中运行的 Linux 进程可以在另一个网络命名空间中创建和拥有侦听套接字。这是 Linux 套接字 API 的基本功能。但是,为了使其在操作上有效并涵盖所有 Pod 生命周期场景,我们必须对 ztunnel 以及 istio-cni 节点代理进行架构更改。

在原型设计和充分验证这种新颖的方法确实适用于我们能够访问的所有 Kubernetes 平台后,我们对这项工作充满信心,并决定将这种新的流量重定向模型贡献到上游,这是一种在工作负载 Pod 和从头开始构建的 ztunnel 节点代理组件之间在 Pod 内的流量重定向机制,旨在与所有主要云提供商和 CNI 具有高度的兼容性。

关键创新在于将 Pod 的网络命名空间传递给与其位于同一节点的 ztunnel,以便 ztunnel 可以在 Pod 的网络命名空间内部启动其重定向套接字,同时仍运行在 Pod 之外。使用这种方法,ztunnel 和应用程序 Pod 之间的流量重定向方式与当今 Sidecar 和应用程序 Pod 非常相似,并且对节点网络命名空间中运行的任何 Kubernetes 主 CNI 完全不可见。无论 CNI 是否使用 eBPF 或 iptables,网络策略都可以继续由任何 Kubernetes 主 CNI 执行和管理,而不会发生任何冲突。

Pod 内流量重定向的技术深入

首先,让我们了解一下 Kubernetes 中数据包如何在 Pod 之间传输的基本原理。

Linux、Kubernetes 和 CNI——什么是网络命名空间,为什么它很重要?

在 Linux 中,容器是指在一个或多个隔离的 Linux 命名空间中运行的一个或多个 Linux 进程。Linux 命名空间只是一个内核标志,它控制在该命名空间中运行的进程能够看到什么。例如,如果您通过 ip netns add my-linux-netns 命令创建一个新的 Linux 网络命名空间并在其中运行一个进程,则该进程只能看到在该网络命名空间中创建的网络规则。它无法看到在其外部创建的任何网络规则——即使该机器上的所有内容仍然共享一个 Linux 网络堆栈。

从概念上讲,Linux 命名空间非常类似于 Kubernetes 命名空间——用于组织和隔离不同活动进程的逻辑标签,并允许您创建有关给定命名空间内的内容可以查看什么以及对其应用哪些规则的规则——它们只是在更低的级别上运行。

当在网络命名空间中运行的进程创建了一个发往其他内容的 TCP 数据包时,该数据包必须首先由本地网络命名空间中的任何本地规则处理,然后离开本地网络命名空间,进入另一个命名空间。

例如,在没有安装任何网格的普通 Kubernetes 中,一个 Pod 可能会创建一个数据包并将其发送到另一个 Pod,并且该数据包可能会(取决于网络的设置方式)

在 Kubernetes 中,容器运行时接口 (CRI) 负责与 Linux 内核通信,为新的 Pod 创建网络命名空间,并在其中启动进程。然后,CRI 调用 容器网络接口 (CNI),后者负责连接各个 Linux 网络命名空间中的网络规则,以便进入和离开新 Pod 的数据包能够到达其目标位置。Kubernetes 或容器运行时并不关心 CNI 使用什么拓扑结构或机制来实现这一点——只要数据包到达了它们应该到达的地方,Kubernetes 就能正常工作,每个人都感到满意。

我们为什么放弃了之前的模型?

在 Istio 环境网格中,每个节点至少运行两个容器作为 Kubernetes DaemonSet。

在之前的环境网格实现中,应用程序 Pod 是这样添加到环境网格中的。

这意味着,对于环境网格中 Pod 创建的数据包,该数据包将离开源 Pod,进入节点的主机网络命名空间,然后理想情况下会被拦截并重定向到该节点的 ztunnel(在其自己的网络命名空间中运行)以代理到目标 Pod,返回路径也类似。

此模型作为初始环境网格 alpha 实现的占位符效果足够好,但如前所述,它存在一个根本问题——有许多 CNI 实现,并且在 Linux 中,有许多从根本上不同且不兼容的方式可以配置数据包如何从一个网络命名空间到另一个网络命名空间。您可以使用隧道、覆盖网络、通过主机网络命名空间或绕过它。您可以通过 Linux 用户空间网络堆栈,也可以跳过它并在内核空间堆栈中来回传送数据包,等等。对于每种可能的方法,可能都存在一个 CNI 实现来利用它。

这意味着,使用以前的重定向方法,有很多 CNI 实现环境网格根本无法与之配合使用。鉴于它依赖于主机网络命名空间数据包重定向——任何不通过主机网络命名空间路由数据包的 CNI 都需要不同的重定向实现。即使对于确实执行此操作的 CNI,我们也会遇到不可避免且可能无法解决的主机级规则冲突问题。我们是在 CNI 之前还是之后拦截?如果我们执行其中一项操作,某些 CNI 会不会崩溃,而它们没有预料到这一点?由于必须在主机网络命名空间中执行 NetworkPolicy,因此 NetworkPolicy 在哪里以及何时执行?我们需要大量代码来专门处理每个流行的 CNI 吗?

Istio 环境流量重定向:新模型

在新环境模型中,应用程序 Pod 是这样添加到环境网格中的。

这是一个基本图表,显示了将应用程序 Pod 添加到环境网格中的流程。

pod added to the ambient mesh flow

一旦 Pod 成功添加到环境网格中,默认情况下,网格中 Pod 之间的流量将始终使用 mTLS 进行完全加密,就像 Istio 一样。

流量现在将作为加密流量进入和离开 Pod 网络命名空间——它看起来像环境网格中的每个 Pod 都能够执行网格策略并安全地加密流量,即使 Pod 中运行的用户应用程序对两者都不了解。

这是一个图表,说明了在新模型中环境网格中 Pod 之间的加密流量是如何流动的。

HBONE traffic flows between pods in the ambient mesh

并且,像以前一样,来自网格外部的未加密明文流量仍然可以处理和执行策略,用于需要这种情况的用例。

Plain text traffic flow between meshed pods

新的环境流量重定向:这对我们有什么好处

新的环境捕获模型的最终结果是,所有流量捕获和重定向都在 Pod 的网络命名空间内发生。对于节点、CNI 和所有其他内容,它看起来像 Pod 内有一个 sidecar 代理,即使Pod 中根本没有运行 sidecar 代理。请记住,CNI 实现的工作是将数据包传送到和传出 Pod。根据设计和 CNI 规范,它们不关心数据包在该点之后的处理方式。

这种方法自动消除了与各种 CNI 和 NetworkPolicy 实现的冲突,并极大地提高了 Istio 环境网格与所有主要托管 Kubernetes 产品(跨所有主要 CNI)的兼容性。

总结

感谢我们可爱的社区投入大量精力,使用各种 Kubernetes 平台和 CNI 测试更改,以及 Istio 维护人员的多轮审查,我们很高兴地宣布,实现此功能的 ztunnelistio-cni PR 已合并到 Istio 1.21 中,并且默认情况下对环境启用,因此 Istio 用户可以开始在任何 Kubernetes 平台上使用任何 CNI 在 Istio 1.21 或更高版本中运行环境网格。我们已使用 GKE、AKS 和 EKS 及其提供的所有 CNI 实现进行了测试,以及 Calico 和 Cilium 等第三方 CNI,以及 OpenShift 等平台,结果非常可靠。

我们非常高兴能够通过 ztunnel 和用户应用程序 Pod 之间这种创新的 Pod 内流量重定向方法,推动 Istio 环境网格向前发展,使其能够在任何地方运行。随着环境 Beta 版面临的这一顶级技术障碍得到解决,我们迫不及待地想要与 Istio 社区的其他成员一起尽快将环境网格推向 Beta 版!要了解有关环境网格 Beta 版进展的更多信息,请加入 Istio 的 Slack 中的 #ambient 和 #ambient-dev 频道,或参加每周三举行的 环境贡献者会议,或者查看环境网格 Beta 版 项目看板 并帮助我们修复某些问题!

分享此帖子