暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

[译文] Cassandra:让您的数据库超越单个 Kubernetes 集群

原创 Christopher Bradford 2022-04-24
742

全球应用程序需要一个与它们所服务的用户一样分布的数据层。Apache Cassandra已应对这一挑战,为 Apple、Netflix 和 Sony 等公司处理数据需求。传统上,分布式应用程序的数据层管理由专门的团队处理,以管理数千个节点的部署和操作——无论是在本地还是在云中。

为了减轻 DevOps 团队感受到的大部分负担,我们在 K8ssandra 中改进了许多这些实践和模式利用Kubernetes (K8s) 提供的通用控制平面。不过有一个问题——运行数据库(或实际上任何应用程序)如果没有适当的照顾和预先计划,跨多个区域或 K8s 集群是很棘手的。

为了向您展示我们是如何做到这一点的,让我们首先查看在单独的 K8s 集群上运行的单个区域 K8ssandra 部署。它由分布在该区域内三个可用区的六个 Cassandra 节点组成,每个可用区内有两个 Cassandra 节点。在此示例中,我们将使用Google Cloud Platform (GCP) 区域名称。但是,我们这里的示例可以很容易地应用于其他云甚至本地。

这是我们现在的位置:

我们的云数据库的现有部署

目标是拥有两个区域,每个区域都有一个 Cassandra 数据中心。在我们这里的云管理 K8s 部署中,这转化为两个 K8s 集群——每个集群都有一个单独的控制平面,但使用一个通用的虚拟私有云 (VPC) 网络。通过将我们的 Cassandra 集群扩展到多个数据中心,我们可以在区域中断的情况下获得冗余,并在本地访问数据的情况下改善客户端应用程序的响应时间和延迟。

这是我们的目标:拥有两个区域,每个区域都有自己的 Cassandra 数据中心。

从表面上看,我们似乎可以通过简单地启动另一个部署相同 K8s YAML的 K8s 集群来实现这一点。然后只需为可用区名称添加一些调整,我们就可以称之为完成,对吧?最终资源的形状非常 相似,都是 K8s 对象。那么,这不应该有效吗?好吧,也许根据您的环境,这种方法可能会奏效。

如果你真的很幸运,你可能是远离完全分布式数据库部署的防火墙规则。不幸的是,它很少那么简单。即使其中一些障碍很容易清除,还有许多其他无害的事情可能会出错并导致降级状态。您选择的云提供商、K8s 发行版、命令行标志,是的,甚至是 DNS——这些都可能导致您走上一条黑暗而暴风雨的道路。因此,让我们探讨一些您可能遇到的最常见问题,以便您可以避免它们。

规模竞赛的常见障碍

即使您的某些部署最初看起来运行良好,但当您成长为多云环境、升级到另一个 K8s 版本或开始使用不同的发行版和免费工具时,您可能会遇到一两个障碍。当涉及到分布式数据库时,幕后还有很多。了解 K8s 为在一组硬件中运行容器所做的工作将帮助您开发高级解决方案,最终开发出适合您确切需求的解决方案。

Cassandra 节点需要唯一 IP 地址

您可能遇到的第一个障碍涉及基本网络。回到我们的第一个集群,让我们看一下所涉及的网络层。

在下面显示的 VPC 中,我们有一个无类域间路由 (CIDR) 范围,表示 K8s 工作程序实例的地址。在 K8s 集群范围内,有一个单独的地址空间供 pod 运行和容器运行。Pod 是具有共享资源的容器的集合,例如存储、网络和进程空间。

在某些云环境中,这些子网与特定的可用区相关联。因此,您的 K8s 工作线程启动到的每个子网可能都有一个 CIDR 范围。您的 VPC 中可能还有其他虚拟机,但在此示例中,我们将坚持使用 K8s 作为唯一租户。

具有 K8s 层的 VPC 使用的 CIDR 范围

在我们的示例中,节点为 10.100.xx,K8s 级别为 10.200.xx。每个 K8s 工作人员都会获得 10.200.xx CIDR 范围的一部分,用于在该单独实例上运行的 pod。

回想一下我们的目标结构,如果两个集群使用相同或重叠的 CIDR 地址范围会发生什么?首次进入网络时,您可能会记得这些错误消息:

尝试连接两个网络时的常见错误消息

K8s 的错误看起来不像这样。您没有弹出警告您的集群无法有效通信的警报。

如果您有一个具有一个 IP 空间的集群,然后您有另一个用于相同 IP 空间或它们重叠的集群,每个集群如何知道特定数据包何时需要离开其地址空间并通过 VPC 网络路由到另一个集群,然后进入该集群的网络?

默认情况下,这里确实没有提示。有一些方法可以解决这个问题;但在高层次上,如果你重叠,你要求的时间很糟糕。这里的重点是您需要了解每个集群的地址空间,然后仔细规划这些 IP 的分配和使用。这允许 Linux 内核(K8s 路由发生的地方)和 VPC 网络层根据需要转发和路由数据包。

但是,如果您没有足够的 IP 怎么办?在某些情况下,您不能为每个 pod 提供自己的 IP 地址。因此,在这种情况下,您需要退后一步,确定哪些服务绝对必须具有唯一地址,以及哪些服务可以在同一地址空间中一起运行。例如,如果您的数据库需要能够与每个其他 pod 通信,它可能需要自己的唯一地址。但是,如果您在东海岸和西海岸的应用程序层只是与他们的本地数据层通信,他们可以拥有自己的专用 K8s 集群,地址范围相同,避免冲突。

扁平化网络

在我们的参考部署中,我们将 K8s 集群中的非重叠范围专用于基础设施层,这些基础设施必须是唯一的,并且服务不会通信的重叠 CIDR 范围。最终,我们在这里所做的是扁平化网络。

