TiOperator对PVC做了不恰当的操作,导致概率出现PV绑定了错误的PVC,从而导致PD或TIKV一直pending

Bug 反馈

集群个别服务器节点故障恢复等情况下,PD或TIKV的PVC与PV绑定错误,导致PD或TIKV一直pending,无法启动。

【 TiDB 版本】 6.5.8
【 Bug 的影响】 出现此故障后集群部分节点不可用

【可能的问题复现步骤】
1、集群运行过程中个别服务器节点故障离线或网络故障,运维修复后节点重新上线。
2、集群运行一段时间,个别服务器节点物理损坏,新加入新节点。

【看到的非预期行为】 故障节点对应的PV绑定了错误的PVC,猜测为TiOperator对PVC做了操作,导致原来的PVC被删除,但是PV又没有正确释放,仍然处于released状态;而新的PVC没有办法绑定,导致对应的POD一直pending。该情况出现在PD和TIKV;常见的其他三方开源的组件,同样使用statefulset部署,仅依赖K8S管理,却没有这个问题。

【期望看到的行为】 根据对其他三方开源组件的使用判断,TiOperator不用对PVC做任何操作,保持绑定,就不会出现绑定错乱。

【相关组件及具体版本】 TiOperator 1.4、1.5

【其他背景信息或者截图】
node-1:/ # kubectl get pv -n namespace | grep pd
pv-local-tidb-pd-namespace-node-1 1Gi RWO Retain Bound namespace/pd-basic-pd-2 tidb-pd-storage-namespace 30h
pv-local-tidb-pd-namespace-node-2 1Gi RWO Retain Bound namespace/pd-basic-pd-1 tidb-pd-storage-namespace 30h
pv-local-tidb-pd-namespace-node-3 1Gi RWO Retain Released namespace/pd-basic-pd-0 tidb-pd-storage-namespace 30h
node-1:/ # kubectl get pvc -n namespace | grep pd
pd-basic-pd-0 Pending tidb-pd-storage-namespace 29h
pd-basic-pd-1 Bound pv-local-tidb-pd-namespace-node-2 1Gi RWO tidb-pd-storage-namespace 30h
pd-basic-pd-2 Bound pv-local-tidb-pd-namespace-node-1 1Gi RWO tidb-pd-storage-namespace 30h
pd-basic-pd-3 Pending tidb-pd-storage-namespace 29h
node-1:/ # kubectl describe pv -n namespace pv-local-tidb-pd-namespace-node-3
Name: pv-local-tidb-pd-namespace-node-3
Labels: app.kubernetes.io/component=pd
app.kubernetes.io/instance=basic
app.kubernetes.io/managed-by=tidb-operator
app.kubernetes.io/name=tidb-cluster
app.kubernetes.io/namespace=namespace
ns=namespace
tidb.pingcap.com/cluster-id=7413947050473649857
tidb.pingcap.com/member-id=14365345130030816002
Annotations: pv.kubernetes.io/bound-by-controller: yes
tidb.pingcap.com/pod-name: basic-pd-0
Finalizers: [kubernetes.io/pv-protection]
StorageClass: tidb-pd-storage-namespace
Status: Released
Claim: namespace/pd-basic-pd-0
Reclaim Policy: Retain
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 1Gi
Node Affinity:
Required Terms:
Term 0: kubernetes.io/hostname in [node-3]
Message:
Source:
Type: LocalVolume (a persistent volume backed by local storage on a node)
Path: /home/datas/namespace/tidb/pd
Events:
node-1:/ # kubectl describe pvc -n namespace pd-basic-pd-0
Name: pd-basic-pd-0
Namespace: namespace
StorageClass: tidb-pd-storage-namespace
Status: Pending
Volume:
Labels: app.kubernetes.io/component=pd
app.kubernetes.io/instance=basic
app.kubernetes.io/managed-by=tidb-operator
app.kubernetes.io/name=tidb-cluster
tidb.pingcap.com/cluster-id=7413947050473649857
tidb.pingcap.com/pod-name=basic-pd-0
Annotations: tidb.pingcap.com/pod-name: basic-pd-0
Finalizers: [kubernetes.io/pvc-protection]
Capacity:
Access Modes:
VolumeMode: Filesystem
Used By: basic-pd-0
Events:
Type Reason Age From Message


