虚拟机问题排查

本页介绍了如何针对 Google Distributed Cloud (GDC) 气隙设备中的 Application Operator (AO) 排查虚拟机 (VM) 问题。

恢复存储空间已满的虚拟机启动磁盘

如果虚拟机的启动磁盘空间不足(例如,当应用使用日志填满启动磁盘分区时),虚拟机上的关键功能将无法正常运行。您可能无法通过 VirtualMachineAccessRequest 资源添加新的 SSH 密钥,也无法使用现有密钥建立与虚拟机的 SSH 连接。

本页介绍了创建新虚拟机并将磁盘附加到新虚拟机以恢复内容作为附加磁盘的步骤。这些步骤演示了以下内容:

  • 成功通过 SSH 连接到新虚拟机。
  • 通过装载磁盘来增加空间,以恢复和删除不必要的数据。
  • 删除新虚拟机,并将原始磁盘替换为原始虚拟机。

准备工作

在继续操作之前,请确保您请求的是项目级虚拟机访问权限。按照给定的步骤分配 Project VirtualMachine Admin (project-vm-admin) 角色。

对于使用 gdcloud CLI 的虚拟机操作,请让项目 IAM 管理员为您分配“Project VirtualMachine Admin”角色和“Project Viewer”角色 (project-viewer)。

如需使用 gdcloud 命令行界面 (CLI) 命令,请确保您已下载、安装并配置 gdcloud CLI。GDC 隔网设备的全部命令都使用 gdcloudkubectl CLI,并且需要操作系统 (OS) 环境。

获取 kubeconfig 文件路径

如需针对管理 API 服务器运行命令,请确保您拥有以下资源:

  1. 找到管理 API 服务器名称,或向平台管理员 (PA) 询问服务器名称。

  2. 登录并生成管理 API 服务器的 kubeconfig 文件(如果您还没有)。

  3. 使用该路径替换这些说明中的 MANAGEMENT_API_SERVER{"</var>"}}

恢复磁盘空间不足的虚拟机

如需恢复空间不足的虚拟机启动磁盘,请完成以下步骤:

  1. 按照停止虚拟机中的步骤停止现有虚拟机。

  2. 修改现有虚拟机:

    kubectl --kubeconfig ADMIN_KUBECONFIG edit \
        virtualmachine.virtualmachine.gdc.goog -n PROJECT VM_NAME
    

    spec 字段中的现有虚拟机磁盘名称替换为新的占位名称:

    ...
    spec:
      disks:
      - boot: true
        virtualMachineDiskRef:
          name: VM_DISK_PLACEHOLDER_NAME
    
  3. 创建新虚拟机,并使用与原始虚拟机不同的映像操作系统 (OS)。例如,如果原始磁盘使用操作系统 ubuntu-2004,则创建新虚拟机时使用 rocky-8

  4. 将原始磁盘作为附加磁盘挂接到新虚拟机:

    ...
    spec:
      disks:
      - boot: true
        autoDelete: true
        virtualMachineDiskRef:
          name: NEW_VM_DISK_NAME
      - virtualMachineDiskRef:
          name: ORIGINAL_VM_DISK_NAME
    

    替换以下内容:

    • NEW_VM_DISK_NAME:您为新虚拟机磁盘指定的名称。
    • ORIGINAL_VM_DISK_NAME:原始虚拟机磁盘的名称。
  5. 创建虚拟机并使其运行后,请按照连接到虚拟机中的说明与虚拟机建立 SSH 连接。

  6. 创建一个目录,然后将原始磁盘装载到装载点。例如 /mnt/disks/new-disk

  7. 使用额外空间检查装载目录中的文件和目录:

    cd /mnt/disks/MOUNT_DIR
    du -hs -- * | sort -rh | head -10
    

    MOUNT_DIR 替换为装载原始磁盘的目录的名称。

    输出类似于以下内容:

    18G   home
    1.4G  usr
    331M  var
    56M   boot
    5.8M  etc
    36K   snap
    24K   tmp
    16K   lost+found
    16K   dev
    8.0K  run
    
  8. 检查每个文件和目录,验证它们各自使用的空间量。此示例检查 home 目录,因为它使用了 18G 的空间。

    cd home
    du -hs -- * | sort -rh | head -10
    

    输出类似于以下内容:

    17G   log_file
    ...
    4.0K  readme.md
    4.0K  main.go
    

    示例文件 log_file 是要清除的文件,因为它占用了 17G 的空间,而且不是必需的。

  9. 删除占用额外空间的不必要文件,或将文件备份到新的虚拟机启动磁盘:

    • 移动要保留的文件:

      mv /mnt/disks/MOUNT_DIR/home/FILENAME/home/backup/
      
    • 删除占用过多空间的文件:

      rm /mnt/disks/MOUNT_DIR/home/FILENAME
      

      FILENAME 替换为您要移动或删除的文件的名称。

  10. 退出新虚拟机并停止虚拟机

  11. 修改新虚拟机,从 spec 字段中移除原始磁盘:

    kubectl --kubeconfig ADMIN_KUBECONFIG \
        edit virtualmachine.virtualmachine.gdc.goog -n PROJECT NEW_VM_NAME
    

    移除包含原始虚拟机磁盘名称的 virtualMachineDiskRef 列表:

    spec:
      disks:
      - autoDelete: true
        boot: true
        virtualMachineDiskRef:
          name: NEW_VM_DISK_NAME
      - virtualMachineDiskRef: # Remove this list
          name: ORIGINAL_VM_DISK_NAME # Remove this disk name
    
  12. 修改原始虚拟机,并将您在第 2 步中设置的 VM_DISK_PLACEHOLDER_NAME 替换为之前的名称:

    ...
    spec:
      disks:
      - boot: true
        virtualMachineDiskRef:
          name: VM_DISK_PLACEHOLDER_NAME # Replace this name with the previous VM name
    
  13. 启动原始虚拟机。如果您已清理足够的空间,虚拟机将成功启动。

  14. 如果您不需要新虚拟机,请将其删除:

    kubectl --kubeconfig ADMIN_KUBECONFIG \
        delete virtualmachine.virtualmachine.gdc.goog -n PROJECT NEW_VM_NAME
    

