VM lifecycle

This section describes the lifecycle of a virtual machine (VM) instance, starting from its creation through its potential deletion.

Create a Linux VM

This section describes how to create a Linux virtual machine in Google Distributed Cloud Hosted.

Before you begin

  1. You must have the curl and yq tools installed on your local machine.

    • For the curl tools, visit https://curl.se/download.html.
    • For the yq tools visit https://github.com/mikefarah/yq.
  2. To create a Linux VM, you must get the URL of the image that shipped with GDCH:

    1. In your terminal, run the following command against the org admin cluster to get the URL of the Linux VM image:

      kubectl get vmimagemetadata \
        -o=custom-columns=NAME:.metadata.name,URL:.commonMetadata.servingURL | grep \
        "ubuntu-20.04"
      

      Sample output:

      ubuntu-20.04-server-cloudimg-amd64-gpc-0.0
      https://10.200.0.36:11443/artifacts/serve/Z3BjLXN5c3RlbS12bS1pbWFnZXMvdWJ1bnR1LTIwLjA0LXNlcnZlci1jbG91ZGltZy1hbWQ2NDpncGMtMC4w
      
    2. Copy the HTTPS certificate to the namespace you are planning to create the VM in. On the org admin cluster, run:

      kubectl get secret root-admin-artifact-registry-services-https -n \
        istio-system -o jsonpath="{.data.tls\.crt}" | base64 --decode > tls.crt
      

      On the default bare metal user cluster, run:

      kubectl create configmap vm-image-cert --from-file=tls.crt -n NAMESPACE_NAME
      
  3. To create a VM, you must provide an SSH public key. Store this SSH public key as a secret in Kubernetes.

    If you need to create an SSH key pair and store it as a secret in your cluster, complete the following steps:

    1. In your terminal, create an SSH key pair. Specify your own path and KEY_NAME:

      ssh-keygen -t rsa -b 4096 -f /path/to/KEY_NAME
      
    2. Save the public key as a Kubernetes secret in the same namespace that you want to create your VM in. Specify your own SECRET_NAME and NAMESPACE_NAME:

      kubectl create secret generic SECRET_NAME \
                      --from-file=key1=/path/to/KEY_NAME.pub \
                      -n NAMESPACE_NAME
      

Create a VM

To get the permissions that you need to create a VM, ask your Project IAM Admin to grant you the VM Admin role.

You define the configuration for a VM in a YAML file, then create the VM by applying the YAML file to the Kubernetes API server. Specify the following information in the YAML file:

  • Name of the VM instance
  • Namespace for the VM to run in
  • Number of vCPU (requests and limits)
  • Memory size (requests and limits)
  • Name of the secret storing the SSH public key
  • OS image to use

