全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 数据分析与数据挖掘
2446 0
2022-04-22

Kubernetes 从根本上改变了传统的应用程序开发和部署模式。应用程序开发团队现在可以在几天内跨不同环境,在他们的 Kubernetes 集群中开发、测试和部署他们的应用程序。前几代技术通常需要数周甚至数月的时间。


这种加速是可能的,因为 Kubernetes 带来了抽象,即它处理物理或虚拟机的底层细节,同时允许用户声明 CPU、内存、容器实例的数量以及其他参数。在庞大的、充满爱心的社区和不断增加的采用率的支持下,Kubernetes 是领先的容器编排平台,具有相当大的优势。

随着采用的增长,Kubernetes 中存储模式的混乱也在增加。

随着每个人都在争夺 Kubernetes 存储的一块蛋糕,存储选项周围有很多噪音,淹没了信号。

Kubernetes 是应用程序开发、部署和管理的现代模型。现代模型将存储和计算分解。要充分理解 Kubernetes 上下文中的分解,我们还需要理解有状态和无状态应用程序和存储的概念。这就是 S3 的 RESTful API 方法比其他解决方案提供的 POSIX/CSI 方法具有明显优势的地方。

这篇文章讨论了 Kubernetes 存储模式并解决了无状态与有状态的争论,目的是准确理解为什么存在差异以及它为什么重要。在这篇文章的后面,我们将根据容器和 Kubernetes 最佳实践来介绍应用程序及其存储模式。

无状态容器
容器本质上是轻量级和短暂的,它们可以在几秒钟内轻松停止、删除或部署到另一个节点。在大型容器编排系统中,这种情况一直在发生,而其消费者甚至没有注意到这种变化。但是,只有当容器对底层节点没有任何数据依赖时,这种移动才有可能。这样的容器是 无状态的。

有状态的容器
如果容器将数据存储在本地安装的驱动器(或块设备)上,则底层存储必须与容器本身一起移动到新节点——以防万一发生故障。这很重要,否则容器中运行的应用程序将无法正常运行,因为它需要引用它存储在本地挂载上的数据。这样的容器是 有状态的。

从技术上讲,有状态容器也可以移动到不同的节点。通常这是通过分布式文件系统或连接到容器运行的所有节点的网络块存储来实现的。通过这种方式,容器可以访问持久卷挂载,并将数据存储到网络上可用的附加存储中。为了统一起见,我将在本文的其余部分将此方法称为 有状态容器方法 。

OZ9n13jGdHIu_QIjL1hlTK_bVt4JoLHDTpvaTbgZ9MhlwVIdPE2YbSqSRhxIcCWS2jzRXCZzcn4mDxE72wfdKmnFK7m2UCW7342jZdC8NglnjR-PUJA8Exb5g5cDhwY9vaPxLdst
在典型的有状态容器方法中,应用程序 pod 被挂载到一个分布式文件系统——一种共享存储,所有应用程序数据都驻留在其中。虽然可能会有一些变化,但这是高级方法。

现在,让我们了解为什么 有状态容器方法在云原生世界中是一种反模式。

云原生应用程序设计
传统上,应用程序使用数据库存储结构化数据,使用本地驱动器或分布式文件系统来转储所有非结构化甚至半结构化数据。随着非结构化数据的增长,开发人员意识到 POSIX 过于健谈,产生了大量的间接税,最终阻碍了应用程序的大规模执行。

这在很大程度上促成了一种新的存储标准,即由 RESTful API 驱动的云原生存储,使应用程序摆脱了处理本地存储的任何负担,并使其有效地无状态(就像远程存储系统的状态一样)。现代应用程序是在考虑到这一点的基础上构建的。通常,任何处理某种数据(日志、元数据、blob 等)的现代应用程序都通过将状态传送到相关存储系统来符合云原生设计。

有状态的容器方法把它带回到它开始的地方!

使用 POSIX 接口来存储数据,应用程序以有状态的方式运行,并且失去了云原生设计的最重要原则,即让应用程序工作人员根据入站负载增长和收缩的能力,一旦当前节点移动到新节点的能力下降等等。

随着我们变得更具体,我们发现我们再次使用 POSIX 与 REST API 进行存储,但由于 Kubernetes 环境的分布式特性,POSIX 问题进一步放大。具体来说,

