文章目录
一、在Kubernetes上能否部署数据库?
作为云原生时代的技术底座,K8s现在已经成为容器编排的事实标准,而且越来越多的工作负载,包括交易事务、音视频流媒体处理、通信系统、人工智能等等都开始使用K8s。因此,K8s又被称为云端的“Linux操作系统“。那么,对于每个企业应用几乎都离不开的数据库而言,其是否可以部署到K8S上了吗?
1、数据库能不能部署到K8s?
在最开始K8s 1.0时代,k8s是为无状态应用设计的。无状态应用可以被重启和重新调度,或者快速的扩展出多个副本实例。虽然说这个时候也可以在k8s中运行容器化的数据库实例,但这个阶段k8s对数据库是不友好的。
随着K8s 1.5版本开始支持StatefulSet,有状态应用正式成为了k8s的一等公民,通过持久卷(Persistent Volume)可以解决数据库的数据持久性问题。尤其是到K8s 1.10有了CSI之后,企业也可以使用性能更高、可靠性更好的外置存储了,当数据库Pod被调度到其它节点重启的时候,共享的持久卷可以在新的节点上重新挂载给数据库Pod。这些解决了数据库的数据安全性和可用性的基础设施问题,但k8s本身并不理解每个数据库的运维的逻辑,因此数据库的运维部分仍然有很多地方需要人工来处理,比如数据库状态的监控、主/从数据库的切换、数据备份等。
让数据库能真正在k8s上变得好用的是Operator(Operator 模型基于 Kubernetes 中的两个概念结合而成:自定义资源和自定义控制器)的出现。Operator使得数据库厂商和第三方可以去扩展K8s API,将数据库运维的能力由Operator来实现。这大幅简化了在k8s中运维和管理数据库,把K8s变成一个优质的数据库运行平台。
2、数据库部署到容器的好处
-
据库的安装、配置和维护更简单
数据库部署到容器,哪怕进行一个复杂的主从关系型数据库安装,都可以通过一个YAML文件轻松搞定,后续不管是给数据库实例增加资源,或者增加实例,都非常简单。K8s还可以大幅简化数据库升级和打补丁的操作。 -
跨多云的部署兼容性更好
对于需要在多云环境中进行部署的系统,或者需要经常切换部署环境场景的,托管的数据库服务基本不可行,而物理部署数据库又太复杂,在容器中进行数据库部署就变得非常有优势。因为目前几乎所有公有云和私有云的K8s都具有高度的兼容性,在容器中进行数据库部署可以提供高度的可移植性和跨平台可管理性。 -
应用和数据库可以统一在一个K8s平台上运维,不需要分开部署运维。
对于完成同一业务目的的应用系统而言,应用本身和数据库可以同时在K8s上进行部署和运维。相对于混合部署的方式而言,同一个平台可以减少基础架构的复杂性,以及所需要的人员技能,从而降低成本。 -
快速进行大量的数据库实例的部署
对于多租户的SaaS服务,或者大规模并行测试等这类需要同时提供大量数据库实例的场景,在容器中部署数据库不仅仅让整个过程更加简单,而且资源的利用率更高,通过命名空间也可以提供提供网络和运行实例的更好的隔离性。
3、数据库上容器的现状
目前主流的开源数据库都已经有了K8s支持,并提供了相应的Operator来方便数据库在k8s上的运维,包括MySQL、PostgreSQL、MongoDB等,以及国产的部分数据库。
传统的大型商业化数据库现在也提供了K8s支持,包括微软的SQL Server,IBM的DB2和Oracle。
二、在 Kubernetes 上部署数据库
如今,越来越多的应用部署在 Kubernetes 上的容器中,尽管在应用层(application layer)的容器化有了大量增长,但数据层(data layer)在容器化方面得到的关注并不多。
处理数据库的可持久化、对应用程序其他层的高可用性和数据库的冗余等方面,有非常具体的要求。这就使得数据库在分布式环境中运行起来很有挑战性。
然而,数据层得到更多关注,是因为很多开发者想要像处理应用层技术栈一样处理数据层基础架构。运维人员希望使用同样的工具来运维数据库和应用程序,而且数据层和应用层能达到相同的收益,跨不同环境的快速启动和可重复自动完成。
1、 Google Cloud 平台上运行数据库的选项
在探讨 Kubernetes 上运行数据库的注意事项之前,先了解下 Google Cloud 平台(GCP)上运行数据库都有哪些选项,以及这些数据库的最佳用法。
-
完全托管的数据库
包括 Cloud Spanner、Cloud Bigtable 和 Cloud SQL 等。这些都是低运维成本的选择,因为 Google Cloud 会承担很多日常维护的工作,如备份、补丁和扩展等。开发者或运维人员无需人为干预,只要创建一个数据库,构建自己的 APP,然后交给 Google Cloud 进行扩展。但这也意味着你可能无法使用到自己想要的数据库版本、扩展或某种类型的数据库。 -
在虚拟机上自行操作的数据库
也可称为“全运维选项”,构建数据库、扩展数据库、管理可靠性、配置备份等通通需要自行设定。这虽然工程量巨大,但所有的功能和数据库类型的选择都在自己的掌握之中。 -
在 Kubernetes 上运行的数据库
在 Kubernetes 上运行数据库更接近于全运维选项,但是可以从 Kubernetes 提供的自动化功能中,享受一些好处,以支持数据库应用程序的运行。话虽如此,但需要记住的是,Pods 也就是数据库应用容器是瞬时性的,所以数据库应用重启或故障切换的可能性较大。此外,由于容器化后增加了抽象功能,一些数据库管理任务,如备份、缩放、调优等,都是不一样的。
2、在 Kubernetes 上运行数据库的技巧
如果选择走 Kubernetes 路线,你需要思考运行哪些数据库,由于 Pods 至关重要,因此发生故障转移事件的可能性,比传统部署或完全托管的数据库要高。如果这个数据库内置支持分片(sharding)、故障选举(failover election)和复制等设计,那么在 Kubernetes 上运行会更简单。一些开源项目提供自定义资源和控制器,来帮助管理容器化的数据库。
接下来,考虑数据库在应用和业务的上下游中起到的作用。存储更多临时的和缓存层的数据库更适合 Kubernetes。这种类型的数据层通常在应用中更有弹性,整体体验更好。
最后,确保你了解数据库中可用的复制模式。异步传输模式可能会出现数据丢失,因为数据库事务(transaction)可能会被提交到主要数据库,而不会提交到次要数据库。因此,一定要明确是否会产生数据丢失,以及在自己的应用程序中,有多少数据丢失是可以接受的。
在评估了以上这些方面后,你最终会得到一个类似于下图这样的决策树:
3、如何在 Kubernetes 上部署数据库?
现在,深入了解一下如何使用 StatefulSets 在 Kubernetes 上部署数据库。借助 StatefulSet,你的数据可以存储在 Persistent Volume 上,将数据库应用程序与持久化存储解耦,因此当重新创建一个 Pod(如数据库应用程序)时,所有的数据依然存在。此外,当在 StatefulSet 中重新创建一个 Pod 时,它将保持相同的名称,所以你会有一个一致的端点来连接。持久数据和一致的命名是 StatefulSets 最大的两个特点(参考 Kubernetes 文档)。
如果你要运行一个不完全适合 Kubernetes 承载的数据库类型,可以考虑使用 Kubernetes Operators 或包含其他改进特性的数据库项目,使得数据库适合容器化环境运行。Operator 会帮助你启动这些数据库,并执行数据库维护任务,如备份和复制。
Operator 借助自定义资源和控制器,通过 Kubernetes API 来暴露特定操作。还有一些其围绕着各自的数据库构建了许多工具,从而可以在 Kubernetes 内部进行操作。可能包括的补充功能有分片、主从选举以及故障转移功能,这些功能都是在 Kubernetes 中成功部署 MySQL 或 PostgreSQL 等数据库所需的。
三、云原生数据库运行之Kubernetes的设计原则
长期以来,我们一直在谈论将工作负载迁移到云中,但是对许多IT组织的应用程序组合的观察表明,仍有许多工作要做。在许多情况下,尽管云中的数据库已经用了多年,但在云中持久存储和移动数据的挑战仍然是阻碍云采用的主要限制因素。
有一个有趣的问题:必须将在Kubernetes上运行的数据库视为云原生数据库吗? 虽然Kubernetes最初是为无状态工作负载设计的,但Kubernetes的最新改进(例如StatefulSets和持久卷)也使运行有状态工作负载成为可能。
但是,勉强接受在Kubernetes上运行数据库并不是我们的目标。为了使数据库成为最“云原生”的数据库,我们需要包含Kubernetes必须提供的所有内容。云原生数据库必须是可以在Kubernetes上有效运行的数据库。
下面是Kubernetes设计原则:
- 原则1:将计算、网络和存储作为商业API
云计算成功的关键之一是计算,网络和存储的商业化,这是我们可以通过简单的API进行配置的资源。考虑以下AWS服务样本:
·计算:我们通过EC2和自动伸缩组(ASG)分配虚拟机
·网络:我们使用ElasticLoadBalancer(ELB),Route53和VPC对等管理流量
·存储:我们使用诸如简单存储服务(S3)进行长期对象存储或弹性块存储(EBS)卷之类的选项来持久化数据。
Kubernetes提供了自己的API来为世界范围内的容器化应用程序提供类似的服务:
·计算:容器,部署和副本集管理计算硬件上容器的调度和生命周期
·网络:服务和入口公开了容器的网络接口
·存储:持久性卷和有状态集可实现容器与存储的灵活关联
Kubernetes资源促进了Kubernetes发行版和服务提供商之间应用程序的可移植性。这对数据库意味着什么? 它们只是利用计算,网络和存储资源来提供数据持久性和检索服务的应用程序:
·计算:数据库需要足够的处理能力来处理传入的数据和查询。每个数据库节点均作为Pod部署并分组在StatefulSets中,从而使Kubernetes能够管理横向扩展和横向扩展。
·网络:数据库需要公开用于数据和控制的接口。我们可以使用KubernetesServices和IngressControllers公开这些接口。
·存储:数据库使用指定存储类的持久卷来存储和检索数据。
从数据库的计算,网络和存储需求的角度考虑,消除了在Kubernetes上部署所涉及的许多复杂性。
-
原则2:将控制平面和数据平面分开
Kubernetes促进了控制平面和数据平面的分离。Kubernetes API服务器是用于请求计算资源的关键数据平面接口,而控制平面则管理将这些请求映射到基础IaaS平台的细节。 -
原则3:简化可观察性
可观察系统的三大支柱是日志记录,指标和跟踪。通过将每个容器的日志暴露给第三方日志聚合解决方案,Kubernetes提供了一个很好的起点。度量和跟踪需要花费更多的精力来实现,但是有多种解决方案可用。 -
原则4:确保默认配置安全
Kubernetes网络默认是安全的:必须显式公开端口才能从外部访问Pod。这为数据库部署树立了有用的先例,迫使我们仔细考虑如何公开每个控制平面和数据平面接口,以及应该通过KubernetesService公开哪些接口。 -
原则5:首选声明式配置
在Kubernetes声明性方法中,您可以指定所需的资源状态,并且控制器可以操纵底层基础结构以实现该状态。Cass-operator允许您指定集群中所需的节点数,并管理放置新节点以按比例放大以及选择要删除的节点以按比例缩小的详细信息。
以上是参考并整理的Kubernetes(K8S)与数据库的“故事”,欢迎阅读!觉得不错的话来个三连支持下博主吧~