排查存储问题

本文档介绍存储问题排查指南。

无法挂接卷

如果虚拟磁盘挂接到错误的虚拟机,则可能出现此问题,原因可能是 Kubernetes 1.12 中的问题 #32727

gkectl diagnose cluster 的输出结果如下所示:

Checking cluster object...PASS
Checking machine objects...PASS
Checking control plane pods...PASS
Checking gke-connect pods...PASS
Checking kube-system pods...PASS
Checking gke-system pods...PASS
Checking storage...FAIL
    PersistentVolume pvc-776459c3-d350-11e9-9db8-e297f465bc84: virtual disk "[datastore_nfs] kubevols/kubernetes-dynamic-pvc-776459c3-d350-11e9-9db8-e297f465bc84.vmdk" IS attached to machine "gsl-test-user-9b46dbf9b-9wdj7" but IS NOT listed in the Node.Status
1 storage errors

一个或多个 Pod 卡在 ContainerCreating 状态,并显示如下警告:

Events:
  Type     Reason              Age               From                     Message
  ----     ------              ----              ----                     -------
  Warning  FailedAttachVolume  6s (x6 over 31s)  attachdetach-controller  AttachVolume.Attach failed for volume "pvc-776459c3-d350-11e9-9db8-e297f465bc84" : Failed to add disk 'scsi0:6'.

要解决此问题,请执行以下操作:

如果虚拟磁盘挂接到了错误的虚拟机,您可能需要手动将其分离:

  1. 排空节点。 请参阅安全排空节点。您可能需要在 kubectl drain 命令中添加 --ignore-daemonsets--delete-local-data 标志。

  2. 关闭虚拟机电源

  3. 在 vCenter 中修改虚拟机的硬件配置以移除卷。

  4. 开启虚拟机

  5. 取消封锁节点

卷丢失

如果虚拟磁盘已被永久删除,则可能会出现此问题。如果操作人员手动删除虚拟磁盘或其挂接的虚拟机,则可能会发生这种情况。如果您看到与 VMDK 文件相关的“未找到”错误,则可能是因为虚拟磁盘已被永久删除。

gkectl diagnose cluster 的输出结果如下所示:

Checking cluster object...PASS
Checking machine objects...PASS
Checking control plane pods...PASS
Checking gke-connect pods...PASS
Checking kube-system pods...PASS
Checking gke-system pods...PASS
Checking storage...FAIL
    PersistentVolume pvc-52161704-d350-11e9-9db8-e297f465bc84: virtual disk "[datastore_nfs] kubevols/kubernetes-dynamic-pvc-52161704-d350-11e9-9db8-e297f465bc84.vmdk" IS NOT found
1 storage errors

一个或多个 Pod 卡在 ContainerCreating 状态:

Events:
  Type     Reason              Age                   From                                    Message
  ----     ------              ----                  ----                                    -------
  Warning  FailedAttachVolume  71s (x28 over 42m)    attachdetach-controller                 AttachVolume.Attach failed for volume "pvc-52161704-d350-11e9-9db8-e297f465bc84" : File []/vmfs/volumes/43416d29-03095e58/kubevols/
  kubernetes-dynamic-pvc-52161704-d350-11e9-9db8-e297f465bc84.vmdk was not found

为了防止出现此问题,请按照调整用户集群大小升级集群中所述管理虚拟机。

如需解决此问题,您可能需要手动清理相关的 Kubernetes 资源:

  1. 通过运行 kubectl delete pvc [PVC_NAME] 删除引用了 PV 的 PVC。

  2. 通过运行 kubectl delete pod [POD_NAME] 删除引用了 PVC 的 Pod。

  3. 重复第 2 步。是的,确实是这样。请参阅 Kubernetes 问题 74374

vSphere CSI 卷分离失败

如果没有向 vSphere 用户授予 CNS > Searchable 权限,则会出现此问题。

如果您发现 pod 卡在 ContainerCreating 阶段并显示 FailedAttachVolume 警告,这可能是由于其他节点上的分离失败造成的。

如需检查是否存在 CSI 分离错误,请运行以下命令:

kubectl get volumeattachments -o=custom-columns=NAME:metadata.name,DETACH_ERROR:status.detachError.message

输出内容类似如下:

NAME                                                                   DETACH_ERROR
csi-0e80d9be14dc09a49e1997cc17fc69dd8ce58254bd48d0d8e26a554d930a91e5   rpc error: code = Internal desc = QueryVolume failed for volumeID: "57549b5d-0ad3-48a9-aeca-42e64a773469". ServerFaultCode: NoPermission
csi-164d56e3286e954befdf0f5a82d59031dbfd50709c927a0e6ccf21d1fa60192d   
csi-8d9c3d0439f413fa9e176c63f5cc92bd67a33a1b76919d42c20347d52c57435c   
csi-e40d65005bc64c45735e91d7f7e54b2481a2bd41f5df7cc219a2c03608e8e7a8   

如需解决此问题,请为您的 vcenter 用户帐号添加 CNS > Searchable 权限。分离操作会自动重试,直到执行成功。

ESXi 主机不支持 vSphere CSI 驱动程序