Create a YAML file and define the required configuration for your VM.

  1. In your terminal, create a YAML file in an editor of your choice. The following example uses Nano as the editor:

    nano vm.yaml
    

    Paste the following YAML content and update as needed for your own environment:

    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    metadata:
      name: VM_NAME
      namespace: NAMESPACE_NAME
    spec:
      running: true
      dataVolumeTemplates:
      - metadata:
          name: VM_NAME-boot-dv
        spec:
          pvc:
            accessModes:
            - ReadWriteMany
            resources:
              requests:
                storage: 10Gi
            storageClassName: standard-rwx
          source:
            http:
              url: LINUX_VM_IMAGE
              certConfigMap: vm-image-cert
      template:
        metadata:
          labels:
            kubevirt.io/vm: VM_NAME
            ingress.virtualmachines.gpc.gke.io: "true"
        spec:
          domain:
            devices:
              disks:
              - bootOrder: 1
                disk:
                  bus: virtio
                name: VM_NAME-boot-dv
              - disk:
                  bus: virtio
                name: cloudinit
              interfaces:
              - masquerade: {}
                macAddress: "f8:8f:ca:00:00:01"
                name: default
            machine:
              type: ""
            resources:
              requests:
                cpu: 1
                memory: 4Gi
              limits:
                cpu: 1
                memory: 4Gi
          networks:
          - name: default
            pod: {}
          accessCredentials:
          - sshPublicKey:
              source:
                secret:
                  secretName: SECRET_NAME
              propagationMethod:
                configDrive: {}
          volumes:
          - dataVolume:
              name: VM_NAME-boot-dv
            name: VM_NAME-boot-dv
          - cloudInitConfigDrive:
              userData: |
                #cloudconfig
            name: cloudinit
    

    This example YAML file creates an instance named VM_NAME with 1 vCPU, 4Gi memory, and a 10Gi disk. The VM uses the KEY_NAME SSH public key from the SECRET_NAME Kubernetes secret.

  2. Save and close.

  3. Create the VM by applying the YAML file to the Kubernetes API server:

    kubectl apply -f vm.yaml
    
  4. Wait a few minutes, then get the status of the VM:

    kubectl get virtualmachine -n NAMESPACE_NAME
    

    The following example output shows the VM is in a Provisioning state:

    NAME   AGE   STATUS         VOLUME
    vm1    25s   Provisioning
    
  5. The VM is ready when the DataVolume is ready and the OS image is applied. If you want to view the progress of the VM create process, list the data volumes to see the status of the OS image import. It might take up to 15-20 minutes to import the OS image and for the VM to start:

    kubectl get datavolume -n NAMESPACE_NAME
    

    The following example output shows the progress of the import:

    NAME          PHASE              PROGRESS   RESTARTS   AGE
    vm1-boot-dv   ImportInProgress   4.02%                 11m
    
  6. When the import status of the OS image is complete, get the status of the VM:

    kubectl get virtualmachine -n NAMESPACE_NAME
    

    The following example output shows the VM in a Running state:

    NAME   AGE   STATUS    VOLUME
    vm1    4     Running
    

Use an out-of-box Ubuntu image

The default method for creating Distributed Cloud Hosted VMs is followed by using an out-of-box (OOB) Ubuntu image. An Ubuntu image is stored in an artifacts registry Harbor project.

TBD

Use a custom image

Custom images are ideal for usage when you have created or modified a persistent boot disk or specific image to a certain state and need to save that state for creating VMs. To use a custom image, or an image that was built from a different flow, upload the image (together with the metadata) to Distributed Cloud Hosted.

Create a disk from the custom image and attach it to the VM.

Directions TBD.

Use additional non-boot disks

You can replace your boot disk for an instance rather than recreating the entire VM instance. You can only attach or detach a boot disk from a stopped VM.

  1. Stop the VM instance.
  2. Detach a boot disk. (You don't need to unmount it.)
  3. Reattach a disk as a boot disk.
  4. Restart the instance.

Use an existing disk

Update a boot disk for a VM. Detach the existing boot disk and attach a new one using the following directions (details TBD).

  1. Stop the VM.
  2. Detach the boot disk.
  3. Edit your VM resource.
  4. Search for the disk you need.
  5. Update the YAML manifest to attach the disk.
  6. Use the name of the disk you selected in the previous step.
  7. Save and close the updated VM manifest in your editor.
  8. Start the VM.

Use multiple disks

Create with or without disk auto-delete

Create a VM without machine type

Create a VM with attached GPUs

You can add graphics processing units (GPUs) to your VM instances. Use these to accelerate specific workloads such as machine learning and data processing on your VMs. The GPUs work in passthrough mode so that the VMs have direct control over both the GPUs and their associated memory. Distributed Cloud Hosted VMs can have NVIDIA A100 GPUs added to them.

Use GPU machine type

GPUs must be attached to VMs that have either predefined or custom machine types.

Use machine type

Create a VM with attached GPUs, then install the GPU driver on your VM to enable your system to use the device.

  1. Create the VM with GPUs attached (details TBD).
  2. Install the GPU driver.
  3. Enable secure boot.

Create and save custom images

Creating and saving a golden image to use as a new VM image for future VM creation prevents you from needing to duplicate your setup steps on every VM that you create.

The customized image is first stored as a PersistentVolumeClaim (PVC). The VM API and controller package the image with user-input metadata in the AR-required format, and upload the packaged image to the AR project that is dedicated to the Distributed Cloud Hosted project.

Create custom images

Create a custom image on a Linux VM. You can create a disk image from a persistent disk, another image in your project, a disk.raw file, or an image that's been shared.

(Detailed directions TBD.)