Cloneable Virtual Machines
To create a cloneable VM, you will need to create a VMDisk and a VMInstance. This guide uses an ubuntu base image
as an example.
Create VMDisk
apiVersion: apps.cozystack.io/v1alpha1 kind: VMDisk metadata: name: ubuntu-source namespace: tenant-root spec: optical: false source: http: url: https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img storage: 20Gi storageClass: replicatedSince expanding a disk can be complicated, we recommend creating it with extra space to accommodate future growth.Create VMInstance
Since the
VirtualMachinecustom resource does not provide an easy way to work with multiple disks, useVMInstanceinstead.Create
VMInstanceusing the following template:apiVersion: apps.cozystack.io/v1alpha1 kind: VMInstance metadata: name: sourcevm namespace: tenant-root spec: externalMethod: PortList disks: - name: ubuntu-source externalPorts: - 22 instanceProfile: ubuntu instanceType: "" running: true sshKeys: - <paste your ssh public key here> external: true resources: cpu: "2" memory: 4GiWhen VM is created, it will get load balancer external IP address. You can get it using:
kubectl get svc -n tenant-root vm-instance-sourcevmSSH into VM
Now you can SSH into VM using the external IP address. Default user for
ubuntubase image isubuntu.ssh ubuntu@<external IP>Configure the virtual machine before cloning.
Delete VMInstance
Data on the disk will be preserved.
kubectl delete vminstance -n tenant-root sourcevmCreate disk image
apiVersion: cdi.kubevirt.io/v1beta1 kind: DataVolume metadata: name: "vm-image-sourcevm" # prefix vm-image is necessary namespace: cozy-public # do not change annotations: cdi.kubevirt.io/storage.bind.immediate.requested: "true" spec: source: pvc: name: vm-disk-ubuntu-source namespace: tenant-root storage: resources: requests: storage: 20Gi storageClassName: replicatedIt will take some time to complete. Wait before continuing. You can check the progress using:
kubectl get datavolume -n cozy-public vm-image-sourcevmExample output when ready:
NAME PHASE PROGRESS RESTARTS AGE vm-image-sourcevm Succeeded 100.0% 7m32sCreate VMDisk from cloned image
apiVersion: apps.cozystack.io/v1alpha1 kind: VMDisk metadata: name: ubuntu-cloned-1 namespace: tenant-root spec: optical: false source: image: name: sourcevm # image name without prefix storage: 20Gi # size greater or equal to the disk image size storageClass: replicatedCreate VMInstance from cloned disk
apiVersion: apps.cozystack.io/v1alpha1 kind: VMInstance metadata: name: cloned-vm namespace: tenant-root spec: external: true externalMethod: PortList cloudInit: "hostname: my-cloned-vm" cloudInitSeed: "1" disks: - name: ubuntu-cloned-1 externalPorts: - 22 instanceProfile: ubuntu running: trueTo ensure the cloned VM’s network functions correctly, you must override its
hostnamevia.spec.cloudInitand provide a unique.spec.cloudInitSeedto prevent conflicts with the source VM.