当 vSphere 集群中的 ESXi 主机运行低于 ESXi 6.7U3 的版本时,会出现此问题。

gkectl check-config 的输出包含此警告:

The vSphere CSI driver is not supported on current ESXi host versions.
CSI requires ESXi 6.7U3 or above. See logs for ESXi version details.

要解决此问题,请将 ESXi 主机升级到 6.7U3 或更高版本。

CSI 卷创建失败并显示 NotSupported 错误

当 vSphere 集群中的 ESXi 主机运行低于 ESXi 6.7U3 的版本时,会出现此问题。

kubectl describe pvc 的输出包含此错误:

Failed to provision volume with StorageClass : rpc error:
code = Internal desc = Failed to create volume. Error: CnsFault error:
CNS: Failed to create disk.:Fault cause: vmodl.fault.NotSupported

要解决此问题,请将 ESXi 主机升级到 6.7U3 或更高版本。

vSphere CSI 卷挂接失败

在节点关停、删除或失败时会发生开源 vSphere CSI 驱动程序中的已知问题

kubectl describe pod 的输出结果如下所示:

Events:
 Type    Reason                 From                     Message
 ----    ------             ... ----                     -------
 Warning FailedAttachVolume ... attachdetach-controller  Multi-Attach error for volume
                                                         "pvc-xxxxx"
                                                         Volume is already exclusively attached to one
                                                         node and can't be attached to another

要解决此问题,请执行以下操作:

  1. 记下上述输出中的 PersistentVolumeClaim (PVC) 名称,然后找到与 PVC 关联的 VolumeAttachment。例如:

    kubectl get volumeattachments | grep pvc-xxxxx
    

    输出会显示 VolumeAttachment 的名称。例如:

    csi-yyyyy   csi.vsphere.vmware.com   pvc-xxxxx   node-zzzzz ...
    
  2. 描述 VolumeAttachment。例如:

    kubectl describe volumeattachments csi-yyyyy | grep "Deletion Timestamp"
    

    记下输出中的删除时间戳:

    Deletion Timestamp:   2021-03-10T22:14:58Z
    
  3. 等待删除时间戳指定的时间,然后强制删除 VolumeAttachment。为此,请修改 VolumeAttachment 对象并删除终结器。例如:

    kubectl edit volumeattachment csi-yyyyy
     Finalizers:
      external-attacher/csi-vsphere-vmware-com
    

vSphere CSI VolumeSnapshot 由于版本无法准备就绪

当 vCenter Server 或 ESXi 主机版本低于 7.0 Update 3 时,就会出现此问题。

kubectl describe volumesnapshot 的输出包含如下错误:

rpc error: code = Unimplemented desc = VC version does not support snapshot operations.

如需解决此问题,请将 vCenter Server 和 ESXi 主机升级到 7.0 Update 3 或更高版本。

vSphere CSI VolumeSnapshot 由于每个卷的快照数上限无法准备就绪

当每个卷的快照数达到 vSphere 容器存储驱动程序的最大值时,就会出现此问题。默认值为 3 个。

kubectl describe volumesnapshot 的输出包含如下错误:

rpc error: code = FailedPrecondition desc = the number of snapshots on the source volume 5394aac1-bc0a-44e2-a519-1a46b187af7b reaches the configured maximum (3)

如需解决此问题,请按照以下步骤更新每个卷的快照数上限:

  1. 获取向 vSphere CSI 控制器提供 vSphere 配置的 Secret 的名称:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG get deployment vsphere-csi-controller \
       --namespace USER_CLUSTER_NAME \
       --output json \
       | jq -r '.spec.template.spec.volumes[] \
       | select(.name=="vsphere-secret") .secret.secretName'
    

    请替换以下内容:

    • ADMIN_KUBECONFIG:管理员集群 kubeconfig 文件的路径
    • USER_CLUSTER_NAME:您的用户集群的名称
  2. 从 Secret 中获取 data.config 的值,对其进行 base64 解码,然后将其保存在名为 config.txt 的文件中:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG get secret SECRET_NAME \
       --namespace USER_CLUSTER_NAME  \
       --output json | jq -r '.data["config"]' | base64 -d > config.txt
    

    SECRET_NAME 替换为上一步中 Secret 的名称。

  3. 打开 config.txt 进行修改:

    [Snapshot] 部分中修改或添加 global-max-snapshots-per-block-volume 字段。例如:

    [Global]
    cluster-id = "my-user-cluster"
    insecure-flag = "0"
    user = "my-account.local"
    password = "fxqSD@SZTUIsG"
    [VirtualCenter "my-vCenter"]
    port = "443"
    datacenters = "my-datacenter1"
    [Snapshot]
    global-max-snapshots-per-block-volume = 4
    
  4. 删除并重新创建 Secret:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG delete secret SECRET_NAME \
       --namespace USER_CLUSTER_NAME
    
    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG create secret generic SECRET_NAME \
       --namespace USER_CLUSTER_NAME \
       --from-file=config
    
  5. 重启 vsphere-csi-controller Deployment:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG rollout restart deployment vsphere-csi-controller \
       --namespace USER_CLUSTER_NAME