有了不重叠的 IP 范围,我们现在可以继续将数据包路由到每个集群中的 pod。在上图中,您可以看到西海岸为 10.100,东海岸为 10.150,K8s pod 接收来自这些范围的 IP。K8s 集群有自己的 IP 空间,200 对 250,并且 pod 像以前一样被分割。

如何处理 Cassandra 数据中心之间的路由

因此,我们有一堆 IP 地址,并且我们对这些地址具有唯一性。现在,我们如何处理这些数据的路由以及所有这些的通信和发现?发往集群 A 的数据包无法知道它们需要如何路由到集群 B。当我们尝试跨集群边界发送数据包时,本地 Linux 网络堆栈发现这不是该主机或任何主机本地的本地 K8s 集群中的主机。然后它将数据包转发到 VPC 网络。从这里开始,我们的云提供商必须有一个路由表条目来了解这个数据包需要去哪里。

在某些情况下,这将开箱即用。VPC 路由表使用 pod 和服务 CIDR 范围进行更新,告知应路由哪些主机数据包。在其他环境中,包括混合环境和本地环境,这可能采取通过 BGP 向网络层通告路由的形式。

但是,这些选项可能并不总是最好的答案,这取决于您的多集群架构在单个云提供商中的样子。它是混合云还是多云,结合了本地和两个不同的云提供商?虽然您当然可以在所有这些不同的环境中检测所有这些,但您可以指望它需要大量时间和维护。

一些需要考虑的解决方案

覆盖网络

一个更简单的答案是使用覆盖网络,您可以在其中为您的应用程序构建一个单独的 IP 地址空间——在这种情况下,它是一个 Cassandra 数据库。然后,您将在现有的 Kube 网络上运行它,利用代理、边车和网关。在这篇文章中,我们不会深入探讨,但我们有一些关于如何跨 K8s 集群连接有状态工作负载的精彩内容,这些内容将向您展示如何从高层次上做到这一点。

下一个是什么?数据包在流动,但现在您需要处理一些新的 K8s 恶作剧。假设您的网络就位并拥有所有适当的路由,那么这些集群之间存在一些连接,至少在 IP 层是这样。您拥有 IP 连接 Pod,并且集群 1 可以与 Pod 和集群 2 通信,但您现在还需要考虑一些新的事情。

服务发现

使用 K8s 网络,身份是短暂的。由于集群事件,Pod 可能会被重新调度并接收新的网络地址。在某些应用程序中,这不是问题。在其他情况下,比如数据库,网络地址就是身份——这可能导致意外行为。尽管 IP 地址可能会发生变化,但随着时间的推移,我们的存储以及每个 pod 所代表的数据都会保持不变。我们必须有一种方法来维护地址到应用程序的映射。这就是服务发现发挥作用的地方。

在大多数情况下,服务发现是通过 K8s 中的 DNS 实现的。即使 pod 的 IP 地址可能发生变化,它也可以具有基于 DNS 的持久身份,该身份会随着集群事件的发生而更新。这听起来不错,但是当我们进入多集群的世界时,我们必须确保我们的服务可以跨集群边界被发现。作为集群 1 中的 pod,我应该能够获取集群 2 中的 pod 的地址。

DNS 存根

解决这个难题的一种方法是 DNS 存根。在此配置中,我们将 K8s DNS 服务配置为将特定域后缀的请求路由到我们的远程集群。有了完全限定的域名,我们就可以将 DNS 查找请求转发到适当的集群进行解析并最终路由。

这里的问题是每个集群都需要通过 kubelet 标志设置一个单独的 DNS 后缀,这不是所有 K8s 风格的选项。一些用户通过使用命名空间名称作为 FQDN 的一部分来配置存根来解决此问题。这行得通,但有点像 hack,而不是设置正确的集群后缀。

托管 DNS

另一种类似于 DNS 存根的解决方案是使用托管 DNS 产品。在 GCP 的情况下,有Cloud DNS产品,它将本地 DNS 条目复制到 VPC 级别,以供外部集群甚至同一 VPC 中的虚拟机解析。此选项提供了很多好处,包括:

  • 消除管理集群托管 DNS 服务器的开销——云 DNS 不需要扩展、监控或管理 DNS 实例,因为它是托管的 Google 服务。
  • 每个 Google K8s 引擎 (GKE) 节点上的 DNS 查询本地解析 — 与 NodeLocal DNSCache 类似,Cloud DNS 在本地缓存 DNS 响应,提供低延迟和高可扩展性的 DNS 解析。
  • 与Google Cloud 的操作套件集成——这提供了 DNS 监控和日志记录。
  • VPC 范围 DNS — 提供多集群、多环境和 VPC 范围的 K8s 服务解析。

用于多集群服务发现的复制托管 DNS

Cloud DNS 抽象出您将拥有的许多传统开销。云提供商将管理扩展、监控和安全补丁,以及您期望从托管产品中获得的所有其他方面。使用 GKE 提供节点本地 DNS 缓存的一些云提供商还有一些额外的好处,它通过在较低级别运行 DNS 缓存来减少延迟,这样您就不会等待 DNS 响应。

从长远来看,如果您只在一个云中,专门用于 DNS 的托管服务将可以正常工作。但是,如果您跨越多个云提供商和本地环境的集群,托管产品可能只是解决方案的一部分。

云原生计算基金会(CNCF) 提供了多种选择,并且有大量开源项目在帮助缓解其中一些痛点方面取得了长足的进步,尤其是在跨云、多云、或混合云类型的场景。


文章来源:Christopher Bradford

https://dzone.com/articles/taking-your-database-beyond-a-single-kubernetes-cl


最后修改时间:2022-04-24 11:26:44
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论