TiDB on Kubernetes 最佳实践

百家 作者:PingCAP 2020-09-14 21:59:33

作者介绍

吴叶磊, PingCAP Cloud 工程师。


随着 Kubernetes(K8s) 的全面成熟,越来越多的组织开始大规模地基于 K8s 构建基础设施层。然而,考虑到数据库在架构中的核心地位与 K8s 在有状态应用编排上的短板,仍有不少组织认为在 K8s 上运行核心数据库会带来颇高的风险。事实上,在 K8s 上运行 TiDB 不仅能实现企业技术栈的统一,降低维护成本,还能带来更高的可用性与安全性。本次分享将介绍 TiDB 在 K8s 上的运维管理系统 TiDB Operator,再从各类故障场景入手剖析 TiDB on K8s 如何实现高效的故障自愈并保障数据安全。最后,我们会分享来自国内外一线公司的 TiDB Operator 生产环境案例,并总结出一套 TiDB on K8s 最佳实践。


要不要在 Kubernetes 上运行 TiDB ?


这个问题其实一直以来也有很多的争议。大家都知道,Kubernetes 的很多概念是为无状态应用(比如微服务)所设计的。由于云原生技术的不断普及,Kubernetes 目前在国内外的很多技术领域都得到大规模的落地,有一种全盘上 Kubernetes 的趋势。但在这期间也有不少人提出了质疑,比如:是不是所有的业务场景都适合 Kubernetes ?我们的组织是不是真的需要 Kubernetes?这样的争议,其实这背后的各种声音都有各自的出发点。

首先 Kubernetes 有没有价值?肯定有价值,它的普及度就是很好的证明。那 Kubernetes 有没有问题?当然也有问题,比如, Kubernetes 会增上技术上的复杂度,此外它还有有比较大的迁移成本。

回到 TiDB 要不要在 Kubernetes 上面运行这个问题。答案其实往往来自于你当前的技术栈和技术团队。

举个例子,假如你的大部分应用已经上了 Kubernetes,而且你的工程师也对 Kubernetes 很熟悉,在 Kubernetes 上去做一些业务,他感觉非常舒服,那么 TiDB 就不该成为一个例外。换句话说,如果当前整个组织的业务都已经上 Kubernetes 了,但还需要专门招一个运维团队在虚拟机上运维 TiDB 的话,不仅会增加额外的维护成本,也没办法发挥出技术栈投资的规模优势。

那么,在 K8s 运行 TiDB,我们想要什么呢?通常,我们想要的是 TiDB 可以和我们在 K8s 上运行的微服务一样,可以做到声明式管理,通过 K8s 实现 TiDB 的自动化运维以及弹性资源配置。我想扩容的时候,并不需要去专门开新的物理机,专门购买一批机器,而是直接从整个的 K8s 资源池中,弹性的给 TiDB 分配一些资源进行扩容,然后再缩容之后又把这些资源还回去。

可是,现在的情况是,即使很多公司已经上了 K8s,但对于把数据库放在 K8s 上运行还是有一定的担忧,这个担忧主要在哪儿呢?

从我个人了解到的信息来说,核心是稳定性,稳定性,最后还是稳定性,因为毕竟我们要上的是数据库。几年前,大家刚开始上 K8s 的时候,会觉得我的业务上在 K8s 上用的很爽,那要不要把数据库也搞上去?那总会有一种声音是,数据库怎么能上 K8s 呢?我们数据库的稳定性要求比 K8s 还要高啊!假如 K8s 挂了,那可能只是线上的微服务无法提供服务,但是假如数据库挂了,我们不仅无法提供服务,还有可能面临数据丢失的风险。所以通常来说,在组织中,数据库可靠性是处于一个核心地位的,也因此在数据库上 K8s 时,一个核心的担忧就是可靠性。

