草庐IT

翻译|是否应该在 Kubernetes 上运行数据库?

RadonDB开源社区 2023-03-28 原文

数据库如何在 Kubernetes 上运行?如果可以,哪些类型的数据库和数据最适合使用 K8s?让我们一起来看看。

Kubernetes 是用于自动部署、扩展和管理容器化应用程序的一个开源的容器编排解决方案。尽管 Kubernetes 最初是为无状态应用程序设计的,但随着有状态工作负载的日益流行,Kubernetes 也可以于管理有状态应用程序。

通常情况下,容器是无状态的,如果容器崩溃或需要重启,容器中的数据肯定会丢失。作为一个容器编排器,Kubernetes 会保持定期重启并在节点间移动容器。无论 Kubernetes 对运行应用程序的容器做了什么,这对于需要保存数据的有状态工作负载来说都是一个重要的问题。

众所周知,数据库服务器是一个有状态的应用程序。

那数据库如何在 Kubernetes 上运行?Kubernetes 是否有机制来管理此类应用程序?如果是这样,什么类型的数据库和数据最适合使用它?

在这篇文章中,我们将找到答案。

运行数据库的不同方式

以企业中运行数据库服务器的不同方式为例分为:

  • 本地自有数据库:目前许多公司仍然选择使用虚拟机在本地或云上托管数据库服务器。企业负责设置数据库服务器、设置其安全性、安装补丁、升级、配置存储、提供高可用性、扩展、备份以及执行其他的数据库管理员操作。这是手动程度最高的方式,但这种方式可以完全控制数据库和数据。
  • 云上托管数据库:大多数现代企业会选择 Amazon RDS、Azure 数据库、谷歌云数据库 或 Instaclustr 等在云上部署和扩展数据库服务器更容易的解决方案。供应商负责存储、计算、网络带宽、安装、升级和高可用性等。作为消费者的企业只需将数据库托管在供应商提供的一个实例上,该实例运行你选择的数据库引擎(如 SQL 或 NoSQL)。
  • Kubernetes 托管数据库:该方式是以上两种方式的混合体。你可以在本地或云端运行 Kubernetes 或者使用托管服务。通过这种方法,你可以利用 Kubernetes 的许多优势,如自动调度、自修复或水平伸缩。但数据库的使用(如性能调优、备份和恢复)仍需要你注意,并且可能会由于一些容器化特点而略有不同。

持久性存储和 K8s 的其他特性

尽管开发 Kubernetes 的目的是管理不需要数据持久性的容器化应用程序,但它现在也提供了管理有状态应用程序的解决方案。持久卷( Persistent volumes 简称 PV)[1] 提供了一个 API,允许 Kubernetes 管理员管理卷[2],它与更多存储种类[3] 一起提供了一种安全而抽象的方式来存储和管理数据。

然而,云是不可预测的,Kubernetes 经常需要重启和重新构建 pods。因此,持久卷很难在节点间移动数据,并同时确保它们连接到正确的容器。更复杂的是,一些数据库需要运行在多节点集群配置中。

Kubernetes 1.5 版本[4] 中引入了一些设计来帮助解决这些问题。StatefulSets[5] 确保 pods 基于相同的容器规范,即使它们被移动到另一个节点也保持唯一的 ID。通过唯一 ID 将 pods 与持久卷耦合起来,即使在重新调度它们时,也可以维护工作负载的状态。DaemonSets[6] 虽然稍微复杂一些,但也是在集群的每个节点上运行工作副本的一种方式。

分布式有状态工作负载通常需要一系列预定义资源无法处理的复杂操作。例如,分布式数据库可能需要在数据库节点(在 Kubernetes 中,是一个 pod)出现故障时执行一组特定的操作。这类操作的例子可以是选举领导者、平衡数据等等。

原生 Kubernetes 功能无法真正处理这些情况,但其自定义资源(Custom resources)[7] 可以提供帮助。 Custom resources 允许 Kubernetes API 使用领域特定的逻辑进行扩展,定义新的资源类型和控制器[8]。Operator 模式[9] 通过帮助开发自定义解决方案,利用自定义资源来管理应用程序及其组件。

OSS 框架,如 kubebuilder[10],或 Operator Framework[11],提供了构建块来创建 Operator,如 Postgres Operator[12]、MySQL Operator for Kubernetes[13], Elastic Cloud on Kubernetes (ECK)[14],或 K8ssandra[15]。

分布式数据库的特性

