k8s 记录一次longhorn重启后容器pvc挂载不上的问题
这里其实记录了两个问题
- longhorn通过fsck修复文件恢复服务
- fsck修复文件导致文件损坏恢复问题
问题一
起因及报错
k8s上部署了longhorn,数据在三个节点上分别都有备份,重启服务器后发现一些statefulset的容器启动失败报错
- //有好几个statefulset的容器报错,下面是其中2个
- //nacos报错
- AttachVolume.Attach failed for volume "pvc-cc910a66-75b0-475a-84a7-bb6418c4e04a" : rpc error: code = DeadlineExceeded desc = volume pvc-cc910a66-75b0-475a-84a7-bb6418c4e04a failed to attach to node idc-general-k8s-29
- //另一个容器报错
- Unable to attach or mount volumes: unmounted volumes=[redis-data], unattached volumes=[start-scripts health redis-data config redis-tmp-conf tmp redis-standalone-token-r7tpv]: timed out waiting for the condition
解决步骤
这个错误信息表明 Kubernetes 无法将某些容器的挂载卷(Volume)附加到节点(Node)上,可能是由于 Kubernetes 调度程序无法在指定的时间内完成挂载操作所致。
-
检查节点状态:使用 kubectl get nodes 命令检查节点的状态,确保该节点处于 "Ready" 状态。
-
检查 Longhorn 状态:使用 kubectl get pods -n longhorn-system 命令检查 Longhorn 的各个组件的状态,确保 Longhorn 正常运行。
-
检查 PVC 状态:使用 kubectl get pvc 命令检查 PVC 的状态,确保 PVC 处于 "Bound" 状态。
-
检查 PV 状态:使用 kubectl get pv 命令检查 PV 的状态,确保 PV 处于 "Bound" 状态,并且已经正确绑定到 PVC。
-
检查相关的 Pod:使用 kubectl get pods 命令检查相关的 Pod 的状态,确保它们已经正确挂载了 PVC。
如果上述步骤都没有解决问题,您可以尝试删除相关的 Pod 和 PVC,然后重新创建它们。另外,您也可以尝试手动挂载 PVC 到节点上,以验证 Longhorn 存储插件是否正常工作。
本次问题处理
我是检查到第2步,kubectl get pods -n longhorn-system
发现有一个pod报错
- //查看报错pod的日志
- kubectl logs -f --tail 200 pod1231231
- //pod报错日志内容
- ime="2023-04-12T13:35:26Z" level=debug msg="device /dev/mapper/pvc-cc910a66-75b0-475a-84a7-bb6418c4e04a is not an active LUKS device: failed to run cryptsetup args: [status pvc-cc910a66-75b0-475a-84a7-bb6418c4e04a] output: error: exit status 127"
- time="2023-04-12T13:35:26Z" level=fatal msg="Error running start command: 'fsck' found errors on device /dev/longhorn/pvc-cc910a66-75b0-475a-84a7-bb6418c4e04a but could not correct them: fsck from util-linux 2.34\n/dev/longhorn/pvc-cc910a66-75b0-475a-84a7-bb6418c4e04a contains a file system with errors, check forced.\n/dev/longhorn/pvc-cc910a66-75b0-475a-84a7-bb6418c4e04a: Missing '..' in directory inode 2621443.\n\n\n/dev/longhorn/pvc-cc910a66-75b0-475a-84a7-bb6418c4e04a: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n."
看到fsck命令可以修复
因此我登录到对应的节点执行了fsck,在这一步一定注意,fsck有可能会导致文件丢失,执行前需要备份
- //修复
- fsck -y /dev/longhorn/pvc-cb074d7b-542c-4e3c-9bd7-b00af53971bc
问题二
longhorn这里部署的是三个副本,并且每天都会自动备份一次。
当我自信满满的打开Backup的时候,发现之前并没有写nfs备份的路径
没有快照的话几乎不可能恢复,好在在volume里找到了一个几小时前的备份,这里应该有个配置,每天备份一次,具体在哪里配置的还不清楚,后面有发现再补充
结合上面的存储目录
分别登录三个节点,找一下这个目录下对应的img
如果您只有 /data/longhorn/replicas/ 目录下的 volume-snap-<snapshot_id>.img 文件,而且您无法在 Longhorn 的 Web UI 中看到该快照或恢复该快照,那么您可能需要手动恢复数据。以下是一些可能有用的步骤:
创建一个新的 PVC(PersistentVolumeClaim)。您可以使用以下 YAML 文件创建一个 PVC:
- apiVersion: v1
- kind: PersistentVolumeClaim
- metadata:
- name: <pvc_name>
- spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: <pvc_size>
请将 <pvc_name>
替换为您要创建的 PVC 的名称,<pvc_size>
替换为您要申请的存储大小。请注意,accessModes
必须设置为 ReadWriteOnce
,以确保您可以将 PVC 挂载到一个节点上并写入数据。
在任何一个 Kubernetes 节点上,创建一个临时目录,并将 volume-snap-<snapshot_id>.img 文件复制到该目录中。
使用以下命令将 volume-snap-<snapshot_id>.img 文件转换为一个块设备文件(block device file):
sudo losetup -f
该命令将会输出一个可用的 loop 设备文件的路径,例如 /dev/loop0
。然后,可以使用以下命令将 volume-snap-<snapshot_id>.img
文件映射到该 loop 设备上:
sudo losetup /dev/loop0 /path/to/volume-snap-<snapshot_id>.img
请将 /path/to/volume-snap-<snapshot_id>.img
替换为 volume-snap-<snapshot_id>.img
文件的实际路径。
根据需要,对该 loop 设备文件执行文件系统检查和修复。例如,如果您的文件系统是 ext4,可以使用以下命令检查和修复文件系统:
- sudo e2fsck -f /dev/loop0
- sudo resize2fs /dev/loop0
请注意,您应该始终在映射到 loop 设备上的文件系统上执行检查和修复操作,而不是在原始映像文件上执行操作。
将该 loop 设备文件挂载到新创建的 PVC 上。您可以使用以下命令将其挂载到 /mnt/data 目录:
- sudo mkdir /mnt/data
- sudo mount /dev/loop0 /mnt/data
然后,您可以通过 /mnt/data
目录访问并恢复数据。
请注意,手动恢复数据可能比使用 Longhorn 的快照恢复功能更容易出错,并且可能需要更长的时间。因此,如果您有其他可用的快照或备份,请首先尝试使用这些方法来恢复您的数据。
我的是mysql数据库文件损坏,所以到这一步,能从img文件转换成linux文件夹,可以拷贝走数据文件,后面的就比较简单了,再起一个数据库,把数据库的文件恢复到新的数据库,然后dump迁移走就可以了
- 最后还是给自己长个记性,重启服务器前记得还有个服务longhorn,一共三个节点,连着重启两个节点,数据会丢失,而恰巧你又没做备份,只能这样恢复数据。重启时尽量关注longhorn,节点数据同步完成后再重启下一台,同时在longhorn做好快照,方便出现问题及时恢复。