Skip to content

Latest commit

 

History

History
273 lines (234 loc) · 7.42 KB

vm-presets.md

File metadata and controls

273 lines (234 loc) · 7.42 KB

Virtual Machine 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.

Implementation

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.

Usage

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.

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.

Because VirtualMachineInstancePresets are implemented within the virt-controller pod, log messages associated with resource conflicts will also be reflected there.

Creation and 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:

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
  ...

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:

kind: VirtualMachineInstance
version: v1
metadata:
  name: myvm
  annotations:
    virtualmachinepresets.admission.kubevirt.io/exclude: "true"
  ...

Examples

Simple VirtualMachineInstancePreset Example

apiVersion: kubevirt.io/v1
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/v1
kind: VirtualMachineInstance
version: v1
metadata:
  name: myvm
  labels:
    kubevirt.io/flavor: windows-10
spec:
  domain:
    firmware:
      uuid: c8f99fc8-20f5-46c4-85e5-2b841c547cef

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

apiVersion: v1
items:
- apiVersion: kubevirt.io/v1
  kind: VirtualMachineInstance
  metadata:
    annotations:
      presets.virtualmachines.kubevirt.io/presets-applied: kubevirt.io/v1
      virtualmachinepreset.kubevirt.io/example-preset: kubevirt.io/v1
    labels:
      kubevirt.io/flavor: windows-10
    name: myvm
    namespace: default
    selfLink: /apis/kubevirt.io/v1/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: ""

Conflict Example

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/v1
kind: VirtualMachineInstancePreset
metadata:
  name: example-preset
spec:
  selector:
    matchLabels:
      kubevirt.io/flavor: default-features
  domain:
    cpu:
      cores: 4
---
apiVersion: kubevirt.io/v1
kind: VirtualMachineInstance
version: v1
metadata:
  name: myvm
  labels:
    kubevirt.io/flavor: default-features
spec:
  domain:
    cpu:
      cores: 6

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

apiVersion: v1
items:
- apiVersion: kubevirt.io/v1
  kind: VirtualMachineInstance
  metadata:
    annotations:
      presets.virtualmachines.kubevirt.io/presets-applied: kubevirt.io/v1
    clusterName: ""
    labels:
      kubevirt.io/flavor: default-features
    name: myvm
    namespace: default
    selfLink: /apis/kubevirt.io/v1/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}