这篇文章已超过一年。较旧的文章可能包含过时内容。请检查页面信息自发布以来是否未失效。
如何在 Kubernetes 中为 TPR 集成 RollingUpdate 策略
使用 Kubernetes,开箱即用地管理和扩展无状态应用(如 Web 应用和 API 服务)非常容易。迄今为止,关于 Kubernetes 的讨论几乎都围绕着微服务和无状态应用。
随着基于容器的微服务架构的普及,部署和管理 RDBMS(关系型数据库管理系统)的需求非常强烈。RDBMS 需要经验丰富的数据库特定知识来进行正确的扩展、升级和重新配置,同时还要防止数据丢失或不可用。
例如,MySQL(最流行的开源 RDBMS)需要将数据存储在持久且对每个 MySQL 数据库存储独占的文件中。每个 MySQL 数据库都需要独立区分,更复杂的场景是在集群中需要将一个 MySQL 数据库从集群中区分出不同的角色,例如主库、从库或分片。在高可用性和零数据丢失方面,替换故障机器上的数据库节点也很难实现。
利用强大的 Kubernetes API 扩展机制,我们可以将 RDBMS 领域知识编码到名为 WQ-RDS 的软件中,使其像内置资源一样在 Kubernetes 上运行。
WQ-RDS 利用 Kubernetes 的基础资源和控制器,提供了一系列企业级功能,并带来了一种非常可靠的方式来自动化耗时的操作任务,例如数据库设置、修补备份以及建立高可用集群。WQ-RDS 支持主流版本的 Oracle 和 MySQL(两者都兼容 MariaDB)。
让我们演示如何管理一个 MySQL 分片集群。
MySQL 分片集群
MySQL 分片集群是一种横向扩展的数据库架构。基于哈希算法,该架构将数据分布到集群的所有分片中。分片对客户端完全透明:代理能够连接到集群中的任何分片,并直接向正确的分片发出查询。
| ----- |
| |
|
注意:每个分片对应一个独立的 MySQL 实例。目前,WQ-RDS 最多支持 64 个分片。
|
所有分片都使用 Kubernetes Statefulset、Service、Storage Class、ConfigMap、Secret 和 MySQL 构建。WQ-RDS 管理分片集群的整个生命周期。分片集群的优点是显而易见的:
- 横向扩展每秒查询次数 (QPS) 和每秒事务数 (TPS)
- 横向扩展存储容量:通过将数据分布到多个节点获得更多存储空间
创建 MySQL 分片集群
让我们创建一个包含 8 个分片的 Kubernetes 集群。
kubectl create -f mysqlshardingcluster.yaml
接下来,创建一个包含 8 个分片的 MySQL 分片集群。
- TPR:MysqlCluster 和 MysqlDatabase
[root@k8s-master ~]# kubectl get mysqlcluster
NAME KIND
clustershard-c MysqlCluster.v1.mysql.orain.com
从 clustershard-c0 到 clustershard-c7 的 MysqlDatabase 属于 MysqlCluster clustershard-c。
[root@k8s-master ~]# kubectl get mysqldatabase
NAME KIND
clustershard-c0 MysqlDatabase.v1.mysql.orain.com
clustershard-c1 MysqlDatabase.v1.mysql.orain.com
clustershard-c2 MysqlDatabase.v1.mysql.orain.com
clustershard-c3 MysqlDatabase.v1.mysql.orain.com
clustershard-c4 MysqlDatabase.v1.mysql.orain.com
clustershard-c5 MysqlDatabase.v1.mysql.orain.com
clustershard-c6 MysqlDatabase.v1.mysql.orain.com
clustershard-c7 MysqlDatabase.v1.mysql.orain.com
接下来,让我们看看两个主要特性:高可用性和 RollingUpdate 策略。
为了演示,我们将首先运行 sysbench 在集群上生成一些负载。在此示例中,QPS 指标由 MySQL export 生成,由 Prometheus 收集,并在 Grafana 中可视化呈现。
特性:高可用性
WQ-RDS 处理 MySQL 实例崩溃,同时防止数据丢失。
当终止 clustershard-c0 时,WQ-RDS 将检测到 clustershard-c0 不可用,并在故障机器上替换 clustershard-c0,平均耗时约 35 秒。
同时实现零数据丢失。
特性:RollingUpdate 策略
MySQL 分片集群不仅带来了强大的可伸缩性,还带来了一定程度的维护复杂性。例如,当更新 MySQL 配置(如 innodb_buffer_pool_size)时,数据库管理员(DBA)必须执行许多步骤:
1. 应用更改时间。
2. 禁用客户端访问数据库代理。
3. 启动滚动升级。
滚动升级需要按顺序进行,是过程中要求最高的步骤。在先前的 MySQL 实例更新运行并就绪之前,无法继续滚动升级。
4. 验证集群。
5. 启用客户端访问数据库代理。
滚动升级可能遇到的问题包括:
- 节点重启
- MySQL 实例重启
- 人为错误 相反,WQ-RDS 使 DBA 能够自动执行滚动升级。
Kubernetes 中的 StatefulSet RollingUpdate
Kubernetes 1.7 包含一个重要特性,为 StatefulSet 添加了自动化更新,并支持多种更新策略,包括滚动更新。
注意:有关 StatefulSet 滚动更新的更多信息,请参阅 Kubernetes 文档。
因为 TPR(目前是 CRD)不支持滚动升级策略,我们需要将 RollingUpdate 策略集成到 WQ-RDS 中。幸运的是,Kubernetes 仓库是一个学习的宝库。在实现过程中,有一些要点可以分享:
**MySQL 分片集群已**更改:每个 StatefulSet 都有其对应的 ControllerRevision,它记录所有修订数据和顺序(就像 git)。无论何时 StatefulSet 进行同步,StatefulSet 控制器都会首先将其 spec 与最新的相应 ControllerRevision 数据进行比较(类似于 git diff)。如果发生更改,将生成一个新的 ControllerRevision,并且修订号将加 1。WQ-RDS 借鉴了这一过程,MySQL 分片集群对象将在 ControllerRevision 中记录所有修订和顺序。
**如何初始化 MySQL 分片集群以满足请求的**副本数:StatefulSet 支持两种 Pod 管理策略:Parallel 和 OrderedReady。由于 MySQL 分片集群的初始过程不需要有序创建,我们使用 Parallel 策略来加速集群的初始化。
**如何执行**滚动升级:StatefulSet 以严格递减的顺序重新创建 Pod。不同之处在于 WQ-RDS 更新分片而不是重新创建它们,如下所示:
**滚动更新何时结束**:Kubernetes 会清晰地标记终止。当一个集合的所有 Pod 都已更新到 updateRevision 时,滚动更新完成。status 的 currentRevision 被设置为 updateRevision,其 updateRevision 被设置为空字符串。status 的 currentReplicas 被设置为 updateReplicas,其 updateReplicas 被设置为 0。
WQ-RDS 中的 Controller Revision
修订信息存储在 MysqlCluster.Status 中,与 StatefulSet.Status 没有区别。
root@k8s-master ~]# kubectl get mysqlcluster -o yaml clustershard-c
apiVersion: v1
items:
\- apiVersion: mysql.orain.com/v1
kind: MysqlCluster
metadata:
creationTimestamp: 2017-10-20T08:19:41Z
labels:
AppName: clustershard-crm
Createdby: orain.com
DBType: MySQL
name: clustershard-c
namespace: default
resourceVersion: "415852"
uid: 6bb089bb-b56f-11e7-ae02-525400e717a6
spec:
dbresourcespec:
limitedcpu: 1200m
limitedmemory: 400Mi
requestcpu: 1000m
requestmemory: 400Mi
status:
currentReplicas: 8
currentRevision: clustershard-c-648d878965
replicas: 8
updateRevision: clustershard-c-648d878965
kind: List
示例:执行滚动升级
最后,我们现在可以更新 "clustershard-c" 将配置 "innodb_buffer_pool_size" 从 6GB 更新到 7GB 并重启。
该过程耗时 480 秒。
升级以单调递减的方式进行
结论
滚动升级对数据库管理员来说意义重大。它提供了一种更有效的方式来操作数据库。