EC2-Proto

Cloud-Hypervisorを使ってVMを作成したい

EC2を作りたいと思い、VMの管理にgoogleが提供しているOSSであるCloud-Hypervisor(CH)を使っています。
CHを使ってブートするためには

  • CLIでワンライナーでブートする
  • CH側に用意されているAPIを叩く

という2種類の方法があり、後者であるAPI経由でのブートで手間取ったので備忘録です。

ドキュメントを読む

ドキュメントが古く(?)、vm_createを叩く際にこれに記載されているJSONの形式でリクエストを送るとNo bootitem provided:というエラーが出ます。

VMを作成する(できない)

./cloud-hypervisor --api-socket /tmp/cloud-hypervisor.sock
curl --unix-socket /tmp/cloud-hypervisor.sock -i \ 
    -X PUT 'http://localhost/api/v1/vm.create' \ 
    -H 'Accept: application/json' \ 
    -H 'Content-Type: application/json' \ 
    -d '{ 
        "cpus": { "boot_vcpus": 1, "max_vcpus": 1 }, 
        "kernel": { "path": "./images/CLOUDHV.fd" }, 
        "cmdline": { "args": "console=ttyS0 console=hvc0 root=/dev/vda1 rw" }, 
        "disks": [ { "path": "./images/noble.raw" } ], 
        "rng": { "src": "/dev/urandom" } }' 

 
この時点で500が返ってきている

HTTP/1.1 500 
Server: Cloud Hypervisor API 
Connection: keep-alive 
Content-Type: application/json 
Content-Length: 72 

ブートする(できない)

curl --unix-socket /tmp/cloud-hypervisor.sock -i 
    -X PUT 'http://localhost/api/v1/vm.boot' 

 
失敗!

HTTP/1.1 500 
Server: Cloud Hypervisor API 
Connection: keep-alive 
Content-Type: application/json 
Content-Length: 162 

["Error from API","The VM could not boot","Failed to validate config","Payload configuration is not bootable","No bootitem provided: neither firmware nor kernel"]

解決

vm_createの際にkernelの指定を”payload”で囲って、かつパスはオブジェクトとしてはなくstringで渡す必要がある。

curl --unix-socket /tmp/cloud-hypervisor.sock -i \ 
    -X PUT 'http://localhost/api/v1/vm.create' \ 
    -H 'Accept: application/json' \ 
    -H 'Content-Type: application/json' \ 
    -d '{ 
        "cpus": { "boot_vcpus": 1, "max_vcpus": 1 }, 
        "payload": { 
            "kernel": "./images/CLOUDHV.fd", 
            "cmdline": "console=ttyS0 console=hvc0 root=/dev/vda1 rw"
        },
        "disks": [ { "path": "./images/noble.raw" } ], 
        "rng": { "src": "/dev/urandom" } }' 

 
vm_bootについては変更する必要はありません。

余談

なぜpayload{}で囲う必要があるか?

ドキュメントは無視して、CHのOpenAPI仕様を読むと

  /vm.create:
    put:
      summary: Create the cloud-hypervisor Virtual Machine (VM) instance. The instance is not booted, only created.
      operationId: createVM
      requestBody:
        description: The VM configuration
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/VmConfig"
        required: true
      responses:
        204:
          description: The VM instance was successfully created.
    PayloadConfig:
      type: object
      properties:
        firmware:
          type: string
        kernel:
          type: string
        cmdline:
          type: string
        initramfs:
          type: string
        igvm:
          type: string
        host_data:
          type: string
      description: Payloads to boot in guest

    VmConfig:
      required:
        - payload
      type: object
      properties:
        cpus:
          $ref: "#/components/schemas/CpusConfig"
        memory:
          $ref: "#/components/schemas/MemoryConfig"
        payload:
          $ref: "#/components/schemas/PayloadConfig"
        rate_limit_groups:
          type: array
          items:
            $ref: "#/components/schemas/RateLimitGroupConfig"
        disks:
          type: array
          items:
            $ref: "#/components/schemas/DiskConfig"
        net:
          type: array
          items:
            $ref: "#/components/schemas/NetConfig"
        rng:
          $ref: "#/components/schemas/RngConfig"
        balloon:
          $ref: "#/components/schemas/BalloonConfig"
        fs:
          type: array
          items:
            $ref: "#/components/schemas/FsConfig"
        pmem:
          type: array
          items:
            $ref: "#/components/schemas/PmemConfig"
        serial:
          $ref: "#/components/schemas/ConsoleConfig"
        console:
          $ref: "#/components/schemas/ConsoleConfig"
        debug_console:
          $ref: "#/components/schemas/DebugConsoleConfig"
        devices:
          type: array
          items:
            $ref: "#/components/schemas/DeviceConfig"
        vdpa:
          type: array
          items:
            $ref: "#/components/schemas/VdpaConfig"
        vsock:
          $ref: "#/components/schemas/VsockConfig"
        numa:
          type: array
          items:
            $ref: "#/components/schemas/NumaConfig"
        iommu:
          type: boolean
          default: false
        watchdog:
          type: boolean
          default: false
        pvpanic:
          type: boolean
          default: false
        pci_segments:
          type: array
          items:
            $ref: "#/components/schemas/PciSegmentConfig"
        platform:
          $ref: "#/components/schemas/PlatformConfig"
        tpm:
          $ref: "#/components/schemas/TpmConfig"
        landlock_enable:
          type: boolean
          default: false
        landlock_rules:
          type: array
          items:
            $ref: "#/components/schemas/LandlockConfig"
      description: Virtual machine configuration

 
と書いてあった。

なお、APIではなくCLI経由で作成する場合は単純に--kernelオプションをつけて作成するだけでブートできます。

ちゃんとAPIの仕様書は読んだほうがいいなと思いました。

 
以上