가상 머신 문제 해결

이 페이지에서는 Google Distributed Cloud (GDC) 에어갭 어플라이언스의 애플리케이션 운영자 (AO)용 가상 머신 (VM) 문제 해결 방법을 다룹니다.

전체 VM 부팅 디스크 복구

애플리케이션이 로그로 부팅 디스크 파티션을 채우는 등 VM의 부팅 디스크 공간이 부족하면 VM의 중요한 기능이 작동하지 않습니다. VirtualMachineAccessRequest 리소스를 통해 새 SSH 키를 추가하거나 기존 키를 사용하여 VM에 SSH 연결을 설정하지 못할 수 있습니다.

이 페이지에서는 새 VM을 만들고 디스크를 연결하여 콘텐츠를 새 VM에 추가 디스크로 복구하는 단계를 설명합니다. 이 단계에서는 다음을 보여줍니다.

  • 새 VM에 대한 SSH 연결이 성공적으로 이루어집니다.
  • 디스크를 마운트하여 공간을 늘려 불필요한 데이터를 복구하고 삭제합니다.
  • 새 VM을 삭제하고 원본 디스크를 원본 VM으로 바꿉니다.

시작하기 전에

계속하기 전에 프로젝트 수준 VM 액세스를 요청해야 합니다. 제공된 단계에 따라 프로젝트 VirtualMachine 관리자 (project-vm-admin) 역할을 할당합니다.

gdcloud CLI를 사용하는 VM 작업의 경우 프로젝트 IAM 관리자에게 프로젝트 VirtualMachine 관리자 역할과 프로젝트 뷰어 (project-viewer) 역할을 모두 할당해 달라고 요청하세요.

gdcloud 명령줄 인터페이스 (CLI) 명령어를 사용하려면 gdcloud CLI를 다운로드, 설치, 구성해야 합니다. GDC 오프라인 어플라이언스의 모든 명령어는 gdcloud 또는 kubectl CLI를 사용하며 운영체제 (OS) 환경이 필요합니다.

kubeconfig 파일 경로 가져오기

관리 API 서버에 대해 명령어를 실행하려면 다음 리소스가 있어야 합니다.

  1. 관리 API 서버 이름을 찾거나 플랫폼 관리자 (PA)에게 서버 이름을 문의합니다.

  2. 관리 API 서버의 kubeconfig 파일이 없는 경우 로그인 및 생성합니다.

  3. 이 안내에서 경로를 사용하여 MANAGEMENT_API_SERVER{"</var>"}}을 바꿉니다.

공간이 부족한 VM 디스크 복구

