Presets

VirtualMachineInstancePresets are an extension to general VirtualMachineInstance configuration behaving much like PodPresets from Kubernetes. When a VirtualMachineInstance is created, any applicable VirtualMachineInstancePresets will be applied to the existing spec for the VirtualMachineInstance. This allows for re-use of common settings that should apply to multiple VirtualMachineInstances.

Create a VirtualMachineInstancePreset

You can describe a VirtualMachineInstancePreset in a YAML file. For example, the vmi-preset.yaml file below describes a VirtualMachineInstancePreset that requests a VirtualMachineInstance be created with a resource request for 64M of RAM.

  1. apiVersion: kubevirt.io/v1alpha3
  2. kind: VirtualMachineInstancePreset
  3. metadata:
  4. name: small-qemu
  5. spec:
  6. selector:
  7. matchLabels:
  8. kubevirt.io/size: small
  9. domain:
  10. resources:
  11. requests:
  12. memory: 64M
  • Create a VirtualMachineInstancePreset based on that YAML file:
  1. kubectl create -f vmipreset.yaml

Required Fields

As with most Kubernetes resources, a VirtualMachineInstancePreset requires apiVersion, kind and metadata fields.

Additionally VirtualMachineInstancePresets also need a spec section. While not technically required to satisfy syntax, it is strongly recommended to include a Selector in the spec section, otherwise a VirtualMachineInstancePreset will match all VirtualMachineInstances in a namespace.

VirtualMachine Selector

KubeVirt uses Kubernetes Labels and Selectors to determine which VirtualMachineInstancePresets apply to a given VirtualMachineInstance, similarly to how PodPresets work in Kubernetes. If a setting from a VirtualMachineInstancePreset is applied to a VirtualMachineInstance, the VirtualMachineInstance will be marked with an Annotation upon completion.

Any domain structure can be listed in the spec of a VirtualMachineInstancePreset, e.g. Clock, Features, Memory, CPU, or Devices such as network interfaces. All elements of the spec section of a VirtualMachineInstancePreset will be applied to the VirtualMachineInstance.

Once a VirtualMachineInstancePreset is successfully applied to a VirtualMachineInstance, the VirtualMachineInstance will be marked with an annotation to indicate that it was applied. If a conflict occurs while a VirtualMachineInstancePreset is being applied, that portion of the VirtualMachineInstancePreset will be skipped.

Any valid Label can be matched against, but it is suggested that a general rule of thumb is to use os/shortname, e.g. kubevirt.io/os: rhel7.

Updating a VirtualMachineInstancePreset

If a VirtualMachineInstancePreset is modified, changes will not be applied to existing VirtualMachineInstances. This applies to both the Selector indicating which VirtualMachineInstances should be matched, and also the Domain section which lists the settings that should be applied to a VirtualMachine.

Overrides

VirtualMachineInstancePresets use a similar conflict resolution strategy to Kubernetes PodPresets. If a portion of the domain spec is present in both a VirtualMachineInstance and a VirtualMachineInstancePreset and both resources have the identical information, then creation of the VirtualMachineInstance will continue normally. If however there is a difference between the resources, an Event will be created indicating which DomainSpec element of which VirtualMachineInstancePreset was overridden. For example: If both the VirtualMachineInstance and VirtualMachineInstancePreset define a CPU, but use a different number of Cores, KubeVirt will note the difference.

If any settings from the VirtualMachineInstancePreset were successfully applied, the VirtualMachineInstance will be annotated.

In the event that there is a difference between the Domains of a VirtualMachineInstance and VirtualMachineInstancePreset, KubeVirt will create an Event. kubectl get events can be used to show all Events. For example:

  1. $ kubectl get events
  2. ....
  3. Events:
  4. FirstSeen LastSeen Count From SubobjectPath Reason Message
  5. 2m 2m 1 myvmi.1515bbb8d397f258 VirtualMachineInstance Warning Conflict virtualmachineinstance-preset-controller Unable to apply VirtualMachineInstancePreset 'example-preset': spec.cpu: &{6} != &{4}

Usage