Normal WaitForPodScheduled 2m44s (x6964 over 29h) persistentvolume-controller waiting for pod basic-pd-0 to be scheduled
node-1:/ # kubectl describe pvc -n namespace pd-basic-pd-3
Name: pd-basic-pd-3
Namespace: namespace
StorageClass: tidb-pd-storage-namespace
Status: Pending
Volume:
Labels: app.kubernetes.io/component=pd
app.kubernetes.io/instance=basic
app.kubernetes.io/managed-by=tidb-operator
app.kubernetes.io/name=tidb-cluster
tidb.pingcap.com/cluster-id=7413947050473649857
tidb.pingcap.com/pod-name=basic-pd-3
Annotations: tidb.pingcap.com/pod-name: basic-pd-3
Finalizers: [kubernetes.io/pvc-protection]
Capacity:
Access Modes:
VolumeMode: Filesystem
Used By: basic-pd-3
Events:
Type Reason Age From Message


Normal WaitForPodScheduled 2m21s (x6984 over 29h) persistentvolume-controller waiting for pod basic-pd-3 to be scheduled

相关pv-local-tidb-pd-namespace-node-3的信息如下:
apiVersion: v1
kind: PersistentVolume
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{“apiVersion”:“v1”,“kind”:“PersistentVolume”,“metadata”:{“annotations”:{},“labels”:{“ns”:“namespace”},“name”:“pv-local-tidb-pd-namespace-node-3”},“spec”:{“accessModes”:[“ReadWriteOnce”],“capacity”:{“storage”:“1Gi”},“local”:{“path”:“/home/datas/namespace/tidb/pd”},“nodeAffinity”:{“required”:{“nodeSelectorTerms”:[{“matchExpressions”:[{“key”:“kubernetes.io/hostname",“operator”:“In”,“values”:[“node-3”]}]}]}},“persistentVolumeReclaimPolicy”:“Retain”,“storageClassName”:“tidb-pd-storage-namespace”,“volumeMode”:"Filesystem”}}
pv.kubernetes.io/bound-by-controller: “yes”
tidb.pingcap.com/pod-name: basic-pd-0
creationTimestamp: “2024-09-13T02:20:39Z”
finalizers:

但是对应的pvc pd-basic-pd-0 信息如下:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
tidb.pingcap.com/pod-name: basic-pd-0
creationTimestamp: “2024-09-13T03:29:05Z”
finalizers:

1 个赞

本地盘的pv就是这样的,本地盘没法飘。只能删了pvc重建。
坏一台物理机可以直接删了pvc删了pod重建。

你说的其他的可以的是不用本地盘吗?具体你贴的yaml文件比较长,着急下班先不看了。一般来说我们绑定本地盘的机器坏掉就这样操作的:删pvc、删tikv、等待节点补上。

1 个赞

现在的情况是多个PVC同时起来了,都在想绑定到这个PV0,而PV0却绑定到另外一个不存在的PVC

今天仔细看了看你这个情况,好解决。
首先确认下, pd-basic-pd-3 这个pvc对应的pd是不是 operator补出来的节点?实际上从来没工作过对吗?这样确认:

kubectl exec -it pd-basic-pd-3 -n namespace -- sh  # 替换到对的pod和namespace名
./pd-ctl member # 看看有没有新增加的 pd-3,如果就没有,那说明新增加的pd-3根本就没上线过,那直接删掉pd-3和他对应的pvc就可以,

接下来就是处理 pd-0 的pv,因为是 released状态,没法直接绑定。
kubectl edit pv pv-local-tidb-pd-namespace-node-3
删掉其中的:

claimRef:
....

这样这个pv就变成了aviable 了。

你的pd-0这个pvc应该能绑定上了。

你这个应该不是简单的重启吧,估计是删过pvc吧。

或者,如果确定pd-basic-pd-2 和 pd-basic-pd-1 都能正常运行,从上面的pd-ctl member 看看状态,正常的话,直接删掉pd-0这个pvc和pd-0的pv,然后重新建一个全新的pv,等待pvc绑定也可以。你这个环境pv应该是手动创建的吧,你看看怎么操作简单吧。

操作生产环境的话慎重,别删错了。

我们这个环境是模拟节点损坏后,重新挂一个新的节点上来。重新在物理机的目录下创建了pd的物理目录。

那你的意思是让pd-3能正常跑起来是吗?那得给pd-3搞个pv。
你的环境pv不是全自动分配的,得手动搞。