作者: Kassadar


概述

在Kubernetes环境中管理TiDB集群时,意外情况可能会导致整个K8S环境的破坏。然而,如果存储卷(挂载卷)仍然存在,我们可以通过恢复这些存储卷来重新建立TiDB集群。本文档将指导您在这种情况下的恢复过程。



前提条件

  • 所有TiDB的存储卷(PV)未丢失。
  • 已知每个PV与原TiDB组件(如TiKV, PD等)的对应关系。
  • 无备份的etcd数据。
  • 原 tc(tidb-cluster.yaml)文件未丢失


恢复步骤



预备或确认 PV 和 PVC 的配置

  • 手动创建或确认 PV:
  • 确保每个 PV 的配置与之前的集群设置相匹配,特别是存储大小、访问模式和任何特定的存储类别(StorageClass)。
  • 由于原有的 PV 配置已丢失,需根据现有存储和记忆或文档中的信息重新创建 PV 对象。这要求你精确地指定存储路径、容量、访问模式等。
  • 手动创建 PVC:
  • PVC 的名称应与原集群中的名称一致,以便在重新部署 TiDB Cluster 时可以正确地绑定到指定的 PV。
    通常情况下,会由 TiDB-Operator 动态分配 PVC,其格式如下:
{component}-{clusterName}-{component}-{ordinal}
  • 各部分含义如下:
  • {component}: 指 TiDB 集群的核心组件名,如 pdtikv
  • {clusterName}: 用户在部署集群时定义的 TiDB 集群名称。
  • {ordinal}: 由 Kubernetes StatefulSet 管理的 Pod 序号,从 0 开始计数。

示例

  • 假设有一个名为 example 的 TiDB 集群,包括三个 PD 实例和三个 TiKV 实例,PVCs 将命名为:
  • PD 组件:
  • pd-example-pd-0
  • pd-example-pd-1
  • pd-example-pd-2
  • TiKV 组件:
  • tikv-example-tikv-0
  • tikv-example-tikv-1
  • tikv-example-tikv-2


解决 PV 与 PVC 的绑定问题

  • 检查和调整绑定:
  • 在部署 TiDB Cluster 之前,需要确保每个 PV 和 PVC 的配对是正确的。
  • 可以使用 claimRef 的形势绑定 PVC,例如:
cat pv.yaml
...
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-pd1
spec:
  capacity:
    storage: 10Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: pd-storage
  claimRef:
    namespace: default
    name: pd-my-pd-1
  local:
    path: /pd
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
                - node101
...
cat pvc.yaml
...
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pd-my-pd-1
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: pd-storage
  ...
kubectl apply -f pv.yaml
kubectl apply -f pvc.yaml
  • 使用命令行工具(如 kubectl)检查状态:
  • 可以使用 kubectl get pvkubectl get pvc 来查看它们的状态,确认是否已正确绑定。


应用原 TiDB Cluster 的配置文件

  • 部署 TiDB Cluster:
  • 使用之前保存的 TiDB Cluster 配置文件,通过 Kubernetes 命令行工具 kubectl 应用配置。
  • 命令示例: kubectl apply -f tidb-cluster.yaml


调整确认 PV 和 PVC 的配置

  • 尝试 PV 和 PVC 的组合
  • 调整 PV,进行多次尝试,直到成功为止。
  • 当 PV 和 PVC 与原集群不一致时,TiDB on K8S 将运行异常,并产生冲突的日志,例如:
    TiKV 无限重启
[2024/05/05 23:03:19.017 +00:00] [FATAL] [server.rs:1153] ["failed to start node: Other(\"[components/pd_client/src/util.rs:914]: duplicated store address: id:4 address:\\\"my-tikv-0.my-tikv-peer.default.svc:20160\\\" version:\\\"6.5.9\\\" peer_address:\\\"my-tikv-0.my-tikv-peer.default.svc:20160\\\" status_address:\\\"my-tikv-0.my-tikv-peer.default.svc:20180\\\" git_hash:\\\"fcbd1624b4445574af328fe78fbb683de76057c8\\\" start_timestamp:1714950176 deploy_path:\\\"/\\\" , already registered by id:1 address:\\\"my-tikv-0.my-tikv-peer.default.svc:20160\\\" version:\\\"6.5.9\\\" peer_address:\\\"my-tikv-0.my-tikv-peer.default.svc:20160\\\" status_address:\\\"my-tikv-0.my-tikv-peer.default.svc:20180\\\" git_hash:\\\"fcbd1624b4445574af328fe78fbb683de76057c8\\\" start_timestamp:1714948050 deploy_path:\\\"/\\\" last_heartbeat:1714948070862037168 node_state:Serving \")"]

PD 长时间卡住

[2024/05/05 23:31:02.703 +00:00] [WARN] [http.go:448] ["failed to find remote peer in cluster"] [local-member-id=c27e0562ab280841] [remote-peer-id-stream-handler=c27e0562ab280841] [remote-peer-id-from=c27e0562ab280841] [cluster-id=ee7cccb0a5c4e114]
  • 可通过表格的形式尝试各种组合

round

role

pv

pvc

result

1

tikv

pv-tikv1

tikv-my-tikv-0

error

1

tikv

pv-tikv2

tikv-my-tikv-2

error

1

tikv

pv-tikv3

tikv-my-tikv-1

error

2

tikv

pv-tikv1

tikv-my-tikv-1

error

2

tikv

pv-tikv2

tikv-my-tikv-0

error

2

tikv

pv-tikv3

tikv-my-tikv-2

error

3

tikv

pv-tikv1

tikv-my-tikv-2

ok

3

tikv

pv-tikv2

tikv-my-tikv-1

ok

3

tikv

pv-tikv3

tikv-my-tikv-0

ok

1

pd

pv-pd1

pd-my-pd-1

ok

1

pd

pv-pd2

pd-my-pd-0

ok

1

pd

pv-pd3

pd-my-pd-2

ok


恢复完成

经过多次的尝试,观察所有 pod 运行正常后

恢复误删的 TiDB 集群:从 Kubernetes 全毁情况下恢复_yaml