VirtualMachineInstancePresets are namespaced resources, so should be created in the same namespace as the VirtualMachineInstances that will use them:

kubectl create -f <preset>.yaml [--namespace <namespace>]

KubeVirt will determine which VirtualMachineInstancePresets apply to a Particular VirtualMachineInstance by matching Labels. For example:

  1. apiVersion: kubevirt.io/v1alpha3
  2. kind: VirtualMachineInstancePreset
  3. metadata:
  4. name: example-preset
  5. selector:
  6. matchLabels:
  7. kubevirt.io/os: win10
  8. ...

would match any VirtualMachineInstance in the same namespace with a Label of flavor: foo. For example:

  1. apiVersion: kubevirt.io/v1alpha3
  2. kind: VirtualMachineInstance
  3. version: v1
  4. metadata:
  5. name: myvmi
  6. labels:
  7. kubevirt.io/os: win10
  8. ...

Conflicts

When multiple VirtualMachineInstancePresets match a particular VirtualMachineInstance, if they specify the same settings within a Domain, those settings must match. If two VirtualMachineInstancePresets have conflicting settings (e.g. for the number of CPU cores requested), an error will occur, and the VirtualMachineInstance will enter the Failed state, and a Warning event will be emitted explaining which settings of which VirtualMachineInstancePresets were problematic.

Matching Multiple VirtualMachineInstances

The main use case for VirtualMachineInstancePresets is to create re-usable settings that can be applied across various machines. Multiple methods are available to match the labels of a VirtualMachineInstance using selectors.

  • matchLabels: Each VirtualMachineInstance can use a specific label shared by all

    instances. * matchExpressions: Logical operators for sets can be used to match multiple

    labels.

Using matchLabels, the label used in the VirtualMachineInstancePreset must match one of the labels of the VirtualMachineInstance:

  1. selector:
  2. matchLabels:
  3. kubevirt.io/memory: large

would match

  1. metadata:
  2. labels:
  3. kubevirt.io/memory: large
  4. kubevirt.io/os: win10

or

  1. metadata:
  2. labels:
  3. kubevirt.io/memory: large
  4. kubevirt.io/os: fedora27

Using matchExpressions allows for matching multiple labels of VirtualMachineInstances without needing to explicity list a label.

  1. selector:
  2. matchExpressions:
  3. - {key: kubevirt.io/os, operator: In, values: [fedora27, fedora26]}

would match both:

  1. metadata:
  2. labels:
  3. kubevirt.io/os: fedora26
  4. metadata:
  5. labels:
  6. kubevirt.io/os: fedora27

The Kubernetes documentation has a detailed explanation. Examples are provided below.

Exclusions

Since VirtualMachineInstancePresets use Selectors that indicate which VirtualMachineInstances their settings should apply to, there needs to exist a mechanism by which VirtualMachineInstances can opt out of VirtualMachineInstancePresets altogether. This is done using an annotation:

  1. kind: VirtualMachineInstance
  2. version: v1
  3. metadata:
  4. name: myvmi
  5. annotations:
  6. virtualmachineinstancepresets.admission.kubevirt.io/exclude: "true"
  7. ...

Examples

Simple VirtualMachineInstancePreset Example

  1. apiVersion: kubevirt.io/v1alpha3
  2. kind: VirtualMachineInstancePreset
  3. version: v1alpha3
  4. metadata:
  5. name: example-preset
  6. spec:
  7. selector:
  8. matchLabels:
  9. kubevirt.io/os: win10
  10. domain:
  11. features:
  12. acpi: {}
  13. apic: {}
  14. hyperv:
  15. relaxed: {}
  16. vapic: {}
  17. spinlocks:
  18. spinlocks: 8191
  19. ---
  20. apiVersion: kubevirt.io/v1alpha3
  21. kind: VirtualMachineInstance
  22. version: v1
  23. metadata:
  24. name: myvmi
  25. labels:
  26. kubevirt.io/os: win10
  27. spec:
  28. domain:
  29. firmware:
  30. uuid: c8f99fc8-20f5-46c4-85e5-2b841c547cef