공간이 부족한 VM 부팅 디스크를 복구하려면 다음 단계를 완료하세요.

  1. VM 중지에 따라 기존 VM을 중지합니다.

  2. 기존 VM을 수정합니다.

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

    spec 필드의 기존 VM 디스크 이름을 새 자리표시자 이름으로 바꿉니다.

    ...
    spec:
      disks:
      - boot: true
        virtualMachineDiskRef:
          name: VM_DISK_PLACEHOLDER_NAME
    
  3. 원래 VM과 다른 이미지 운영체제 (OS)로 새 VM을 만듭니다. 예를 들어 원래 디스크에서 OS ubuntu-2004를 사용하는 경우 rocky-8로 새 VM을 만듭니다.

  4. 원래 디스크를 새 VM에 추가 디스크로 연결합니다.

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

    다음을 바꿉니다.

    • NEW_VM_DISK_NAME: 새 VM 디스크에 지정하는 이름입니다.
    • ORIGINAL_VM_DISK_NAME: 원래 VM 디스크의 이름입니다.
  5. VM을 만들고 실행 중인 후 VM에 연결에 따라 VM에 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. 각 파일과 디렉터리를 확인하여 각 항목이 사용하는 공간의 크기를 확인합니다. 이 예시에서는 18G 공간을 사용하므로 home 디렉터리를 확인합니다.

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

    출력은 다음과 비슷합니다.

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

    log_file 파일은 공간을 17G만큼 사용하고 필요하지 않으므로 삭제할 파일입니다.

  9. 추가 공간을 차지하는 불필요한 파일을 삭제하거나 파일을 새 VM 부팅 디스크에 백업합니다.

    • 보관할 파일을 이동합니다.

      mv /mnt/disks/MOUNT_DIR/home/FILENAME/home/backup/
      
    • 추가 공간을 차지하는 파일을 삭제합니다.

      rm /mnt/disks/MOUNT_DIR/home/FILENAME
      

      FILENAME을 이동하거나 삭제할 파일의 이름으로 바꿉니다.

  10. 새 VM에서 로그아웃하고 VM을 중지합니다.

  11. 새 VM을 수정하여 spec 필드에서 원래 디스크를 삭제합니다.

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

    원본 VM 디스크 이름을 포함하는 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. 원본 VM을 수정하고 2단계에서 설정한 VM_DISK_PLACEHOLDER_NAME을 이전 이름으로 바꿉니다.

    ...
    spec:
      disks:
      - boot: true
        virtualMachineDiskRef:
          name: VM_DISK_PLACEHOLDER_NAME # Replace this name with the previous VM name
    
  13. 기존 VM을 시작합니다. 공간을 충분히 확보했다면 VM이 정상적으로 부팅됩니다.

  14. 새 VM이 필요하지 않으면 VM을 삭제합니다.

    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 기능을 제공할 수 없는 경우 ReadWriteOnce 액세스 모드를 포함하도록 spec.dataVolumeTemplate.spec.pvc.accessMode 값을 업데이트합니다.

  • CSI 드라이버가 PersistentVolume를 프로비저닝할 수 없습니다.

    1. 오류 메시지를 확인합니다.

      kubectl describe pvc VM_NAME-boot-dv -n NAMESPACE_NAME
      

      다음 변수를 바꿉니다.

      • VM_NAME: 가상 머신의 이름입니다.
      • NAMESPACE_NAME: 네임스페이스의 이름입니다.
    2. 드라이버를 구성하여 오류를 해결합니다. PersistentVolume 프로비저닝이 작동하는지 확인하려면 dataVolumeTemplate.spec.pvc에 지정된 이름과 다른 이름으로 새 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. 가상 머신의 해당 포드 상태를 확인합니다.

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

    출력에 포드 상태가 표시됩니다. 가능한 옵션은 다음과 같습니다.

ContainerCreating 상태

포드가 ContainerCreating 상태인 경우 다음 단계를 따르세요.

  1. 포드 상태에 관한 추가 세부정보를 가져옵니다.

    kubectl get pod -l kubevirt.io/vm=VM_NAME
    
  2. 볼륨이 마운트 해제된 경우 spec.volumes 필드에 지정된 모든 볼륨이 성공적으로 마운트되었는지 확인합니다. 볼륨이 디스크인 경우 디스크 상태를 확인합니다.

  3. spec.accessCredentials 필드는 SSH 공개 키를 마운트할 값을 지정합니다. 보안 비밀이 가상 머신과 동일한 네임스페이스에 생성되어 있는지 확인합니다.

클러스터에 포드를 만들기에 충분한 리소스가 없는 경우 다음 단계를 따르세요.

  1. 가상 머신 포드를 예약할 컴퓨팅 리소스가 클러스터에 충분하지 않으면 리소스를 해제할 수 있도록 다른 원치 않는 포드를 삭제합니다.

  2. 가상 머신의 spec.domain.resources.requests.cpuspec.domain.resources.requests.memory 값을 줄입니다.

Error 또는 CrashLoopBackoff 상태

Error 또는 CrashLoopBackoff 상태의 포드를 해결하려면 가상 머신 컴퓨팅 포드에서 로그를 가져옵니다.

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

Running 상태 및 가상 머신 오류

