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.
VirtualMachineInstancePresets are applied early while processing VirtualMachineInstance
resources. This means the VirtualMachineInstance resource is modified before it
is processed by any other component of KubeVirt.
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.
KubeVirt uses Kubernetes Labels and Selectors to determine which
VirtualMachineInstancePresets apply to any given VirtualMachineInstance, similarly to how
PodPresets work in Kubernetes. The VirtualMachineInstance is marked with an
Annotation upon successful completion.
Any domain structure can be listed in the spec of a VirtualMachineInstancePreset.
e.g. Clock, Features, Memory, CPU, or Devices such network interfaces. All
elements of the spec section of a VirtualMachineInstancePreset will be applied
to the VirtualMachineInstance.
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.
Because VirtualMachineInstancePresets are implemented within the virt-controller pod,
log messages associated with resource conflicts will also be reflected there.
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:
kind: VirtualMachineInstancePreset
metadata:
name: example-preset
spec:
selector:
matchLabels:
kubevirt.io/flavor: foo
...would match any VirtualMachineInstance in the same namespace with a Label of
kubevirt.io/flavor: foo. For example:
kind: VirtualMachineInstance
version: v1
metadata:
name: myvm
labels:
kubevirt.io/flavor: foo
...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:
kind: VirtualMachineInstance
version: v1
metadata:
name: myvm
annotations:
virtualmachinepresets.admission.kubevirt.io/exclude: "true"
...apiVersion: kubevirt.io/v1alpha2
kind: VirtualMachineInstancePreset
metadata:
name: example-preset
spec:
selector:
matchLabels:
kubevirt.io/flavor: windows-10
domain:
features:
acpi: {}
apic: {}
hyperv:
relaxed: {}
vapic: {}
spinlocks:
spinlocks: 8191
---
apiVersion: kubevirt.io/v1alpha2
kind: VirtualMachineInstance
version: v1
metadata:
name: myvm
labels:
kubevirt.io/flavor: windows-10
spec:
domain:
firmware:
uuid: c8f99fc8-20f5-46c4-85e5-2b841c547cefOnce the VirtualMachineInstancePreset is applied to the VirtualMachineInstance, the
resulting resource would look like this:
apiVersion: v1
items:
- apiVersion: kubevirt.io/v1alpha2
kind: VirtualMachineInstance
metadata:
annotations:
presets.virtualmachines.kubevirt.io/presets-applied: kubevirt.io/v1alpha2
virtualmachinepreset.kubevirt.io/example-preset: kubevirt.io/v1alpha2
labels:
kubevirt.io/flavor: windows-10
name: myvm
namespace: default
selfLink: /apis/kubevirt.io/v1alpha2/namespaces/default/virtualmachineinstances/myvm
spec:
domain:
devices: {}
features:
acpi:
enabled: true
apic:
enabled: true
hyperv:
relaxed:
enabled: true
spinlocks:
enabled: true
spinlocks: 8191
vapic:
enabled: true
firmware:
uuid: c8f99fc8-20f5-46c4-85e5-2b841c547cef
machine:
type: q35
resources:
requests:
memory: 8Mi
status:
phase: Scheduling
kind: List
metadata:
resourceVersion: ""
selfLink: ""This is an example of a merge conflict. In this case both the VirtualMachineInstance
and VirtualMachineInstancePreset request different number of CPU's.
apiVersion: kubevirt.io/v1alpha2
kind: VirtualMachineInstancePreset
metadata:
name: example-preset
spec:
selector:
matchLabels:
kubevirt.io/flavor: default-features
domain:
cpu:
cores: 4
---
apiVersion: kubevirt.io/v1alpha2
kind: VirtualMachineInstance
version: v1
metadata:
name: myvm
labels:
kubevirt.io/flavor: default-features
spec:
domain:
cpu:
cores: 6In this case the VirtualMachineInstance Spec will remain unmodified. Use
kubectl get events to show events.
apiVersion: v1
items:
- apiVersion: kubevirt.io/v1alpha2
kind: VirtualMachineInstance
metadata:
annotations:
presets.virtualmachines.kubevirt.io/presets-applied: kubevirt.io/v1alpha2
clusterName: ""
labels:
kubevirt.io/flavor: default-features
name: myvm
namespace: default
selfLink: /apis/kubevirt.io/v1alpha2/namespaces/default/virtualmachineinstances/myvm
spec:
domain:
cpu:
cores: 6
devices: {}
features:
acpi:
enabled: true
firmware:
uuid: efaaa6e4-0002-44d6-9de1-5526b24615d1
machine:
type: q35
resources:
requests:
memory: 8Mi
status:
phase: Scheduling
kind: List
metadata:
resourceVersion: ""
selfLink: ""Calling kubectl get events would have a line like:
2m 2m 1 myvm.1515bbb8d397f258 VirtualMachineInstance Warning Conflict virtualmachine-preset-controller Unable to apply VirtualMachineInstancePreset 'example-preset': spec.cpu: &{6} != &{4}