POSIX 是健谈的:POSIX 语义要求每个操作都有关联的元数据和文件描述符,以维护操作的状态。这会导致大量开销,而不会增加任何实际价值。像 S3 API 这样的对象存储 API 摆脱了这些要求,允许应用程序触发并忘记调用。来自存储系统的响应指示操作是否成功。如果失败,应用程序可以重试。
网络限制: 在分布式系统中,暗示可能有多个应用程序试图将数据写入单个挂载。因此,不仅应用程序争夺带宽(将数据发送到挂载),存储系统本身也在同一网络上争夺带宽以将数据发送到实际驱动器。由于 POSIX 聊天,网络调用的数量增加了几倍。另一方面,S3 API 允许在客户端到服务器和内部服务器调用之间明确隔离网络调用。
安全性:POSIX 安全模型是为人类用户构建的,管理员为每个用户或组配置特定的访问级别。这使得难以适应云原生世界。现代应用程序依赖于基于 API 的安全模型,具有策略定义的访问、服务帐户、临时凭证等。
可管理性: 有状态的容器增加了管理开销。同步并行数据访问、确保数据一致性等需要仔细考虑数据访问模式。这意味着需要安装、管理和配置更多的软件,当然还有额外的开发工作。
容器存储接口
虽然 CSI 在将 Kubernetes 卷层扩展到第三方存储供应商方面做得很好,但它也无意中让生态系统相信有状态容器方法是 Kubernetes 中推荐的存储方法。

CSI 被开发为一种标准,用于将任意块和文件存储系统暴露给 Kubernetes 上的遗留应用程序。而且,正如我们在这篇文章中看到的,有状态容器方法(以及当前形式的 CSI)有意义的唯一情况是应用程序本身是一个遗留系统,无法添加对对象存储 API 的支持。

重要的是要了解,以当前形式使用 CSI,即现代应用程序的卷安装,最终将导致我们在 POSIX 样式存储系统中看到的类似问题。

更好的方法
要理解的重要一点是,大多数应用程序本质上不是有状态或无状态的。它们的行为由整体架构和特定设计选择定义。当然,有些存储应用程序需要有状态(例如 MinIO)。我们稍后会讨论有状态的应用程序。

一般来说,应用程序数据可以分为几大类:

日志数据
时间戳数据
交易数据
元数据
容器图像
Blob 数据
所有这些数据类型在现代存储平台中都得到了很好的支持,并且有几个云原生平台可用于满足这些特定数据格式中的每一种。例如,事务数据和元数据可以位于现代的云原生数据库中,如 CockroachDB、YugaByte 等。容器图像或 blob 数据可以存储在基于 MinIO 的 docker 注册表中。TimeStamp 数据可以存储在 InfluxDB 等时间序列数据库中。我们将跳过每种数据类型和相关应用程序的详细信息,但其想法是避免基于本地挂载的持久性。

SaHQMxaOY0lidc_Ey_5Go7YR41_Vx3apx2CvHGsIJNvPANd_Vb60DpUTqX3mto9nGqSxg_APDTXxSz3CPE8-1NFK-4dDoKkuQh71uh3zO6Ns-ZlOUU_amdaxJgtXsJmFH8ZxlQQj
此外,在许多情况下,将临时缓存层用作应用程序的暂存空间是有效的,但应用程序不应依赖该层作为事实来源。

有状态的应用程序存储
虽然通常最好保持应用程序无状态,但存储应用程序(例如数据库、对象存储、键值存储)需要有状态。让我们了解这些应用程序是如何部署在 Kubernetes 上的。我将以 MinIO 为例,但类似的原则适用于所有主要的云原生存储系统。

云原生存储应用程序旨在利用容器带来的灵活性,这意味着这些应用程序不会对其部署的环境做出假设。例如,MinIO 使用内部擦除编码机制来确保系统中有足够的冗余,以允许多达一半的驱动器发生故障。MinIO 还使用自己的散列和服务器端加密来管理数据的完整性和安全性。

对于此类云原生应用程序,本地持久卷 (PV) 最适合作为后备存储。本地 PV 提供原始存储容量,而在这些 PV 之上运行的应用程序使用自己的智能来扩展和管理不断增长的数据需求。

与带有自己的管理和冗余层的基于 CSI 的 PV 相比,这是一种更简单和可扩展的方法,这些层通常与有状态应用程序的设计竞争。

向分解的稳步前进
在这篇文章中,我们讨论了应用程序的无状态化,或者换句话说,将存储与计算分离。现在,让我们来看看这种趋势的一些真实世界的例子。

Spark是著名的数据分析平台,传统上在面向 HDFS 的部署中以有状态方式运行,但随着它转向云原生世界,Spark 越来越多地使用“s3a”连接器在 Kubernetes 上以无状态方式运行。Spark 使用连接器将状态传送到其他系统,而 Spark 容器本身完全无状态运行。大数据分析领域的其他主要企业参与者,如 Vertica、  Teradata、  Greenplum 也正在转向计算和存储的分解模型。

同样,从 Presto、Tensorflow 到 R、Jupyter 笔记本等所有其他主要分析平台都遵循这种模式。将状态卸载到远程云存储系统使您的应用程序更易于扩展和管理。此外,它有助于保持应用程序可移植到不同的环境。

      相关帖子DA内容精选
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群