预配虚拟机

本部分介绍了如何排查在 Google Distributed Cloud (GDC) 气隙设备中预配新虚拟机 (VM) 时可能出现的问题。

应用操作员 (AO) 必须针对默认用户集群运行所有命令。

无法创建磁盘

如果 PersistentVolumeClaim (PVC) 处于 Pending 状态,请查看以下替代方案以解决此状态:

  • 相应存储类不支持创建具有 ReadWriteMany 访问模式的 PVC:

    1. 使用支持 ReadWriteMany 访问模式并使用容器存储接口 (CSI) 驱动程序作为其存储空间配置程序的存储类更新虚拟机的 spec.dataVolumeTemplate.spec.pvc.storageClassName 值。

    2. 如果集群上没有其他存储类可以提供 ReadWriteMany 功能,请更新 spec.dataVolumeTemplate.spec.pvc.accessMode 值以包含 ReadWriteOnce 访问模式。

  • CSI 驱动程序无法预配 PersistentVolume

    1. 检查是否有错误消息:

      kubectl describe pvc VM_NAME-boot-dv -n NAMESPACE_NAME
      

      执行以下变量替换操作:

      • VM_NAME:虚拟机的名称。
      • NAMESPACE_NAME:命名空间的名称。
    2. 配置驱动程序以解决该错误。为确保 PersistentVolume 配置正常运行,请在新的 spec 中创建一个测试 PVC,其名称与 dataVolumeTemplate.spec.pvc 中指定的名称不同:

      cat <<EOF | kubectl apply -
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: test-pvc
        namespace: NAMESPACE_NAME
      spec:
        storageClassName: standard-rwx
        accessModes:
        - ReadWriteMany
        resources:
          requests:
            storage: 10Gi
      EOF
      
    3. 成功完成 PersistentVolume 对象配置后,在验证后删除测试 PVC:

      kubectl delete pvc test-pvc -n NAMESPACE_NAME
      

无法创建虚拟机

如果虚拟机资源已应用,但未达到 Running 状态,请按以下步骤操作:

  1. 查看虚拟机日志:

    kubectl get vm VM_NAME -n NAMESPACE_NAME
    
  2. 检查虚拟机的相应 Pod 状态:

    kubectl get pod -l kubevirt.io/vm=VM_NAME
    

    输出显示了 Pod 状态。可能的选项如下:

ContainerCreating 状态

如果 Pod 处于 ContainerCreating 状态,请按以下步骤操作:

  1. 获取有关 Pod 状态的更多详细信息:

    kubectl get pod -l kubevirt.io/vm=VM_NAME
    
  2. 如果卷已卸载,请确保 spec.volumes 字段中指定的所有卷都已成功装载。如果卷是磁盘,请检查磁盘状态。

  3. spec.accessCredentials 字段用于指定装载 SSH 公钥的值。确保在与虚拟机相同的命名空间中创建 Secret。

