通过 ISO 文件创建永久性磁盘映像


Windows 应用的安装媒体通常以 ISO 文件的形式提供,但 Compute Engine 不允许将 ISO 文件作为虚拟 DVD 驱动器公开给虚拟机实例。

如需在单个 Windows 虚拟机上访问 ISO 文件的内容,您可以执行以下操作之一:

  • 将 ISO 文件复制到该虚拟机并将其装载到本地。如果您只需要在单个虚拟机实例上访问 ISO 文件的内容,则此方法非常适用。

  • 通过 ISO 文件创建一个永久性磁盘,然后以只读模式将该磁盘挂接到一个或多个虚拟机实例上。如果有多个虚拟机需要访问 ISO 文件的内容,则此方法非常适用。

本文档介绍如何通过 ISO 文件创建永久性磁盘,并以只读模式将该磁盘挂接到一个或多个虚拟机上。

准备工作

  • 如果您尚未设置身份验证,请进行设置。身份验证是通过其进行身份验证以访问 Google Cloud 服务和 API 的过程。如需从本地开发环境运行代码或示例,您可以选择以下任一选项向 Compute Engine 进行身份验证:

    Select the tab for how you plan to use the samples on this page:

    Console

    When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.

    gcloud

    1. Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init
    2. Set a default region and zone.

准备 ISO 文件

如果 ISO 文件已通过 HTTP 公开提供,则您无需先下载 ISO 文件。如需使用本地 ISO 文件,您可以将此 ISO 文件上传到 Cloud Storage。

HTTP 网址

  1. 在 Google Cloud 控制台中,点击激活 Cloud Shell 激活 Cloud Shell。 按钮,打开 Cloud Shell

    前往 Google Cloud 控制台

  2. 为下载网址创建一个环境变量。该网址可以是 HTTP 或 HTTPS 网址,但必须可匿名访问。

    ISO_URL=https://example.com/big.iso
    

本地 ISO 文件

  1. 在 Google Cloud 控制台中,创建一个 Cloud Storage 存储桶

    前往 Google Cloud 控制台

  2. 上传 ISO 文件

    上传过程可能需要几分钟或几小时才能完成,具体取决于 ISO 文件的大小。

  3. Storage 浏览器中,导航到已上传的对象。

  4. 对象详情页面上,复制该对象的 URI。该 URI 以 gs:// 开头。

  5. 点击激活 Cloud Shell 激活 Cloud Shell。 按钮,打开 Cloud Shell

    前往 Google Cloud 控制台

  6. 为下载网址创建一个环境变量。将 URI 替换为您复制的 URI。

    ISO_URL=URI
    

创建包含 ISO 文件内容的磁盘