Once the VirtualMachineInstancePreset is applied to the VirtualMachineInstance, the resulting resource would look like this:

  1. apiVersion: kubevirt.io/v1alpha3
  2. kind: VirtualMachineInstance
  3. metadata:
  4. annotations:
  5. presets.virtualmachineinstances.kubevirt.io/presets-applied: kubevirt.io/v1alpha3
  6. virtualmachineinstancepreset.kubevirt.io/example-preset: kubevirt.io/v1alpha3
  7. labels:
  8. kubevirt.io/os: win10
  9. kubevirt.io/nodeName: master
  10. name: myvmi
  11. namespace: default
  12. spec:
  13. domain:
  14. devices: {}
  15. features:
  16. acpi:
  17. enabled: true
  18. apic:
  19. enabled: true
  20. hyperv:
  21. relaxed:
  22. enabled: true
  23. spinlocks:
  24. enabled: true
  25. spinlocks: 8191
  26. vapic:
  27. enabled: true
  28. firmware:
  29. uuid: c8f99fc8-20f5-46c4-85e5-2b841c547cef
  30. machine:
  31. type: q35
  32. resources:
  33. requests:
  34. memory: 8Mi

Conflict Example

This is an example of a merge conflict. In this case both the VirtualMachineInstance and VirtualMachineInstancePreset request different number of CPU’s.

  1. apiVersion: kubevirt.io/v1alpha3
  2. kind: VirtualMachineInstancePreset
  3. version: v1alpha3
  4. metadata:
  5. name: example-preset
  6. spec:
  7. selector:
  8. matchLabels:
  9. kubevirt.io/flavor: default-features
  10. domain:
  11. cpu:
  12. cores: 4
  13. ---
  14. apiVersion: kubevirt.io/v1alpha3
  15. kind: VirtualMachineInstance
  16. version: v1
  17. metadata:
  18. name: myvmi
  19. labels:
  20. kubevirt.io/flavor: default-features
  21. spec:
  22. domain:
  23. cpu:
  24. cores: 6

In this case the VirtualMachineInstance Spec will remain unmodified. Use kubectl get events to show events.

  1. apiVersion: kubevirt.io/v1alpha3
  2. kind: VirtualMachineInstance
  3. metadata:
  4. annotations:
  5. presets.virtualmachineinstances.kubevirt.io/presets-applied: kubevirt.io/v1alpha3
  6. generation: 0
  7. labels:
  8. kubevirt.io/flavor: default-features
  9. name: myvmi
  10. namespace: default
  11. spec:
  12. domain:
  13. cpu:
  14. cores: 6
  15. devices: {}
  16. machine:
  17. type: ""
  18. resources: {}
  19. status: {}

Calling kubectl get events would have a line like:

  1. 2m 2m 1 myvmi.1515bbb8d397f258 VirtualMachineInstance Warning Conflict virtualmachineinstance-preset-controller Unable to apply VirtualMachineInstancePreset example-preset: spec.cpu: &{6} != &{4}

Matching Multiple VirtualMachineInstances Using MatchLabels

These VirtualMachineInstances have multiple labels, one that is unique and one that is shared.

Note: This example breaks from the convention of using os-shortname as a Label for demonstration purposes.

  1. apiVersion: kubevirt.io/v1alpha3
  2. kind: VirtualMachineInstancePreset
  3. metadata:
  4. name: twelve-cores
  5. spec:
  6. selector:
  7. matchLabels:
  8. kubevirt.io/cpu: dodecacore
  9. domain:
  10. cpu:
  11. cores: 12
  12. ---
  13. apiVersion: kubevirt.io/v1alpha3
  14. kind: VirtualMachineInstance
  15. metadata:
  16. name: windows-10
  17. labels:
  18. kubevirt.io/os: win10
  19. kubevirt.io/cpu: dodecacore
  20. spec:
  21. ---
  22. apiVersion: kubevirt.io/v1alpha3
  23. kind: VirtualMachineInstance
  24. metadata:
  25. name: windows-7
  26. labels:
  27. kubevirt.io/os: win7
  28. kubevirt.io/cpu: dodecacore
  29. spec:
  30. terminationGracePeriodSeconds: 0

