【翻译】利用Kubernetes、WireGuard和Rook实现跨数据中心的冗余

客串文章,最初发表在Elastisys的博客上,作者是Elastisys的高级云架构师Cristian Klein

一些 法院的裁决和欧洲数据保护委员会(EDPB)的指南明确指出:在美国拥有的云上处理欧盟的个人数据是一个巨大的法律风险。因此,许多Kubernetes运营商正争先恐后地将他们的环境移植到欧盟的云供应商或其内部的数据中心。不幸的是,这种环境往往缺乏 "可用区 "的概念,这使得跨数据中心的冗余变得困难。在这篇文章中,我们将向你展示我们如何使用Kubernetes、Rook / Ceph、Calico和WireGuard来处理这一要求。

区域与可用区

美国的云计算供应商把他们的数据中心称为 "可用区",并把它们归入区域。一个区域内的数据中心在物理上相互之间有足够的距离,因此它们不太可能受到同一个互联网或电力中断或极端天气事件的影响。然而,它们之间的距离足够近,所以延迟很低,带宽也很充足,可以作为一个单一的单元来暴露。

事实上,从使用的角度来看,一个地区 "感觉 "就像一个单一的数据中心。例如,运营商可以享受一个跨越几个区域的单一私有网络。同样,一个地区的负载平衡器可以指向几个地区的虚拟机。一些美国的云供应商甚至提供区域性的磁盘。

因此,将你的工作负载延伸到同一地区的两个区域,大大增加了对故障的恢复能力,而不需要你的额外努力。

我总是有可用区域吗?

不幸的是,大多数欧盟云供应商和内部数据中心缺乏可用性区域的概念,只将他们的数据中心分为区域。这意味着,尽管他们的数据中心可能在物理上很接近,有低延迟和充足的带宽,但他们并不 "感觉 "是一个单一的数据中心。具体来说,它们缺乏一个延伸的私有网络,缺乏跨数据中心复制的磁盘,也缺乏跨数据中心故障转移入口流量的方法。

如果你的弹性要求需要在多个数据中心之间伸展你的工作负载,你将不得不投入大量的额外努力。

云原生来拯救!

云原生项目,如Kubernetes,允许构建一个满足你的弹性要求的应用平台。让我们通过下面的架构图来一步步描述我们所构建的平台。

Diagram showing building application platform with Kubernetes architecture

选择区域

首先,你需要选择三个区域。区域1和2运行工作负载并存储数据,因此需要更多的容量。区域3只是充当 "仲裁者",以避免 "大脑分裂",需要很少的容量。当区域1认为区域2宕机,但区域2认为区域1宕机,并且各自认为自己负责执行写操作时,分裂大脑就可能发生。在系统的两个部分发生的写操作没有适当的同步,可能会导致巨大的数据损失。仲裁者的存在是为了制裁 "正确的 "区域,并确保只有一个区域负责写操作。

创建基础设施

下一步涉及创建基础设施。提供足够的虚拟机(VM),将控制平面节点和工作负载节点完全分开。你甚至可能想拥有独立的存储节点,这些节点不运行应用容器,只托管Ceph实例。

大多数基础设施供应商都有一个通过安全组配置的防火墙。确保打开正确的端口,既可以让管理员访问,也可以让Kubernetes和应用程序组件进行通信,如架构图中所示。由于安全组在各地区之间不共享--记住,这些基本上是三个不同的云--你将不得不使用IP允许列表。尽量限制,也就是说,不要向全世界开放Kubelet的TCP端口。

创建一个拉伸的Kubernetes集群

下一步涉及到在创建的基础设施之上喷洒Kubernetes集群。我们是Kubespray的忠实粉丝,以至于我们为它做出了贡献。Kubespray将允许你通过添加正确的污点,正确地分离控制面和数据面节点。用拓扑标签正确地标记你的节点,将允许应用程序使用PodTopologySpreadConstraints将其副本分散到各个数据中心,实现你所需要的跨数据中心的弹性。

