写点什么

K8S 上 TiDB 集群升级卡住问题探讨

  • 2022 年 7 月 11 日
  • 本文字数:1832 字

    阅读完需:约 6 分钟

作者: zhuboshuai 原文来源:https://tidb.net/blog/5fa22034

现象

最近把 TiDB Operator 升级到 v1.1.0 后,打算把 tidbcluster 也升级到较高版本。按照常规操作准备了镜像,执行 kubectl edit命令后开始观察集群升级状态:


watch kubectl -n ${namespace} get pod -o wide


结果发现某个 pd 的 pod 已经处于反复重启状态,于是开始排查。

排查

因为之前在 K8S 上遇到过类似 pd 集群不正常的问题,所以沿用以前思路首先查看 pd 集群的 API 是否正常:


wget -c http://tidb-cluster-prod-pd.tidb-cluster-prod:2379/pd/api/v1/members


使用 ClusterIP 访问以确认底层网络是否正常:


wget -c http://${ClusterIP}:2379/pd/api/v1/members


结果是 pd 集群的 API 可以正常访问。


查看集群 tidbcluster CR 的 yaml 和 pd 的 StatefulSet 的 yaml 没有发现问题。


于是查看相应 pod 的日志:


kubect logs -f ${clustername}-pd-2


日志如下:


2020/06/16 11:03:04.329 log.go:86: [warning] etcdserver: [could not get cluster response from http://${clustername}-pd-4.${clustername}-pd-peer.${clustername}.svc:2380: Get http://${clustername}-pd-4.${clustername}-pd-peer.${clustername}.svc:2380/members: dial tcp: lookup ${clustername}-pd-4.${clustername}-pd-peer.tidbcluster->wuhanwuli.svc on ${ip}:53: no such host]


实际上集群中有 pd-0 到 pd-3 这 4 个 pod,pd-4 不在集群里:



继续查看 pd-2 日志可见 pd-2 已经从集群下线:



但是 pd-2 所在的 pod 仍然在运行。


查看和 pd-2 相关的 PV:



查看为 Released 状态的 PV 存储内容:



查看为 Bound 状态的 PV 存储内容:



发现为 Bound 状态的 PV 文件创建时间比为 Released 状态的 PV 文件创建时间还早。老的 PV 里面的 join 文件的创建时间大概是 2 月 7 日,而新 PV 里面的 join 文件的创建时间大概是 1 月 20 日,比老 join 文件还旧。


于是总结合理的时间序列如下:


  1. pd-2 发生了 failover 之后,TiDB-Operator 将这个 member 从集群中删掉了,并且删掉了 pvc 和 pd-2 的 pod

  2. pd-2 之前使用的 PV 被释放,成为 Released 状态

  3. pd-2 新 pod 和 pvc 创建,绑定了新的 PV,状态为 Bound

  4. 由于这个新绑定的 PV 里面有老数据,导致 pd-2 这个节点无法启动


查看 local-volume-provisioner 目前用的版本仍然是 v2.3.2,从 PingCAP 小伙伴那里已经收到了存在 bug 的提醒,从 TiDB DevCon 2020 也看到了相关分享,对应 bug 说明如下:


github.com/kubernetes-sigs/sig-storage-local-static-provisioner


[](https://github.com/yuyulei)

Remove old cleanup status before create new pv

by yuyulei on 01:29PM - 18 Feb 20 UTC


1 commits changed 1 files with 7 additions and 0 deletions.


这个 bug 会导致 PV 对象重建了,但是里面的数据未清理。还没有来得及升级 local-volume-provisioner 就碰到了这个坑。

恢复方法

可以将 pd-2 现在使用的 PV 里面的数据删除,让 /var/lib/pd 目录为空,这样 pd-2 就会作为一个新的 member 启动,重新加入到整个 pd 集群。


kubectl get pv | grep pd-2


找到对应的 Local PV:


kubectl get pv local-pv-xxxx -oyaml


从以上输出中找到对应目录删除所有内容,然后观察所有 pod 状态。


watch kubectl get po -n ${namespace}


可以看到 pd 全部重启并恢复 Running 状态,然后其它组件也相继升级成功:


隐患排查和解决

  1. 排查所有目前状态为 Available 的 PV,确认目录为空

  2. kubectl get pv | grep Available | grep local-storage-pd | awk '{print $1}' | xargs kubectl get pv -oyaml | egrep 'kubernetes.io/hostname|path

  3. 找到所有目录逐一排查。

  4. 备注:本环境中 pd 的 storageclass 为 local-storage-pd

  5. local-volume-provisioner 升级到 2.3.4:

  6. docker pull quay.io/external_storage/local-volume-provisioner:v2.3.4

  7. docker tag quay.io/external_storage/local-volume-provisioner:v2.3.4 ${registry address}/tidb/local-volume-provisioner:2.3.4

  8. docker push ${registry address}/tidb/local-volume-provisioner:2.3.4

  9. 编辑 local-volume-provisioner:

  10. kubectl edit ds local-volume-provisioner -oyaml -n kube-system

  11. 修改 spec.template.spec.image 保存后观察升级情况:

  12. watch kubectl get po -l app=local-volume-provisioner -n kube-system

  13. 可见 local-volume-provisioner 已经升级成功。

后记

截止目前,K8S 上的 TiDB 集群已正常运行两周,没有再发现问题。


同时感谢 PingCAP 小伙伴的大力支持!


发布于: 刚刚阅读数: 2
用户头像

TiDB 社区官网:https://tidb.net/ 2021.12.15 加入

TiDB 社区干货传送门是由 TiDB 社区中布道师组委会自发组织的 TiDB 社区优质内容对外宣布的栏目,旨在加深 TiDBer 之间的交流和学习。一起构建有爱、互助、共创共建的 TiDB 社区 https://tidb.net/

评论

发布
暂无评论
K8S上TiDB集群升级卡住问题探讨_TiDB 社区干货传送门_InfoQ写作社区