1.2. Start and stop a VM

Start and stop your virtual machines

In the previous section, we wrote a VirtualMachine specification and applied the manifest to the Kubernetes cluster.

Lifecycle

When the underlying technology libvirt refers to a VM it often also uses the concept of so-called guest domains.

According to libvirt.org , a guest domain can be in several states:

  1. Undefined: This is a baseline state. Libvirt does not know anything about domains in this state because the domain hasn’t been defined or created yet.
  2. Defined or Stopped: The domain has been defined but it’s not running. This state is also called stopped. Only persistent domains can be in this state. When a transient domain is stopped or shut down, it ceases to exist.
  3. Running: The domain has been created and started either as transient or persistent domain. Either domain in this state is being actively executed on the node’s hypervisor.
  4. Paused: The domain execution on the hypervisor has been suspended. Its state has been temporarily stored until it is resumed. The domain does not have any knowledge whether it was paused or not.
  5. Saved: Similar to the paused state, but the domain state is stored to persistent storage. Again, the domain in this state can be restored and it does not notice that any time has passed.

VM Lifecycle

Task 1.2.1: List your virtual machines

In the left menu under Virtualization, click on VirtualMachines. Not so empty anymore! You can see your virtual machine, its status, condition, when it was created and, if it was running, what IP address it has:

VMs list

Of course, you can also list the VMs via CLI:

oc get virtualmachine --namespace lab-<username>

You should see your virtual machines listed as follows:

NAME            AGE   STATUS    READY
lab01-firstvm   10m   Stopped   False

This indicates that the VM has been created but is still in a stopped state.

Working with your VMs

There are different ways of starting and stopping your virtual machines. You can use OpenShift’s web console, patch your VirtualMachine resource with oc or use virtctl to start the VM. Try starting and stopping your VM with different methods.

Task 1.2.2: Start using OpenShift’s web console

From the list view you should still see, click on your VM’s name. On the top right, you can see different buttons. Click the Start button to start your VM.

VM actions

Sometimes you have to be patient for a few seconds after clicking. If you’re in doubt, reload the page.

Watch how the Status changes to Running and a small view of the VNC console is shown. Further below, the Utiliziation is constantly updated with new data about your VM’s resource usage.

Task 1.2.3: Stop using OpenShift’s web console

On the top right of your VM’s management view, you can also see buttons for stopping, restarting and pausing the virtual machine.

Stop your VM again.

Task 1.2.4: Start with oc

Your VirtualMachine resource contains a field spec.runStrategy which indicates the desired state of the VM. You can check the resource with:

oc describe vm lab01-firstvm --namespace lab-<username>

Alternatively you can directly select the relevant field using a jsonpath:

oc get vm lab01-firstvm -o jsonpath='{.spec.runStrategy}' --namespace lab-<username>

Use the following command to start your VM:

oc patch vm lab01-firstvm --type merge -p '{"spec":{"runStrategy":"Always"}}' --namespace lab-<username>

The output should be:

virtualmachine.kubevirt.io/lab01-firstvm patched

Now check the state of your VM again:

oc get vm --namespace lab-<username>

You should see that the VM is now in Running state:

NAME            AGE   STATUS    READY
lab01-firstvm   11m   Running   True

Task 1.2.7: Stop with oc

Stopping the VM is similar to starting. Just set spec.runStrategy back to Halted:

oc patch vm lab01-firstvm --type merge -p '{"spec":{"runStrategy":"Halted"}}' --namespace lab-<username>

The output should again be:

virtualmachine.kubevirt.io/lab01-firstvm patched

Task 1.2.8: Start with virtctl

The binary virtctl provides an easier way of interacting with OpenShift Virtualization VMs. And adds additional features like:

  • Serial and graphical console access
  • Starting and stopping VirtualMachineInstances
  • Live migrating VirtualMachineInstances
  • Uploading virtual machine disk images
  • Adding, removing volumes
  • Exposing services
  • Debugging features: creating memory dumps

We will use some of those functionalities during the lab.

virtctl uses the default kubeconfig to interact with the Kubernetes Cluster.

Explore the capabilities of virtctl by executing the following commands:

virtctl --help

and

virtctl <command> --help

or the following to display all options

virtctl options

Let’s now start the VM by using virtctl by executing the following command:

virtctl start lab01-firstvm --namespace lab-<username>

The output should be:

VM lab01-firstvm was scheduled to start

If you check the state of your VM you’ll see that it had the same effect as using the oc command:

oc get vm --namespace lab-<username>

Your VM is in Running state:

NAME            AGE   STATUS    READY
lab01-firstvm   11m   Running   True

Question to explore virtctl: What’s the exact command to restart a VM (vm-to-restart) using the kubeconfig from (~/.kube/prod-cluster the config does not exist in the webshell, it’s just an example)

Solution
virtctl --kubeconfig ~/.kube/prod-cluster restart vm-to-restart --namespace lab-<username>

Task 1.2.9: Stop with virtctl

When using the --dry-run option we can see what would happen without really executing the actual command. This can be a helpful option when interacting with production workload.

Let’s dry-run the stop command:

virtctl stop lab01-firstvm --dry-run --namespace lab-<username>

This will return the following:

Dry Run execution
VM lab01-firstvm was scheduled to stop

To stop your VM for real, remove the --dry-run option:

virtctl stop lab01-firstvm --namespace lab-<username>

The output should be:

VM lab01-firstvm was scheduled to stop

Task 1.2.10: Pause a VirtualMachine with virtctl

Pausing a VM is as simple as:

virtctl pause vm lab01-firstvm --namespace lab-<username>

However, if you try to execute above command, it will result in an error:

Error pausing VirtualMachineInstance lab01-firstvm. VirtualMachine lab01-firstvm is not set to run

Obviously we can not pause a stopped VM, so start the VM first and then try the pause command again:

virtctl start lab01-firstvm --namespace lab-<username>

Make sure the VM shows it has started before you pause it:

oc get vm --namespace lab-<username>

Now pause it:

virtctl pause vm lab01-firstvm --namespace lab-<username>

The output should be:

VMI lab01-firstvm was scheduled to pause

Again, verify the state of the VM:

oc get vm --namespace lab-<username>

Resuming a VM can be done with:

virtctl unpause vm lab01-firstvm --namespace lab-<username>

The output should be:

VMI lab01-firstvm was scheduled to unpause

Involved components

When your VM is in a running state, you may have noticed that there is an additional pod running. Make sure your VM is running and issue the following command:

oc get pods --namespace lab-<username>

The output will be similar to:

NAME                                READY   STATUS    RESTARTS   AGE

virt-launcher-lab01-firstvm-mfxrs   3/3     Running   0          90s

For each running VM there is a virt-launcher pod which is responsible to start the effective VM process in the container and observes the VM state.

Beside the existence of the virt-launcher pod, a new custom resource VirtualMachineInstance is present. This resource is created under the hood by the virt-controller and will only be available as long as the VM is running. It represents a single running virtual machine instance.

You may see your VirtualMachineInstance with the following command:

oc get vmi --namespace lab-<username>

The output will be similar to:

NAME            AGE     PHASE     IP             NODENAME               READY
lab01-firstvm   3m59s   Running   10.244.3.144   training-worker-0   True

Above output also indicates that our lab01-firstvm is running on Kubernetes node training-worker-0.