如果集群上没有足够的资源来创建 Pod,请按以下步骤操作:

  1. 如果集群没有足够的计算资源来调度虚拟机 Pod,请移除其他不需要的 Pod 以释放资源。

  2. 降低虚拟机的 spec.domain.resources.requests.cpuspec.domain.resources.requests.memory 值。

ErrorCrashLoopBackoff 状态

如需解决处于 ErrorCrashLoopBackoff 状态的 Pod,请从虚拟机计算 Pod 中检索日志:

kubectl logs -l  kubevirt.io/vm=VM_NAME  -c compute

Running 状态和虚拟机故障

如果 Pod 处于 Running 状态,但虚拟机本身出现故障,请按以下步骤操作:

  1. 查看虚拟机日志 Pod 中的日志:

    kubectl logs -l  kubevirt.io/vm=VM_NAME  -c log
    
  2. 如果日志显示虚拟机启动时出现错误,请检查虚拟机的正确启动设备。将主启动磁盘的 spec.domain.devices.disks.bootOrder 值设置为 1。请参考以下示例:

      spec:
          domain:
            devices:
              disks:
              - bootOrder: 1
                disk:
                  bus: virtio
                name: VM_NAME-boot-dv
      

如需排查虚拟机映像的配置问题,请使用其他映像创建另一个虚拟机。

访问串行控制台

本部分介绍如何使用虚拟机实例的串行控制台来调试启动和网络问题、排查实例故障、与 GRand Unified Bootloader (GRUB) 进行交互,以及执行其他问题排查任务。

与串行端口交互类似于使用终端窗口:输入和输出均采用文本模式,不支持图形界面。实例的操作系统 (OS)、基本输入和输出 (BIOS) 通常将输出写入串行端口,并接受输入(例如命令)。

如需获取对串行控制台的访问权限,请完成以下各部分中的步骤:

配置用户名和密码

默认情况下,GDC Linux 系统映像未配置为允许本地用户使用密码登录。

如果您的虚拟机正在运行预先配置了串行控制台登录的映像,您可以在虚拟机上设置本地密码,并通过串行控制台登录。在 GDC Linux 虚拟机中,您可以在虚拟机创建期间或创建后,通过保存为 Kubernetes Secret 的启动脚本配置用户名和密码。

以下说明介绍如何在创建虚拟机后设置本地密码。如需配置用户名和密码,请完成以下步骤:

  1. 创建文本文件。
  2. 在文本文件中,配置用户名和密码:

    #!/bin/bash
    username="USERNAME"
    password="PASSWORD"
    sudo useradd -m -s /bin/bash "$username"
    echo "$username:$password" | sudo chpasswd
    sudo usermod -aG sudo "$username"
    

    替换以下内容:

    • USERNAME:您要添加的用户名。
    • PASSWORD:用户名的密码。 避免使用基本密码,因为某些操作系统可能对密码长度和复杂度有最低要求。
  3. 以 Kubernetes Secret 的形式创建启动脚本:

    kubectl --kubeconfig=ADMIN_KUBECONFIG create secret \
    generic STARTUP_SCRIPT_NAME -n PROJECT_NAMESPACE \
    --from-file=STARTUP_SCRIPT_PATH
    

    替换以下内容:

    • PROJECT_NAMESPACE:虚拟机所在项目的命名空间。
    • STARTUP_SCRIPT_NAME: the name you give to the startup script. For example,configure-credentials`。
    • STARTUP_SCRIPT_PATH:包含您配置的用户名和密码的启动脚本的路径。
  4. 停止虚拟机

  5. 修改虚拟机规范:

    kubectl --kubeconfig=ADMIN_KUBECONFIG edit gvm \
    -n PROJECT_NAMESPACE VM_NAME
    

    VM_NAME 替换为要在启动脚本中添加的虚拟机的名称。

  6. startupScripts 字段中,添加您在第 3 步中创建的 Kubernetes Secret 引用:

    spec:
      compute:
        memory: 8Gi
        vcpus: 8
      disks:
      - boot: true
        virtualMachineDiskRef:
          name: disk-name 
      startupScripts:
      - name: STARTUP_SCRIPT_NAME
        scriptSecretRef:
          name: STARTUP_SCRIPT_NAME
    
  7. 启动虚拟机

    • 如果您正在使用新的虚拟机,请跳过此步骤。

访问虚拟机串行控制台

如需开始访问虚拟机串行控制台,请执行以下操作:

  1. 连接到串行控制台:

    gdcloud compute connect-to-serial-port VM_NAME \
    --project PROJECT_NAMESPACE
    
  2. 在系统提示时,输入您在配置用户名和密码中定义的用户名和密码。