序
发现一些用户在使用 tidb-ansible 做部署、升级等操作时,会使用成错误的版本(这里指 tidb-ansible 的版本)以及对于官网提到的常用操作命令也不是很了解,导致总会出现一些不可预期的报错,这里针对以下几个内容做一下介绍。
- Github 分支与 tidb-ansible Tag 以及 tidb 版本的关系
- tidb-ansible 的结构
- tidb-ansible 常用命令和常见问题
注:以下提到的 Github 分支都是指 github.com/pingcap/tidb-ansible 的分支
一、版本
1、Github 分支和 tidb-ansible tag
目前 tidb-ansible 主要分支有:master、release-2.1、release-2.0、release-1.1、release-1.0;在比较老的版本中 tidb-ansible 是不区分 tag 的,应一些用户的需求,我们从 v2.1.1 和 v.2.0.10 版本开始对 tidb-ansible 打 Tag,不同 Tag 的 tidb-ansible 来操作对应版本的 TiDB 集群。
-
master 分支用来部署 latest 版本(最新版本,目前就是指 3.0.0-BETA)集群,latest 版本由于还没有 GA,所以不区分 Tag。
-
release-2.1 分支用来部署 2.1.x 版本的集群,其中包含 v2.1.1 及之后版本的 Tag。不同 tag 之间会有一些 pr 的修改,可能包含参数等变更,所以建议使用相匹配的版本来操作集群,比如:
- 使用 v2.1.5 Tag 的 tidb-ansible 来部署管理 2.1.5 版本的集群
- 从 2.1.3 版本升级到 2.1.5 版本,也需要使用 v2.1.5 Tag 的 tidb-ansible 来操作
-
release-2.0 分支和 2.1 分支类似。
-
release-1.1 和 release-1.0 分支属于老版本(很少用户使用这个版本),没有 Tag。
2、下载指定 Tag 的 tidb-ansible
有两种方式:
- 从 Github 上下载打好的 Release 压缩包
- 使用 git 命令下载或者切换到指定 Tag
2.1、从 Github 上下载 Release 压缩包
- 在 Github 上打开 tidb-ansible 的 Release 页面(https://github.com/pingcap/tidb-ansible/releases)
- 可以在浏览器上直接下载,以 v2.1.6 为例,可以选择 zip 或者 tar.gz 两种压缩包
- 也可以右键复制下载链接,在 Linux 操作系统上 wget 下载
2.2 使用 Git 命令下载 tidb-ansible
- 直接 clone 指定 Tag 的 tidb-ansible,如下命令最终会下载 Tag 为 v2.1.6 的 tidb-ansible,目录默认为项目名称(即 tidb-ansible)。
git clone -b v2.1.6 https://github.com/pingcap/tidb-ansible.git # -b 即指定分支或者 Tag
- 先 clone master 分支,然后切换到指定 Tag 分支,以 v2.1.6 为例
git clone https://github.com/pingcap/tidb-ansible.git # 默认是 clone 的 master 分支
git checkout v2.1.6 # 切换到 v2.1.6 tag 的 tidb-ansible
二、tidb-ansible 结构
tidb-ansible 实际上是 playbook 和文件(binary、配置文件等)的集合。每个 playbook 都包含了一系列的操作指令,当执行 playbook 时,就会按照定义好的指令对不同节点做分发 binary、生成配置文件、启停服务等操作。这里需要注意,yml 文件对格式要求很严格,同一级别的配置一定要缩进对齐。
1、ini 文件
主要是 hosts.ini 和 inventory.ini,ini 文件以 [xxx](组名称) 分组,在 playbook 中可以定义对哪个组做哪些操作。ansible-playbook 默认使用当前目录中的 inventory.ini 文件,在 tidb-ansible/ansible.cfg 中设置。
- hosts.ini 用来初始化机器,添加用户、设置互信、同步时间等。
- inventory.ini 用来部署集群,包含集群的拓扑和一些常用变量。如果有自定义变量或者单机多个实例,ip 或者别名要区分开,一定不要相同,不然变量之间会互相覆盖。如下截图包含两个示例,每个示例中的变量都会互相覆盖,最终只会有一个生效。
2、conf 目录
顾名思义,集群的配置主要通过 conf 目录中的文件来管理,配置文件以服务名称区分。
3、scripts 目录
主要存放 Grafana Dashboard 相关的文件、环境校验脚本、日常使用常用脚本。其中 .json 文件就是我们平常监控上看到的 dashboard 的内容,也可以在 grafana 上手动 import 导入。
4、group_vars 目录
包含了不同组的变量和全局变量。需要注意的是,group_vars 中的全局/组变量优先级比 inventory.ini 中的全局/组变量优先级高,但是比 inventory.ini 中 host 后面设置的变量优先级低。
5、roles 目录
roles 里面的内容比较多,核心功能都在这个目录中,tidb-ansible 目录下的 playbook 执行时也是在调用 roles 中对应的角色。下面以 roles/pd 为例具体说明:
- defaults 是必须存在的目录,存储一些默认变量信息,这个变量的优先级最低
- files 目录存放由 copy 或 script 等模块调用的文件
- meta 目录定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它的文件需要在此文件中通过include 进行包含
- tasks 是存放 playbook 的目录,其中 main.yml 是主入口文件,在 main.yml 中导入其他 yml 文件
- templates 目录存放模板文件,template 模块会将模板文件中的变量替换为实际值,然后覆盖到客户机指定路径上
- vars 目录存放角色用到的变量,这里我们用来存放默认配置文件信息
6、常用 playbook 说明
- deploy.yml 用来部署集群。执行 deploy 操作会自动将配置文件、binary 等分发到对应的节点上;如果是已经存在的集群,执行时会对比配置文件、binary 等信息,如果有变更就会覆盖原来的文件并且将原来的文件备份到 backup(默认) 目录。
- start.yml 用来启动集群。注意:这个操作只是 start 集群,不会对配置等信息做任何更改
- stop.yml 用来停止集群。与 start 一样,不会对配置等做任何修改。
- rolling_update.yml 用来逐个更新集群内的节点。此操作会按 PD、TiKV、TiDB 的顺序以 1 并发对集群内的节点逐个做 stop → deploy → start 操作,其中对 PD 和 TiKV 操作时会先迁移掉 leader,将对集群的影响降到最低。一般用来对集群做配置更新或者升级。
- rolling_update_monitor.yml 用来逐个更新监控组件,与 rolling_update.yml 功能一样,面向的组件有区别。
- unsafe_cleanup.yml 用来清掉整个集群。这个操作会先将整个集群停掉服务,然后删除掉相关的目录,操作不可逆,需要谨慎。
- unsafe_cleanup_data.yml 用来清理掉 PD、TiKV、TiDB 的数据。执行时会先将对应服务停止,然后再清理数据,操作不可逆,需要谨慎。这个操作不涉及监控。
三、tidb-ansible 常见命令和问题
1、常用命令
- ansible-playbook deploy.yml -l 192.168.1.100,tikv1
-l 参数指定对哪些节点做操作,可以指定 ip 或者别名。以 deploy.yml 为例,假如 192.168.1.100 存在于 tidb_servers 和 monitored_servers 两个组中,会在该节点上做两个组对应的 task。
- ansible-playbook deploy.yml --tags=tidb,tikv
–tags 可以指定执行哪些 Task,这些 Task 和 Tags 是在 playbook 中设置的,其中有一个特殊的 Tags: all 表示每次都会执行对应的 task。当需要精确的在某个节点上部署某个服务时,可以同时使用 --tags 和 -l。
- ansible all -m shell -a “date”
调用 shell 模块,获取所有机器的时间。当调用 shell 模块时,-a “xxx” 中可以使用大多数系统命令来获取需要的信息。比如:hostname、ps aux |grep tidb-server、df -h 等。
2、权限
权限不对会导致执行时候产生莫名的异常,下面是最常见的两个相关场景,需要规避。
- 不要将 tidb-ansible 放到 /root 目录下
- 不要随意修改 tidb-ansible 的目录和文件的权限
3、import grafana dashboards 失败
一般有如下几种原因:
- apikey 匹配不上
- inventory.ini 中设置的 grafana 用户名密码不正确
- 防火墙端口限制
- grafana 上 prometheus 数据源错误,或者没有对应集群的数据源
4、wait until the xxx is up 报错
ansible 执行启动指令之后,只是通过端口或者一些 api 来判断服务没有正常启动,但是并不能看出是因为什么没有正常启动。可能是端口没有监听,也可能是服务没有正常工作,具体原因需要去看该服务的日志来判断。
5、Could not find the requested service xxx.service 报错
当使用 systemd 方式部署集群时,启动和停止都会使用类似 systemctl start/stop xxx.service 的方式,当相关服务的 service 文件不存在时就会报错。
6、Failed to connect to the host via ssh
该错误实际上从字面意思就能看出来了,是指通过 ssh 连接其他节点失败,有几个可能原因:
- 到对应机器的网络不可达
- ssh 端口不匹配
- 如果是使用密码的方式,可能是密码不对
- 如果没有指定密码,可能是互信有问题
- 也有可能是使用了错误的用户(默认会使用当前用户的私钥去 ssh 连接 ansible_user@ip),导致私钥不匹配