如需将 ISO 文件的内容复制到新的磁盘,请先创建一个临时虚拟机,然后根据该磁盘创建映像:

  1. 在 Cloud Shell 中,指定要分配给新磁盘的名称:

    DISK_NAME=iso
    
  2. 创建一个新磁盘,以将 ISO 文件的内容复制到其中:

    gcloud compute disks create $DISK_NAME \
      --size=10GB \
      --zone=$(gcloud config get-value compute/zone)
    

    如果您的 ISO 文件超过 9 GB,请使用较大的磁盘。

  3. 为临时虚拟机创建启动脚本。该启动脚本会执行以下操作:

    1. 使用 NTFS 文件系统格式化辅助磁盘。
    2. 从您指定的 HTTP 或 Cloud Storage 网址下载 ISO 文件。
    3. 装载 ISO 文件并将其内容复制到辅助磁盘。
    cat << "EOF" > startup.ps1
    
    $DownloadDirectory = 'c:\download\'
    $ErrorActionPreference = 'Stop'
    $MetadataUrl = 'http://metadata.google.internal/computeMetadata/v1/instance'
    
    $DownloadUrl = (Invoke-RestMethod `
        -Headers @{"Metadata-Flavor" = "Google"} `
        -Uri "$MetadataUrl/attributes/iso")
    
    mkdir $DownloadDirectory\Source -Force
    
    Write-Host '== Formatting secondary disk... ===' -ForegroundColor Black -BackgroundColor Yellow
    Set-Disk -Number 1 -IsOffline $false
    Clear-Disk -Number 1 -RemoveData -Confirm:$false -ErrorAction SilentlyContinue
    Initialize-Disk -Number 1 -PartitionStyle MBR
    New-Partition -DiskNumber 1 -UseMaximumSize -DriveLetter D -IsActive |
    Format-Volume -FileSystem 'NTFS' -Confirm:$false
    
    Write-Host '== Downloading ISO... =============' -ForegroundColor Black -BackgroundColor Yellow
    if ($DownloadUrl.StartsWith('gs:')) {
        & gcloud storage cp $DownloadUrl "$DownloadDirectory\Source\image.iso" | Out-Default
    }
    else {
        Import-Module BitsTransfer
        Start-BitsTransfer -Source $DownloadUrl -Destination "$DownloadDirectory\Source\image.iso"
    }
    
    Write-Host '== Mounting ISO... ================' -ForegroundColor Black -BackgroundColor Yellow
    Mount-DiskImage -ImagePath "$DownloadDirectory\Source\image.iso" -StorageType ISO
    
    Write-Host '== Copying ISO contents... ========' -ForegroundColor Black -BackgroundColor Yellow
    Copy-Item 'e:\*' 'd:\' -Force -Recurse -PassThru `
        | Where-Object { -Not $_.PSIsContainer } `
        | Set-ItemProperty -Name IsReadOnly -Value $False
    
    Write-Host '== Completed. =====================' -ForegroundColor Black -BackgroundColor Yellow
    Invoke-RestMethod `
        -Headers @{'Metadata-Flavor'='Google'}  `
        -Method PUT  `
        -Uri "$MetadataUrl/guest-attributes/vm/ready" `
        -Body true
    EOF
    
  4. 创建一个使用您之前创建的启动脚本和磁盘的 Windows Server 2019 虚拟机:

    gcloud compute instances create iso-copier \
        --machine-type=n1-standard-2 \
        --image-family=windows-2019-core \
        --image-project=windows-cloud \
        --disk=name=$DISK_NAME,auto-delete=no \
        --metadata=enable-guest-attributes=true,iso=$ISO_URL \
        --metadata-from-file=windows-startup-script-ps1=startup.ps1 \
        --scopes=https://www.googleapis.com/auth/devstorage.read_only
    

    虚拟机大约需要 2 分钟才能启动。根据 ISO 文件的大小,文件复制操作可能需要 5 至 15 分钟时间才能完成。您可以通过运行以下命令来观察进度:

    gcloud compute instances tail-serial-port-output iso-copier \
        --zone=$(gcloud config get-value compute/zone)
    
  5. 等待虚拟机完成启动脚本的运行:

    until gcloud compute instances get-guest-attributes iso-copier \
        --zone=$(gcloud config get-value compute/zone) \
        --query-path=vm/ready > /dev/null 2>&1
    do
        sleep 5 && echo waiting for VM to finish...
    done
    
  6. 关闭并删除虚拟机:

    gcloud compute instances delete iso-copier \
        --zone=$(gcloud config get-value compute/zone) \
        --quiet
    

    请注意,辅助磁盘并未删除,因为它是通过 auto-delete=no 参数装载的。

该磁盘现已可供使用。您可以只读模式将该磁盘挂接到同一可用区内的一个或多个虚拟机实例上

通过创建映像跨地区和区域共享磁盘

如需在其他地区或区域中提供 ISO 文件的内容,请创建 Compute Engine 映像:

  1. 在 Cloud Shell 中,根据您在上一部分中创建的磁盘创建映像:

    gcloud compute images create $DISK_NAME \
        --source-disk=$DISK_NAME \
        --source-disk-zone=$(gcloud config get-value compute/zone)
    

清理

为避免在完成此过程后产生额外的费用,您可以删除已创建的资源:

  1. 删除磁盘:

    gcloud compute disks delete $DISK_NAME \
        --zone=$(gcloud config get-value compute/zone) \
        --quiet
    
  2. 删除映像:

    gcloud compute images delete $DISK_NAME
    

后续步骤