如何在数据量大的Kubernetes环境中处理数据重复

作者:奥古斯丁·斯特比斯(CAST AI)

为什么重复数据?

为每个团队创建其状态的副本,可以方便地创建应用程序的副本。例如,您可能希望一个单独的数据库副本来测试一些重要的模式更改或开发其他中断操作,如批量插入/删除/更新...

复制数据需要很多时间。这是因为您需要先从源块存储提供程序下载所有数据来计算,然后再次将其发送回存储提供商。在此过程中使用了很多网络流量和CPU / RAM。通过将某些昂贵的操作卸载到专用硬件来实现硬件加速总是能极大地提升性能.它将完成一次手术所需的时间减少了几个数量级。

卷快照拯救

库伯内特斯介绍VolumeSnapshots如1.12的alpha版本,1.17的beta版本和1.20的通用可用版本。VolumeSnapshots使用来自存储提供商的专用api来复制数据卷。

由于数据已经在同一个存储设备(设备阵列)中,复制数据通常是具有本地快照(大多数本地存储提供商)的存储提供商的元数据操作。您所需要做的就是将新磁盘指向一个不可变快照,并且只保存增量(或者让它进行整个磁盘的复制)。作为存储后端的操作,它速度快得多,通常不需要通过网络发送流量。公有云存储提供商的工作原理略有不同。它们将快照保存到对象存储,然后在“复制”磁盘时从对象存储复制回块存储。从技术上讲,云提供商花费了大量的计算和网络资源,但从Kubernetes用户的角度来看,无论是本地快照存储提供商还是远程快照存储提供商,VolumeSnapshots的工作方式是一样的,并且该操作不涉及计算和网络资源。

看来我们有办法了,对吧?

实际上,VolumeSnapshots是命名空间的,Kubernetes保护命名空间的数据不被租户(命名空间)共享。Kubernetes的这种限制是一种有意识的设计决策,这样运行在不同名称空间中的Pod就不能挂载另一个应用程序的名称空间PersistentVolumeClaim(聚氯乙烯)。

周围的一种方式是在一个名称空间中创建具有重复数据的多个卷。但是,您可以轻松引用错误的副本。

因此,该想法是通过名称空间分离团队/举措,以避免该团队/概述,并且通常限制对生产命名空间的访问。

解决方案?在外部创建金色快照

绕过这个设计限制的另一种方法是在外部创建快照(而不是通过Kubernetes)。这也称为手动预配置快照。接下来,我将把它作为一个多租户黄金快照导入,它可以用于许多名称空间。下图为AWS EBS(弹性块存储)和GCE PD(持久磁盘)服务。

准备黄金快照的高级别计划

  1. 确定要使用云提供程序中的数据克隆的磁盘(EBS/永久磁盘)
  2. 创建磁盘快照(在云提供商控制台中)
  3. 获取磁盘快照ID

为每个团队克隆数据的高级别计划

  1. 创建名称空间“sandbox01”
  2. 将磁盘快照(ID)作为VolumEnapshotContent到Kubernetes
  3. 在命名空间“sandbox01”上创建卷快照
  4. 从volumesnapshot创建持久性volumeclabl
  5. 用PVC安装部署或StatefulSet

第1步:识别磁盘

首先,你需要确定你的黄金来源。在我的例子中,它是一个PostgreSQL数据库,位于“生产”名称空间中的persistentvolumecclaim“postgresp -claim”上。

kubectl -n  get pvc  -o jsonpath='{.spec.volumeName}' '

输出如下所示:

PVC-3096B3BA-38B6-4FD1-A42F-EC99176ED0D90

第2步:准备你的金色来源

您需要这样做一次或每次您想刷新黄金数据时都需要这样做。

制作磁盘快照

转到AWS EC2或GCP计算引擎控制台,搜索EBS卷(在AWS上)或永久磁盘(在GCP上),其标签与上次输出匹配。在本例中,我看到:PVC-3096B3BA-38B6-4FD1-A42F-EC99176ED0D9

单击Create snapshot并给它一个名称。你可以在控制台手动操作,AWS CloudShell /谷歌CloudShell,或者在终端中。要在终端中创建快照,您必须使用AWS CLI工具(AWS.)或者谷歌的CLI(GCLOUD.)已安装和配置。

下面是在GCP上创建快照的命令:

gcloud计算磁盘快照<云磁盘id>--项目=--快照名称=--区域=--存储位置=
显示GCP上的终端的屏幕截图

