简介
TiDB Operator是 Kubernetes 上的 TiDB 集群自动运维系统,提供包括部署、升级、扩缩容、备份恢复、配置变更的 TiDB 全生命周期管理。借助 TiDB Operator,TiDB 可以无缝运行在公有云或私有部署的 Kubernetes 集群上,目前已开源 pingcap/tidb-operator 。
TiDB Operator 与适用的 TiDB 版本的对应关系如下:
TiDB 版本 | 适用的 TiDB Operator 版本 |
dev | dev |
TiDB >= 5.4 | 1.3 |
5.1 <= TiDB < 5.4 | 1.3(推荐),1.2 |
3.0 <= TiDB < 5.1 | 1.3(推荐),1.2,1.1 |
2.1 <= TiDB < v3.0 | 1.0(停止维护) |
为什么需要TiDB Operator
第一,TiDB Operator提供自动化部署、升级、扩缩容、备份恢复、配置变更的全生命周期管理。
TiDB 的分层架构对于分布式系统是比较常见的,各个组件都可以根据业务需求独立水平伸缩,并且 TiKV 和 TiDB 都可以独立使用。比如,在 TiKV 之上可以构建兼容 Redis 协议的 KV 数据库,而 TiDB 也可以对接 LevelDB 这样的 KV 存储引擎。但是,这种多组件的分布式系统增加了手工部署和运维的成本。一些传统的自动化部署和运维工具如 Puppet/Chef/SaltStack/Ansible,由于缺乏全局状态管理,不能及时对各种异常情况做自动故障转移,并且很难发挥分布式系统的弹性伸缩能力。其中有些还需要写大量的 DSL 甚至与 Shell 脚本一起混合使用,可移植性较差,维护成本比较高。
第二,在云时代容器成为应用分发部署的基本单位,Kubernetes 成为当前容器编排技术上的标准。
如今各大云厂商都开始提供托管的 Kubernetes 集群,部署在 Kubernetes 平台的应用可以不用绑定在特定云平台,轻松实现在各种云平台之间的迁移,其容器化打包和发布方式也解决了对操作系统环境的依赖。
为了在 Kubernetes 上部署和管理 TiDB 这种有状态的服务,我们需要扩展 StatefulSet 的功能。TiDB Operator 正是基于 Kubernetes 内置的 StatefulSet 云原生开发的 TiDB 集群管理和运维工具。官方本地 PV 方案直到最近的 Kubernetes v1.10 才相对稳定地支持调度功能(需要运行在 Kubernetes v1.10 及以上版本),满足用户对本地 PV 的需求。为了降低用户的使用和管理成本并且拥抱 Kubernetes 开源社区。
第三,执行操作需要TiDB相关的知识。
在通过TiDB Operator部署tidb集群时,需要了解tidb集群的架构,各服务组件的关系以及启动都有相关的顺序的,在扩缩容的时候需要按照相应的组件进行操作。
核心亮点
轻松部署TiDB群集
能安全扩展在TiDB的集群的每个组件,TiDB Operator 则通过自定义资源对象(Custom Resource)、自定义控制器(Custom controller)和调度器扩展(Scheduler extender)为 Kubernetes 注入 TiDB 的专业运维知识,允许用户以 Kubernetes 的声明式 API 风格来管理 TiDB 集群。具体来说,用户只需要描述集群规格,TiDB Operator 就会不断调整 Kubernetes 中的资源,驱动实际集群满足该描述。在这种模式下,TiDB 集群会自动完成服务的健康检查、故障转移,而部署、升级、扩缩容等操作则能通过修改集群的规格定义“一键”完成,极大简化了 TiDB 集群的运维管理
滚动更新。
在没有任何停机的情况下,平稳地执行滚动更新,各服务组件在更新的过程中会逐个进行,当完成后才会有其他的pod进行,出现问题便于快速回滚。
多租户支持
用户可以使用TiDB Operator在单个Kubernetes集群上部署和管理多个TiDB集群。
自动故障切换
当节点/Pod发生故障时,TiDB Operator自动执行故障转移切换。
简单监控
TiDB Operator支持安装Prometheus和Grafana进行集群监控
多云支持
1提供了面向 AWS、谷歌云和阿里云的 Terraform 部署脚本。 这些脚本能帮助大家在十几分钟内创建一个 Kubernetes 集群,并在该集群上部署一个或更多生产可用的 TiDB 集群。在后续的管理过程中,Terraform 脚本会在操作 TiDB 集群的同时对相关的云资源进行操作。比如,当扩容一个 TiDB 集群时,Terraform 脚本就会自动创建更多的云服务器来承载集群扩容后的资源需求。
架构
其中,TidbCluster
、TidbMonitor
、TidbInitializer
、Backup
、Restore
、BackupSchedule
、TidbClusterAutoScaler
是由 CRD(CustomResourceDefinition
)定义的自定义资源:
TidbCluster
用于描述用户期望的 TiDB 集群TidbMonitor
用于描述用户期望的 TiDB 集群监控组件TidbInitializer
用于描述用户期望的 TiDB 集群初始化 JobBackup
用于描述用户期望的 TiDB 集群备份Restore
用于描述用户期望的 TiDB 集群恢复BackupSchedule
用于描述用户期望的 TiDB 集群周期性备份TidbClusterAutoScaler
用于描述用户期望的 TiDB 集群自动伸缩
TiDB 集群的编排和调度逻辑则由下列组件负责:
tidb-controller-manager
是一组 Kubernetes 上的自定义控制器。这些控制器会不断对比TidbCluster
对象中记录的期望状态与 TiDB 集群的实际状态,并调整 Kubernetes 中的资源以驱动 TiDB 集群满足期望状态,并根据其他 CR 完成相应的控制逻辑;tidb-scheduler
是一个 Kubernetes 调度器扩展,它为 Kubernetes 调度器注入 TiDB 集群特有的调度逻辑。tidb-admission-webhook
是一个 Kubernetes 动态准入控制器,完成 Pod、StatefulSet 等相关资源的修改、验证与运维。discovery
是一个用于组件间发现的服务。每一个 TiDB 集群会对应存在一个 discovery Pod,用于该集群中组件发现其他已经创建的组件。
TiDB Controller Manager
tidb-controller-manager不断持续地调整期望状态和实际状态的差异。如果状态不匹配的话,控制器将触发动作以转换为所期待的状态,具体如下图:
TiDB Scheduler扩展调度器
TiDB Scheduler 是 Kubernetes 调度器扩展 的 TiDB 实现。TiDB Scheduler 用于向 Kubernetes 添加新的调度规则。Kubernetes 集群中默认会部署一个 kube-scheduler,用于 Pod 调度,默认调度器名字为 default-scheduler
,具体的调度规则请参考K8S-POD资源和调度 。
TiDB Scheduler 通过实现 Kubernetes 调度器扩展(Scheduler extender)来添加自定义调度规则。
TiDB Scheduler 组件部署为一个或者多个 Pod,但同时只有一个 Pod 在工作。Pod 内部有两个 Container,一个 Container 是原生的 kube-scheduler
;另外一个 Container 是 tidb-scheduler
,实现为一个 Kubernetes scheduler extender。
如果 TidbCluster
中配置组件使用 tidb-scheduler
,TiDB Operator 创建的 PD、TiDB、TiKV Pod 的 .spec.schedulerName
属性会被设置为 tidb-scheduler
,即都用 TiDB Scheduler 自定义调度器来调度。
此时,一个 Pod 的调度流程是这样的:
kube-scheduler
拉取所有.spec.schedulerName
为tidb-scheduler
的 Pod,对于每个 Pod 会首先经过 Kubernetes 默认调度规则过滤;- 在这之后,
kube-scheduler
会发请求到tidb-scheduler
服务,tidb-scheduler
会通过一些自定义的调度规则(见上述介绍)对发送过来的节点进行过滤,最终将剩余可调度的节点返回给kube-scheduler
; - 最终由
kube-scheduler
决定最终调度的节点。
TiDB Operator 准入控制器
Kubernetes 在 1.9 版本引入了 动态准入机制,从而使得拥有对 Kubernetes 中的各类资源进行修改与验证的功能。 在 TiDB Operator 中,我们也同样使用了动态准入机制来帮助我们进行相关资源的修改、验证与运维。
TiDB Operator 准入控制器与大部分 Kubernetes 平台上产品的准入控制器较为不同,TiDB Operator 通过扩展 API-Server 与 WebhookConfiguration 的两个机制组合而成。所以需要 Kubernetes 集群启用聚合层功能,通常情况下这个功能已经默认开启。如需查看是否开启聚合层功能,请参考启用 Kubernetes Apiserver 标志。
原理
Operator 本质上是 Kubernetes 的控制器(Controller),其核心思想是用户给定一个 Spec 描述文件,Controller 根据 Spec 的变化,在 Kubernetes 集群中创建对应资源,并且不断调整资源使其状态满足用户预期的 Spec。
上图是 TiDB Operator 工作流程原理图,其中 TidbCluster 是通过 CRD(Custom Resource Definition)扩展的内置资源类型:
- 用户通过 Helm 往 Kubernetes API Server 创建或更新 TidbCluster 对象。
- TiDB Operator 通过 watch API Server 中的 TidbCluster 对象创建更新或删除,维护 PD/TiKV/TiDB StatefulSet, Service 和 Deployment 对象更新。
- Kubernetes 根据 StatefulSet, Service 和 Deployment 对象创建更新或删除对应的容器和服务。
在第 2 步中,TiDB Operator 在更新 StatefulSet 等对象时会参考 PD API 给出的集群状态来做出 TiDB 集群的运维处理。通过 TiDB Operator 和 Kubernetes 的动态调度处理,创建出符合用户预期的 TiDB 集群。
安装部署TiDB Operator
安装helm
Helm 是一个 Kubernetes 的包管理工具,是查找、分享和使用软件构建 Kubernetes 的最优方式,类似 Linux 的包管理器,如RedHat系的yum、Debian的apt,可以很方便的将之前打包好的 yaml 文件部署到 Kubernetes 上。Helm主要解决以下问题:1、把yaml作为一个整体管理。2、实现yaml的高效复用。3、实现应用级别的版本管理。helm安装比较简单
Helm官方下载地址 (https://github.com/helm/helm/releases )
wget https://get.helm.sh/helm-v3.4.2-linux-amd64.tar.gz
解压Helm
tar zxvf helm-v3.4.2-linux-amd64.tar.gz
移动到主节点 /usr/bin 目录
mv linux-amd64/helm /usr/bin/
验证是否安装成功
helm version
部署TiDB Operator(离线方式)
由于客户大部分都是内网不能上外网,所以本文档以离线的方式部署TiDB Operatro
下载tidb-operator
#下载最新版本的包
wget http://charts.pingcap.org/tidb-operator-v1.4.3.tgz
#解压
tar zxvf tidb-operator.v1.4.3.tgz
下载所需的镜像,打标签并推到私有仓库
#tidb operator所用到的所有镜像
pingcap/tidb-operator:v1.4.3
pingcap/tidb-backup-manager:v1.4.3
bitnami/kubectl:latest
pingcap/advanced-statefulset:v0.3.3
k8s.gcr.io/kube-scheduler:v1.16.9
##镜像拉取并下载
docker pull pingcap/tidb-operator:v1.4.3
docker pull pingcap/tidb-backup-manager:v1.4.3
docker pull bitnami/kubectl:latest
docker pull pingcap/advanced-statefulset:v0.3.3
docker save -o tidb-operator-v1.4.3.tar pingcap/tidb-operator:v1.4.3
docker save -o tidb-backup-manager-v1.4.3.tar pingcap/tidb-backup-manager:v1.4.3
docker save -o bitnami-kubectl.tar bitnami/kubectl:latest
docker save -o advanced-statefulset-v0.3.3.tar pingcap/advanced-statefulset:v0.3.3
##上传镜像
docker load -i tidb-operator-v1.4.3.tar
docker load -i tidb-backup-manager-v1.4.3.tar
docker load -i bitnami-kubectl.tar
docker load -i advanced-statefulset-v0.3.3.tar
##备注,如果推到私有仓库需要给镜像打标签并上传
docker tag pingcap/tidb-operator:v1.4.3 xxx.com:5003/pingcap/tidb-operator:v1.4.3
docker push xxx.com:5003/pingcap/tidb-operator:v1.4.3
配置TiDB Operator
主要配置的镜像名、limits
、requests
和 replicas
,请根据需要进行修改
vim ./tidb-operator/values.yaml
clusterScoped: true
rbac:
create: true
timezone: UTC
operatorImage: pingcap/tidb-operator:v1.4.3
imagePullPolicy: IfNotPresent
tidbBackupManagerImage: pingcap/tidb-backup-manager:v1.4.3
##启用asts配置
features:
- AdvancedStatefulSet=true
advancedStatefulset:
create: true
appendReleaseSuffix: false
controllerManager:
create: true
serviceAccount: tidb-controller-manager
clusterPermissions:
nodes: true
persistentvolumes: true
storageclasses: true
logLevel: 2
replicas: 1
resources:
requests:
cpu: 80m
memory: 50Mi
autoFailover: true
pdFailoverPeriod: 5m
tikvFailoverPeriod: 5m
tidbFailoverPeriod: 5m
tiflashFailoverPeriod: 5m
dmMasterFailoverPeriod: 5m
dmWorkerFailoverPeriod: 5m
detectNodeFailure: false
affinity: {}
nodeSelector: {}
tolerations: []
selector: []
env: []
securityContext: {}
podAnnotations: {}
scheduler:
create: true
serviceAccount: tidb-scheduler
logLevel: 2
replicas: 1
schedulerName: tidb-scheduler
resources:
limits:
cpu: 250m
memory: 150Mi
requests:
cpu: 80m
memory: 50Mi
kubeSchedulerImageName: k8s.gcr.io/kube-scheduler
affinity: {}
nodeSelector: {}
tolerations: []
securityContext: {}
podAnnotations: {}
configmapAnnotations: {}
advancedStatefulset:
create: true
image: pingcap/advanced-statefulset:v0.4.0
imagePullPolicy: IfNotPresent
serviceAccount: advanced-statefulset-controller
logLevel: 4
replicas: 1
resources:
limits:
cpu: 500m
memory: 300Mi
requests:
cpu: 200m
memory: 50Mi
affinity: {}
nodeSelector: {}
tolerations: []
securityContext: {}
admissionWebhook:
create: false
replicas: 1
serviceAccount: tidb-admission-webhook
logLevel: 2
rbac:
create: true
validation:
statefulSets: false
pingcapResources: false
mutation:
pingcapResources: true
failurePolicy:
validation: Fail
mutation: Fail
apiservice:
insecureSkipTLSVerify: true
tlsSecret: ""
caBundle: ""
cabundle: ""
securityContext: {}
nodeSelector: {}
tolerations: []
安装TiDB Operator
kubectl create ns tidb-admin
helm install tidb-operator ./tidb-operator --namespace=tidb-admin
升级TiDB Operator
helm upgrade tidb-operator ./tidb-operator --namespace=tidb-admin