数据库如何在 Kubernetes 上运行?如果可以,哪些类型的数据库和数据最适合使用 K8s?让我们一起来看看。
Kubernetes 是用于自动部署、扩展和管理容器化应用程序的一个开源的容器编排解决方案。尽管 Kubernetes 最初是为无状态应用程序设计的,但随着有状态工作负载的日益流行,Kubernetes 也可以于管理有状态应用程序。
通常情况下,容器是无状态的,如果容器崩溃或需要重启,容器中的数据肯定会丢失。作为一个容器编排器,Kubernetes 会保持定期重启并在节点间移动容器。无论 Kubernetes 对运行应用程序的容器做了什么,这对于需要保存数据的有状态工作负载来说都是一个重要的问题。
众所周知,数据库服务器是一个有状态的应用程序。
那数据库如何在 Kubernetes 上运行?Kubernetes 是否有机制来管理此类应用程序?如果是这样,什么类型的数据库和数据最适合使用它?
在这篇文章中,我们将找到答案。
以企业中运行数据库服务器的不同方式为例分为:
尽管开发 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 更适合于某些类型的数据。重要的是要了解数据的重要性,以及它必须在多大程度上可用。
为了实现高可用性,一些数据库引擎使用所谓的最终一致性模型。最终一致性是一种技术,它确保如果给定的数据块没有新的更新,所有对它的访问都将返回最后更新的值。它假设,在任何时间点,不同节点的数据可能存在一些不一致(取决于从哪里读取它),因为它正在不断更新,但是一旦更新完成,所有节点都将拥有它的相同副本,并且所有客户端请求都将获得相同的数据。当你在 Kubernetes 中运行数据库系统时,需要从业务角度来看这是否可接受。
一些数据库引擎可以处理故障转移(例如,当运行数据的主副本的 pod 重新调度或崩溃时),但备用节点恢复并承担主要节点角色可能需要一些时间。你需要考虑在这种情况下,可以承受多少数据不可用,以及是否可以接受使用旧数据。
如你所见,这完全取决于业务需求。处理瞬态数据(如缓存层)、只读数据(如查找表)或可轻松重建的数据(如 API 输出)的工作负载时,很显然更适合在 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/