GCP快照创建

GCP通过它的PVC名称来标识磁盘,因此它是直接映射。在AWS中,首先需要通过带有PVC名称值的CSIVolumeName AWS标记找到将用于创建快照的卷。

AWS web控制台屏幕截图,显示EBS卷标识

识别AWS上的磁盘ID

标记完成Volume (Volume -id)vol-00c7ecd873c6fb3ec并在AWS控制台中创建EBS快照,或使用AWS CLI.

AWS EC2 Create-Snapshot --volume-id' '--description'' - 规格'resourcetype = snapshot'

第3步:获取磁盘快照ID

在AWS中,上面的命令将输出类似于:

:“SnapshotId snap-09ed24a70bc19bbe4”

如果你正在使用GCP云,你可以通过查询快照的给定名称从gcloud命令获取快照ID:

Gcloud计算快照——project= description  | grep id:

您应该获得类似的输出:

id: 6645363163809389170

步骤4:为每个团队创建一个开发环境

现在我有了Golden Snapshot,它是不可变数据。每个团队将获得该数据的副本,并且团队成员可以根据自己的需要对其进行修改,因为将为每个团队创建一个新的EBS/持久磁盘。

下面我将为每个命名空间定义一个清单。要节省时间,可以使用诸如的工具替换名称空间名称(例如更改“Sandbox01”→“Sandbox42”)sed或者YQ.,Kubernetes感知模板工具Kustomize.,或在CI/CD管道中使用变量替换。

下面是一个清单示例:

---apiVersionsnapshot.storage.k8s.io / v1种类VolumeSnapshotContent元数据姓名PostgreSQL-ORDERS-DB-SANDBOX01名称空间沙盒01规范deletionpolicy.保留驾驶员pd.csi.storage.gke.io.snapshotHandle“gcp/projects/staging-eu-castai-vt5hy2/global/snapshots/6645363163809389170”volumesnapshotref.种类volumesnapshot.姓名PostgreSQL-ORDERS-DB-SNAP名称空间沙盒01---apiVersionsnapshot.storage.k8s.io / v1种类volumesnapshot.元数据姓名PostgreSQL-ORDERS-DB-SNAP名称空间沙盒01规范volumeSnapshotContentNamePostgreSQL-ORDERS-DB-SANDBOX01

在Kubernetes中,VolumesNapshotContent(VSC)对象不是命名的。但是,我需要一个单独的vsc来使用每个不同的命名空间来使用,所以metadata.name每个VSC也必须是不同的。为了简单起见,我使用目标名称空间作为名称的一部分。

现在是时候用K8s集群中安装的CSI(容器存储接口)驱动程序替换驱动程序字段了。主要的云提供商有支持Volumesnapshot的块存储CSI驱动程序,但通常默认情况下不安装CSI驱动程序,请咨询Kubernetes提供商。

上面的清单定义了在GCP上工作的VSC。在AWS上,驱动程序和SnashotHandle值可能如下所示:

驾驶员ebs.csi.aws.comsnapshotHandle“snap-07ff83d328c981c98”

此时,我需要使用保留策略,以便CSI驱动程序不会尝试删除手动创建的EBS磁盘快照。

对于GCP,您必须手动构建此字符串 - 添加完整的项目ID和快照ID。对于AWS,它只是一个纯粹的快照ID。

VSC还需要指定哪个VolumeSnapshot (VS)将使用它,因此VSC和VS相互引用。

现在我可以从上面的vs创建persistentvolumeclaim。首先设置这一点是很重要的:

---apiVersionv1种类PersistentVolumeClaim元数据姓名postgres pv索赔名称空间沙盒01规范数据源种类volumesnapshot.姓名PostgreSQL-ORDERS-DB-SNAP每组snapshot.storage.k8s.io.访问模式——ReadWriteOnce资源要求贮存21胃肠道

如果默认的StorageClassWaitForFirstConsumer策略,那么只有当某些Pod限制了PVC时,才会从黄金快照创建实际的云磁盘。

现在我将那个PVC分配给我的Pod(在我的例子中,它是Postgresql),就像我分配给其他PVC一样。

kubectl-n获取卷快照内容、卷快照、pvc、pod

VS和VSC都应该是READYTOUSE, PVC绑定,Pod(来自Deployment或StatefulSet)运行。

为了继续使用来自Golden Snapshot的数据,我只需要为下一个名称空间和voilà!不需要在复制过程中浪费时间和计算资源。