维护 TiDB 集群所在的 Kubernetes 节点
TiDB 是高可用数据库,可以在部分数据库节点下线的情况下正常运行,因此,我们可以安全地对底层 Kubernetes 节点进行停机维护。在具体操作时,针对 PD、TiKV 和 TiDB 实例的不同特性,我们需要采取不同的操作策略。
本文档将详细介绍如何对 Kubernetes 节点进行临时或长期的维护操作。
环境准备:
注意:
长期维护节点前,需要保证 Kubernetes 集群的剩余资源足够运行 TiDB 集群。
维护 PD 和 TiDB 实例所在节点
PD 和 TiDB 实例的迁移较快,可以采取主动驱逐实例到其它节点上的策略进行节点维护:
检查待维护节点上是否有 TiKV 实例:
kubectl get pod --all-namespaces -o wide | grep ${node_name}
假如存在 TiKV 实例,请参考维护 TiKV 实例所在节点
TiKV 实例迁移较慢,并且会对集群造成一定的数据迁移负载,因此在维护 TiKV 实例所在节点前,需要根据维护需求选择操作策略:
- 假如是维护短期内可恢复的节点,则不需要迁移 TiKV 节点,在维护结束后原地恢复节点;
- 假如是维护短期内不可恢复的节点,则需要规划 TiKV 的迁移工作。
维护短期内可恢复的节点
针对短期维护,我们可以通过调整 PD 集群的
max-store-down-time
配置来增大集群所允许的 TiKV 实例下线时间,在此时间内维护完毕并恢复 Kubernetes 节点后,所有该节点上的 TiKV 实例会自动恢复。kubectl port-forward svc/${CLUSTER_NAME}-pd 2379:2379
pd-ctl -d config set max-store-down-time 10m
调整
max-store-down-time
到合理的值后,后续的操作方式与维护短期内不可恢复的节点针对短期内不可恢复的节点维护,如节点长期下线等情形,需要使用
pd-ctl
主动通知 TiDB 集群下线对应的 TiKV 实例,再手动解除 TiKV 实例与该节点的绑定。使用
kubectl cordon
命令防止新的 Pod 调度到待维护节点上:kubectl cordon ${node_name}
查看待维护节点上的 TiKV 实例:
tkctl get -A tikv | grep ${node_name}
使用
pd-ctl
主动下线 TiKV 实例。注意:
下线 TiKV 实例前,需要保证集群中剩余的 TiKV 实例数不少于 PD 配置中的 TiKV 数据副本数(配置项:
max-replicas
)。假如不符合该条件,需要先操作扩容 TiKV。查看 TiKV 实例的
store-id
:kubectl get tc ${CLUSTER_NAME} -ojson | jq '.status.tikv.stores | .[] | select ( .podName == "${POD_NAME}" ) | .id'
下线实例:
kubectl port-forward svc/${CLUSTER_NAME}-pd 2379:2379
pd-ctl -d store delete ${ID}
等待 store 状态(
state_name
)转移为Tombstone
:watch pd-ctl -d store ${ID}
解除 TiKV 实例与节点本地盘的绑定。
查询 Pod 使用的
PesistentVolumeClaim
:kubectl get -n ${namespace} pod ${pod_name} -ojson | jq '.spec.volumes | .[] | select (.name == "tikv") | .persistentVolumeClaim.claimName'
删除该
PesistentVolumeClaim
:kubectl delete -n ${namespace} pvc ${pvc_name}
删除 TiKV 实例:
kubectl delete -n ${namespace} pod ${pod_name}
观察该 TiKV 实例是否正常调度到其它节点上:
watch kubectl -n ${namespace} get pod -o wide
假如待维护节点上还有其它 TiKV 实例,则重复同样的操作步骤直到所有的 TiKV 实例都迁移到其它节点上。
确认节点不再有 TiKV 实例后,再逐出节点上的其它实例:
kubectl drain ${node_name} --ignore-daemonsets --delete-local-data
再次确认节点不再有任何 TiKV、TiDB 和 PD 实例运行:
kubectl get pod --all-namespaces | grep ${node_name}
最后(可选),假如是长期下线节点,建议将节点从 Kubernetes 集群中删除:
kubectl delete node ${node_name}
至此,操作完成。