另一个需要记住的问题是,集群内的流量可能会通过不受信任的网络。大多数数据安全法规要求你对所有此类流量进行加密。幸运的是,Kubespray最近增加了对Calico与WireGuard配置的支持。不谈细节,WireGuard就像一个节点到节点的VPN。想象一下,IPsec的立体化同样的安全保证,零麻烦。

创建一个拉伸的Rook集群

由于你正在创建一个拉伸的Kubernetes集群,你不能使用容器存储接口(CSI)来整合存储 - 即动态连接的虚拟磁盘 - 由三个区域提供。虚拟磁盘不会在区域之间同步,这意味着失去一个区域将使你失去所有存储在该区域托管的PersistentVolumes上的数据--这与我们想实现的目标相去甚远。

幸运的是,Rook CNCF项目可以用来创建一个Kubernetes原生的存储集群,使用连接到虚拟机的磁盘。在引擎盖下,Rook使用了一个经过战斗考验的存储解决方案,称为Ceph,它处理数据映射和复制。事实上,你可以轻松地创建一个拉伸的存储集群。Rook了解你的Kubernetes节点的拓扑标签,并配置所谓的Ceph CRUSH映射,以确保数据在数据中心之间进行复制。

使用正确的容忍度,你可以确保一个Ceph Mon运行在仲裁者区域,以便在一个数据中心停机时也能保持Ceph Mon的法定人数。如果没有Mon的法定人数,Ceph OSD--实际存储数据的组件--将不被允许执行写入,以避免分裂的大脑和巨大的数据损失。

让流量进入集群

你的最后一个挑战是让流量进入集群,特别是只把它路由到健康区域。幸运的是,带有健康检查的DNS服务是很多的。这种DNS服务提供动态DNS记录,只指向那些通过健康检查的IP地址。如果你正在使用Ingress控制器--就像大多数(所有)Kubernetes集群那样--只需将健康检查指向Ingress控制器的healthz端点。结合低DNS TTL,你的应用程序用户--无论是他们的浏览器在应用程序上--将被引导到健康区域。

你可以自由选择美国或欧盟所属实体的DNS服务。DNS服务将只看到解析的DNS服务器的IP地址和被解析的域名。因此,没有任何个人数据--甚至是被裁定为个人数据的应用用户的IP地址--将被DNS服务处理。

如果你想对你的Kubernetes开发者格外仁慈--你想让他们给你发送hugops,不是吗?- 考虑向他们发送一个DNS记录,而不是访问Kubernetes API的IP地址。这允许你使用相同的DNS服务与健康检查,向你的开发人员隐藏你的区域的故障。

这听起来很容易!我说完了吗?

正如瑞典人所说。"nja"(是和不是)。你的集群中是否有两倍的所需容量?你是否用正确的PodTopologySpreadConstraints正确配置了所有的应用程序?你所有的部署和状态集都配置了足够的复制吗?故障转移的速度是否足够快?

回答所有这些问题并不是一个简单的清单工作,而是应该定期测试对故障的恢复能力。这可以确保你不会在故障发生时被意外的故障模式咬住,而是积极主动地找出差距,并根据需要弥补这些差距。

例如,我们有一个使用StatefulSet与复制1的应用程序,这被认为是足够的,因为该应用程序可以容忍在故障转移期间有几分钟的停机时间。当我们诱导承载StatefulSet的唯一Pod的区域发生故障时,我们惊讶地发现Kubernetes没有将其重新安排到健康区域,因为我们需要手动删除该Pod。实际上,我们碰到了Kubernetes的一个功能,该功能的设计是为了按照预期的方式微妙地处理StatefulSets。幸运的是,我们在失败测试中发现了这一点,所以解决方案是简单地设置复制2。

这一点非常重要,所以我打算再写一遍。必须定期测试对故障的恢复能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值