数据库对于企业来讲相当重要,所以数据库体系结构迁移到容器平台显得尤其必要。本文将介绍如何用Rancher建立产品质量数据库设置,并分析在Rancher高可用和Kubernetes中可供使用的各类选项,给你们设计产品质量数据库提供参考。node
**目标:**在本文中,咱们将介绍如何运行一个分布式产品质量数据库设置,它由Rancher进行管理,而且保证持久性。为了部署有状态的分布式Cassandra数据库,咱们将使用Stateful Sets (有状态集)以及Rancher中的Kubernetes集群。数据库
**先决条件:**假设您已经有一个由云服务商提供的Kubernetes集群。若是您想在Amazon EC2中使用Rancher 2.0建立K8s集群,能够查看Rancher的资源:api
https://rancher.com/docs/rancher/v2.x/en/cluster-provisioning/rke-clusters/node-pools/ec2/。服务器
数据库对业务相当重要,不管是数据丢失仍是泄露,都会为企业带来严重的风险。操做错误或体系结构故障均可能致使重大事件和资源的损失,这就须要故障转移系统/过程来减小数据丢失的可能。在将数据库体系结构迁移到Kubernetes以前,必须完成在容器体系结构以及裸机上运行数据库集群的成本效益分析对比,这包括评估恢复时间目标(Recovery Time Objective,RTO)以及恢复数据目标(Recovery Point Objective,RPO)的灾难恢复要求。这些分析在面对数据敏感的应用程序是很是重要,尤为当程序须要真正高可用、针对大规模和冗余须要地理分离、以及应用程序恢复要低延迟时。网络
在下文的步骤中,咱们将分析在Rancher高可用和Kubernetes中可供使用的各类选项,给你们设计产品质量数据库提供参考。架构
A.有状态系统容器架构的缺点less
部署在相似Kubernetes的集群中的容器天然是无状态并且短暂的,这意味着它们不会保持固定的身份,而且当发生错误或从新启动时会发生数据丢失和遗忘。在设计分布式数据库环境时,须要提供高可用性以及容错,这对Kubernetes的无状态体系结构提出了挑战,由于不管是复制仍是扩展都须要维护下面的状态:分布式
(1)存储;(2)身份;(3)会话;(4)集群角色。微服务
考虑到咱们的容器化应用程序,咱们立刻就能够看出无状态架构面临的挑战,咱们的应用程序须要知足一系列的要求:工具
咱们的数据库须要将数据(Data)和事务(Transactions)存储在文件中,这些文件对每一个数据库容器来讲都是持久且独有的;
数据库应用程序中的每一个容器都须要维护一个固定的身份做为数据库节点,以便咱们能够经过名称、地址或者索引将流量路由给它;
须要数据库客户端会话来维护状态,为保证一致性,需确保在状态更改以前,读写事务已经终止,并且出现持久性故障时状态转换不受影响。
个数据库节点都须要在其数据库集群中有持久化的角色,好比主机、副本或者分片,除非它们被特定的应用程序的事件更改,或者因为模式更改了而必须更改。
针对这些挑战,目前的解决方案多是将PersistentVolume附加到咱们Kubernetes pods上,它的生命周期独立于使用它的任何一个pod。可是,PersistentVolume不会向集群节点(即父节点、子节点或种子节点)提供一致的角色分配。集群不能保证在整个应用程序的生命周期中维护数据库状态,说的具体一点就是,新的容器会由非肯定的随机名称建立,而且pods能够设置在任什么时候间按照任何的顺序启动、终止或者缩放。因此咱们的挑战依然存在。
B.K8s部署分布式数据库的优势
有这么多在Kubernetes集群中部署分布式数据库的挑战,咱们是否还值得付出努力呢?Kubernetes开辟了许多优点和可能性,包括管理大量的数据库服务以及常见的自动化操做,从可恢复性、可靠性和可扩展性来支持其生命周期健康。即便在虚拟化环境中,部署数据库集群的所需的时间和成本也远低于部署裸机集群。
Stateful Sets提供了前一节中所述挑战的前进方向。在1.5版本引入了Stateful Sets以后,Kubernetes如今为存储和身份实现了有状态质量,保证了下面的内容:
每一个pod都附有一个持久卷,从pod连接到存储,这解决了A中的存储状态问题;
每一个pod都以相同的顺序开始并以相反的顺序终止,这解决了A的会话状态问题;
每一个pod都有一个惟一且可肯定的名称、地址和序号索引,用于解决A中的身份和集群角色问题。
C.部署带有Headless服务的有状态集
注意:这部分咱们会使用到kubectl服务。关于如何使用Rancher来部署kubectl服务能够参考这里:
https://rancher.com/docs/rancher/v2.x/en/k8s-in-rancher/kubectl/。
Stateful Set Pods须要headless服务来管理Pods的网络身份。实际上,headless服务具备未定义的集群IP地址,这意味着在服务上没有定义集群IP。相反的,该服务定义具备选择器,当服务被访问的时候,DNS被配置成返回多个地址记录或者地址。此时,服务fqdn将使用相同的选择器映射到服务后面的全部pod IP的全部IP。
如今咱们按照这个模板来为Cassandra建立一个Headless服务:
使用get svc命令列出cassandra服务的属性:
用describe svc能够将cassandra服务的属性按照verbose格式输出:
D.为持久卷建立存储类别
在Rancher中,经过本机的Kubernetes API资源、PersistentVolume和PersistentVolumeClaim,咱们可使用各类选项来管理持久存储。Kubernetes中的存储类别告诉了咱们哪些存储类别是咱们的集群所支持的。咱们能够为持久存储设置动态配置来自动建立卷,并将其附加到pod。例如,下面的存储类将AWS做为它的存储提供者,使用类型是gp2,可用区是us-west-2a。
若是须要,还能够建立一个新的存储类,例如:
在建立有状态集时,将根据它的存储类为有状态集pod启动PersistentVolumeClaim。使用动态供应,能够根据PersistentVolumeClaim中请求的存储类为pod动态供应PersistentVolume。
您可也以经过静态供应手动建立持久卷。能够在这里阅读关于静态供应的更多信息:
https://rancher.com/docs/rancher/v2.x/en/k8s-in-rancher/volumes-and-storage/。
注意:对于静态供应,要求它具备与Cassandra服务器中的Cassandra节点数量相同的持久卷数量。
E.建立有状态集
如今咱们能够建立有状态集,它将提供咱们想要的属性:有序的部署和终止、惟一的网络名称和有状态的处理。咱们调用下面命令,启动一个Cassandra服务器:
F.验证有状态集
接着,咱们调用下面命令验证是否在Cassandra服务器中部署了有状态集:
在建立了有状态集以后,DESIRED和CURRENT应该是相等的,调用get pods命令来查看经有状态集建立的pods的顺序列表。
在节点建立期间,你能够执行nodetool state来查看Cassandra节点是否启动。
G.有状态集的扩缩容
将F步骤中的设置复制x次,调用缩放命令就能够增长或者减小有状态集的大小。在下面的示例中,咱们按照x=3进行操做。
调用get statefulsets能够验证是否有状态集已经部署到了Cassandra服务器上。
再次调用get pods来查看有状态集建立的pods顺序。须要注意的是,在部署Cassandra pods时,它们是按照顺序建立的。
咱们能够在5分钟后执行nodetool 状态检查,验证Cassandra节点是否已经加入而且造成了一个Cassandra集群。
一旦nodetool中节点的状态变动为Up/Normal,咱们就能够经过调用CQL来执行大量的数据库操做。
H.调用CQL进行数据库访问和操做
当咱们看到状态是U/N,咱们就能够调用cqlsh来访问Cassandra容器。
I.使用Cassandra做为高可用无状态数据库服务的持久层
在前面的练习中,咱们在K8s集群中部署了一个Cassandra服务,并经过PersistentVolume提供持久存储。而后,咱们使用有状态集为Cassandra集群提供有状态处理的属性,并将集群扩展到其余节点。咱们如今能够在Cassandra集群中使用CQL模式进行数据库访问和操做。CQL模式的优势是,咱们能够轻松地使用天然类型和流畅的api实现无缝数据建模,特别是在设计扩展和时间序列数据模型(如欺诈检测)的解决方案中。此外,CQL利用分区和集群keys来提升数据建模场景中的操做速度。
总 结
在本系列文章的下一篇中,咱们将探索如何在“数据库即微服务”或无状态数据库中使用Cassandra做为持久层,利用Cassandra独特的体系结构属性并使用Rancher工具集做为起点。而后,咱们将分析cassandra驱动的无状态数据库应用程序的操做性能和延迟,并评估其在设计中,边缘和云之间具备低延迟的高可用性服务的使用价值。
经过结合Cassandra和微服务架构,咱们能够探索有状态集数据库的替代方案,改善内存SQL数据库(如SAP HANA)容易出现/ifor read/write事务的延迟的问题,以及HTAP工做负载和NoSQL数据库在执行须要多个表查询或复杂过滤器的高级分析时速度较慢的问题。同时,无状态体系结构能够改善数据库由于内存异常而出现的问题。这些问题均可归因于SQL数据库中内存索引和多模型NoSQL数据库中的高内存使用。有了这两个方面的改进,将能够给大规模查询和时间序列建模提供更好的操做性能。