Adding this VirtualMachineInstancePreset and these VirtualMachineInstances will result in:

  1. apiVersion: kubevirt.io/v1alpha3
  2. kind: VirtualMachineInstance
  3. metadata:
  4. annotations:
  5. presets.virtualmachineinstances.kubevirt.io/presets-applied: kubevirt.io/v1alpha3
  6. virtualmachineinstancepreset.kubevirt.io/twelve-cores: kubevirt.io/v1alpha3
  7. labels:
  8. kubevirt.io/cpu: dodecacore
  9. kubevirt.io/os: win10
  10. name: windows-10
  11. spec:
  12. domain:
  13. cpu:
  14. cores: 12
  15. devices: {}
  16. resources:
  17. requests:
  18. memory: 4Gi
  19. ---
  20. apiVersion: kubevirt.io/v1alpha3
  21. kind: VirtualMachineInstance
  22. metadata:
  23. annotations:
  24. presets.virtualmachineinstances.kubevirt.io/presets-applied: kubevirt.io/v1alpha3
  25. virtualmachineinstancepreset.kubevirt.io/twelve-cores: kubevirt.io/v1alpha3
  26. labels:
  27. kubevirt.io/cpu: dodecacore
  28. kubevirt.io/os: win7
  29. name: windows-7
  30. spec:
  31. domain:
  32. cpu:
  33. cores: 12
  34. devices: {}
  35. resources:
  36. requests:
  37. memory: 4Gi
  38. terminationGracePeriodSeconds: 0

Matching Multiple VirtualMachineInstances Using MatchExpressions

This VirtualMachineInstancePreset has a matchExpression that will match two labels: kubevirt.io/os: win10 and kubevirt.io/os: win7.

  1. apiVersion: kubevirt.io/v1alpha3
  2. kind: VirtualMachineInstancePreset
  3. metadata:
  4. name: windows-vmis
  5. spec:
  6. selector:
  7. matchExpressions:
  8. - {key: kubevirt.io/os, operator: In, values: [win10, win7]}
  9. domain:
  10. resources:
  11. requests:
  12. memory: 128M
  13. ---
  14. apiVersion: kubevirt.io/v1alpha3
  15. kind: VirtualMachineInstance
  16. metadata:
  17. name: smallvmi
  18. labels:
  19. kubevirt.io/os: win10
  20. spec:
  21. terminationGracePeriodSeconds: 60
  22. ---
  23. apiVersion: kubevirt.io/v1alpha3
  24. kind: VirtualMachineInstance
  25. metadata:
  26. name: largevmi
  27. labels:
  28. kubevirt.io/os: win7
  29. spec:
  30. terminationGracePeriodSeconds: 120

Applying the preset to both VM’s will result in:

  1. apiVersion: v1
  2. items:
  3. - apiVersion: kubevirt.io/v1alpha3
  4. kind: VirtualMachineInstance
  5. metadata:
  6. annotations:
  7. presets.virtualmachineinstances.kubevirt.io/presets-applied: kubevirt.io/v1alpha3
  8. virtualmachineinstancepreset.kubevirt.io/windows-vmis: kubevirt.io/v1alpha3
  9. labels:
  10. kubevirt.io/os: win7
  11. name: largevmi
  12. spec:
  13. domain:
  14. resources:
  15. requests:
  16. memory: 128M
  17. terminationGracePeriodSeconds: 120
  18. - apiVersion: kubevirt.io/v1alpha3
  19. kind: VirtualMachineInstance
  20. metadata:
  21. annotations:
  22. presets.virtualmachineinstances.kubevirt.io/presets-applied: kubevirt.io/v1alpha3
  23. virtualmachineinstancepreset.kubevirt.io/windows-vmis: kubevirt.io/v1alpha3
  24. labels:
  25. kubevirt.io/os: win10
  26. name: smallvmi
  27. spec:
  28. domain:
  29. resources:
  30. requests:
  31. memory: 128M
  32. terminationGracePeriodSeconds: 60