那么,我们在部署传统数据库应用的时候,是怎么保证稳定性的?一般来说,是开几台固定的物理机,然后我们会把数据库的 Binary 传上去运行起来,这时候要点就是,运行起来之后只要不出问题就不要再动它(If it works don't touch it)。即使要动它,也需要经过一个非常严苛的审计流程和预演,保证它最佳的稳定性。听起来,对于传统的关系型数据库而言,高度动态化的 K8s 环境并不是一个很好的解决方案。

那为什么还会推荐大家把 TiDB 放在 K8s 上运行呢?

第一点,TiDB 本身能够适应动态化的 K8s 环境。

  • TiDB 可以多副本做容错,当挂掉一个集群当中的小数节点并不会对整个集群的运行产生影响;

  • TiDB 能够很好的借助 K8s 环境做水平伸缩;

  • TiDB 提供了开箱自用的可观测性,大家基本上把 TiDB 部署起来,就可以看到 TiDB 的所有指标,即使是在一个动态化混部的环境里面,也能很清楚的明白 TiDB 现在的状态是什么,即使有副本挂掉,也没有问题。

第二点,反回来,K8s 也能很高效的去撬动 TiDB 的潜力。

  • 声明式 API 简化集群管理,作为一个分布式数据库,TiDB 的管理会比传统的单机数据库相对复杂一点,而在 K8s 上,它的声明是 API,就能把这一点多出来的复杂度很好的消化掉;

  • 弹性资源池简化扩容缩与故障转移, TiDB 的故障容忍和无限的水平伸缩都需要额外的资源,比如说,我们去横向扩张 TiDB 集群时,需要申请一部分新的资源进来,在故障容错之后,要做故障转移把故障副本数补齐。那么 K8s 的弹性资源池就能很好的把 TiDB 在水平伸缩和故障容忍上的潜力发挥出来。

因此, TiDB 和 K8s 能够非常好的进行一个结合,并且释放出更大的潜力达成 1+1 大于 2 的效果的。这当然不是一个巧合,这背后的原因是,TiDB 和 K8s 都遵循同样的云原生最佳实践原则。那么假如说我们已经熟悉 TiDB 和 K8s 的知识,只要稍微花费一些工夫,用 K8s 的云原生对象就可以部署一个 TiDB 集群,而且能运行的不错。

但是,TiDB 和 Kuberentes 都有大量的最佳实践,基本上你想快速看完是有点困难的。那么,我们在 K8s 上部署 TiDB 的时候,应该怎样去遵守最佳实践呢?一个基本的办法就是把这些坑都了解清楚,并且写非常多的 run book 来告诉 SRE team,怎么去运维好它们。run book 需要口口相传,需要不断的进行知识的交互、交流。但其实大家都知道,程序员一般不喜欢做这个。

我们更喜欢把这些知识写成代码,做自动化。那么,我们怎么样把这些东西写成代码自动化呢?


TiDB on Kubernetes 运维专家:TiDB Operator


答案就是 TiDB Operator 。TiDB Operator 是什么?本质就是利用 K8s 本身的扩展机制,把领域性的运维知识编写成代码,大家可以把 TiDB Operator 理解为在 K8s 上运行 TiDB 的运维专家,把一个专家型人物对 TiDB 和 K8s 的所有知识都编写成了代码。

TiDB Operator 首先添加了一组自定义类型,比如说 TiDB Cluster,代表一个 TiDB 集群,可以在这些类型里描述你想要的 TiDB 长什么样;第二,TiDB Operator 添加了一组自定义控制器,这组自定义控制器就是这些运维知识的集合,它会用这些代码化的知识帮助你自动化的运维 K8s 上的 TiDB 集群。

看一个例子:首先是自定义类型,当 TiDB Operator 把自定义类型添加到 K8s 中后,作为用户就可以提交资源定义到 K8s 里面,比如我们需要一个 TiDB 集群,这个集群要的版本是什么,要多少 PD,要多少 KV。以及我们可以定义一个 TiDBMonitor 对象,用来监控 TiDB,在对象定义里则只需要定义我们要监控哪一个 TiDB 就可以了。

那么,大家可以发现,我们在做这些资源定义时是遵循 K8s 本身的声明式定义的。那这些的理想状态由谁来实现呢?——由自定义控制器。自定义控制器会把所有的需求和 K8s 集群里的实际状态做一个对比,对比之后就能发现两者的不同,就需要把实际状态向期望状态转移。比如说我们把刚刚的 TiDB 集群对象和 TiDB 监控对象提交到 K8s ,那么 TiDB Operator 的控制器就会帮助我们创建很多的容器以及监控。

当然,仅仅只有创建是不够的,TiDB Operator 中还集成了 TiDB 运维专家的所有的领域知识,下面我分享几个运维知识。

 

关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接