포드가 Running 상태이지만 가상 머신 자체가 실패하는 경우 다음 단계를 따르세요.

  1. 가상 머신 로그 포드의 로그를 봅니다.

    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
      

가상 머신 이미지의 구성 문제를 해결하려면 다른 이미지로 가상 머신을 하나 더 만드세요.

직렬 콘솔 액세스

이 섹션에서는 VM 인스턴스의 직렬 콘솔을 사용하여 부팅 및 네트워킹 문제를 디버그하고, 고장 난 인스턴스의 문제를 해결하고, GRUB (Grand Unified Bootloader)와 상호작용하고, 기타 문제 해결 작업을 수행하는 방법을 설명합니다.

직렬 포트와의 상호작용은 터미널 창 사용과 비슷합니다. 입력과 출력이 텍스트 모드이며 그래픽 인터페이스 지원이 없습니다. 인스턴스의 운영체제 (OS), 기본 입력 및 출력 (BIOS)은 종종 직렬 포트에 출력을 쓰고 명령어와 같은 입력을 허용합니다.

직렬 콘솔에 액세스하려면 다음 섹션을 확인하세요.

사용자 이름 및 비밀번호 구성

기본적으로 GDC Linux 시스템 이미지는 로컬 사용자에게 비밀번호 기반 로그인을 허용하도록 구성되어 있지 않습니다.

VM이 직렬 콘솔 로그인으로 사전 구성된 이미지를 실행 중인 경우 VM에서 로컬 비밀번호를 설정하고 직렬 콘솔을 통해 로그인할 수 있습니다. GDC Linux VM에서는 VM 생성 중 또는 생성 후에 Kubernetes 보안 비밀로 저장된 시작 스크립트를 통해 사용자 이름과 비밀번호를 구성합니다.

다음 안내에서는 VM 생성 이후에 로컬 비밀번호를 설정하는 방법을 설명합니다. 사용자 이름과 비밀번호를 구성하려면 다음 단계를 완료하세요.

  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: 사용자 이름의 비밀번호입니다. 일부 OS에서는 최소 비밀번호 길이와 복잡성을 요구할 수 있으므로 기본 비밀번호는 사용하지 않아야 합니다.
  3. 시작 스크립트를 Kubernetes 보안 비밀로 만듭니다.

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

    다음을 바꿉니다.

    • PROJECT_NAMESPACE: VM이 있는 프로젝트의 네임스페이스입니다.
    • STARTUP_SCRIPT_NAME: the name you give to the startup script. For example,configure-credentials'를 실행합니다.
    • STARTUP_SCRIPT_PATH: 구성한 사용자 이름과 비밀번호가 포함된 시작 스크립트의 경로입니다.
  4. VM을 중지합니다.

  5. VM 사양을 수정합니다.

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

    VM_NAME을 시작 스크립트에 추가할 VM의 이름으로 바꿉니다.

  6. startupScripts 필드에 3단계에서 만든 Kubernetes 보안 비밀 참조를 추가합니다.

    spec:
      compute:
        memory: 8Gi
        vcpus: 8
      disks:
      - boot: true
        virtualMachineDiskRef:
          name: disk-name 
      startupScripts:
      - name: STARTUP_SCRIPT_NAME
        scriptSecretRef:
          name: STARTUP_SCRIPT_NAME
    
  7. VM을 시작합니다.

    • 새 VM을 사용하는 경우 이 단계를 건너뜁니다.

VM 직렬 콘솔 액세스

VM 직렬 콘솔에 대한 액세스를 시작하려면 다음 단계를 따르세요.

  1. 직렬 콘솔에 연결합니다.

    gdcloud compute connect-to-serial-port VM_NAME \
    --project PROJECT_NAMESPACE
    
  2. 메시지가 표시되면 사용자 이름 및 비밀번호 구성에서 정의한 사용자 이름과 비밀번호를 입력합니다.