大多数数据库引擎都提供了一种或多种方式来分发数据并使其具有高可用性。当选择要在 Kubernetes 上运行数据库时,你需要考虑以下特性:

  • 复制:数据库是否支持复制?如果支持,它支持什么类型的复制(如:双向复制、事务复制和快照)?这将有助于提高可靠性、容错性和可访问性。
  • 分片:数据库是否能够对数据进行分区,并在不同的实例(即 pod)中保存不同的片段?这可以帮助优化冗余和分散负载。
  • 故障转移:数据库是否能够从主节点、读写节点切换到其他只读节点并将只读节点提升为主节点?这也将有助于提高可靠性、容错性和可访问性。
  • 可伸缩性:数据库是否具备可伸缩性(向内扩展和向外扩展)?Kubernetes 为水平扩展铺平了道路,但是数据库需要根据需要添加或删除实例。这可以帮助处理增加的负载或在负载下降时降低成本。
    具有这些特性的数据库(例如:MySQL、PostgreSQL、ClickHouse、Elasticsearch、MongoDB 或 Cassandra 等)可以更轻松地应对异构云环境的不确定性。

数据可用性的考虑

由于 pod 和计算节点在本质上通常是临时的,因此,Kubernetes 更适合于某些类型的数据。重要的是要了解数据的重要性,以及它必须在多大程度上可用。

为了实现高可用性,一些数据库引擎使用所谓的最终一致性模型。最终一致性是一种技术,它确保如果给定的数据块没有新的更新,所有对它的访问都将返回最后更新的值。它假设,在任何时间点,不同节点的数据可能存在一些不一致(取决于从哪里读取它),因为它正在不断更新,但是一旦更新完成,所有节点都将拥有它的相同副本,并且所有客户端请求都将获得相同的数据。当你在 Kubernetes 中运行数据库系统时,需要从业务角度来看这是否可接受。

一些数据库引擎可以处理故障转移(例如,当运行数据的主副本的 pod 重新调度或崩溃时),但备用节点恢复并承担主要节点角色可能需要一些时间。你需要考虑在这种情况下,可以承受多少数据不可用,以及是否可以接受使用旧数据。

如你所见,这完全取决于业务需求。处理瞬态数据(如缓存层)、只读数据(如查找表)或可轻松重建的数据(如 API 输出)的工作负载时,很显然更适合在 Kubernetes 上。

总结

作为一种容器编排技术,Kubernetes 简化了许多常见的操作问题,例如调度、自动扩展或故障转移。虽然它非常适用于无状态工作负载,但有状态工作负载(如数据库)还有其他需要解决的问题。我们已经看到:

  • 持久卷和存储类提供了一种安全而抽象的方式来管理数据;
  • 通过允许将 pod 与持久数据绑定,可以在这些概念的基础上构建 StatefulSet 和 DaemonSet;
  • 自定义资源和 Operator 可以帮助为需要数据持久性的应用程序提供自定义逻辑。
    但是,重要的是要考虑对要在 Kubernetes 上运行的数据库引擎的可用支持,以及要存储的数据类型和数据的可用性要求。在 Kubernetes 中运行服务需要应对一定程度的波动性。

因此,Kubernetes 上更适合部署可以处理复制、分片和故障转移的数据库。同样,Kubernetes 托管的理想数据是可以轻松快速重新生成的数据。归根结底,这将取决于业务需要的容错能力。

原文:https://www.containiq.com/post/should-you-run-a-database-on-kubernetes

引用链接

1.持久卷:https://www.containiq.com/post/kubernetes-persistent-volumes

2.卷:https://kubernetes.io/docs/concepts/storage/volumes/

3.存储种类:https://kubernetes.io/docs/concepts/storage/storage-classes/

4.Kubernetes 1.5:https://kubernetes.io/blog/2016/12/kubernetes-1-5-supporting-production-workloads/

5.StatefulSets:https://www.containiq.com/post/kubernetes-statefulsets

6.DaemonSets:https://www.containiq.com/post/using-kubernetes-daemonsets-effectively

7.自定义资源:https://www.containiq.com/post/kubernetes-crds-custom-resource-definitions

8.控制器:https://www.containiq.com/post/kubernetes-controllers

9.Operator 模式:https://kubernetes.io/docs/concepts/extend-kubernetes/operator/

10.kubebuilder:https://github.com/kubernetes-sigs/kubebuilder

11.Operator Framework:https://operatorframework.io/

12.Postgres Operator:https://github.com/zalando/postgres-operator

13.MySQL Operator:https://github.com/mysql/mysql-operator

14.Elastic Cloud on Kubernetes:https://github.com/elastic/cloud-on-k8s

15.K8ssandra:https://k8ssandra.io/

有关翻译|是否应该在 Kubernetes 上运行数据库?的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  3. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  6. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  7. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  8. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  9. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  10. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

随机推荐