Skip to content

Commit e544b77

Browse files
authored
[release/v1.61] Cherry pick 1906 to release/v1.61 (#1916)
* Change KubeVirt VM CPU assignment to not overwrite cpu alloc ratio (#1906) * change kubevirt vm cpu assignment to not overwrite cpu alloc ratio Signed-off-by: soer3n <[email protected]> * update kubevirt testdata Signed-off-by: soer3n <[email protected]> * revert testdata change and add condition for vm cpu assignment Signed-off-by: soer3n <[email protected]> * switch to providerSpec for enabling vcpu assignment Signed-off-by: soer3n <[email protected]> * adapt kubevirt cpu struct * adapt kubevirt cpu struct for configuring vcpus for a virtual machine * modify logic in function for rendering resource requests and limits * modify validation accordingly to be a bit more specific regarding resources Signed-off-by: soer3n <[email protected]> * revert unnessecarry changes to mocked kubevirt vm Signed-off-by: soer3n <[email protected]> * changes after review Signed-off-by: soer3n <[email protected]> --------- Signed-off-by: soer3n <[email protected]> * fix kubevirt cpu check + update sdk version in go.mod Signed-off-by: soer3n <[email protected]> revert change regarding import of sdk submodule Signed-off-by: soer3n <[email protected]> kubevirt resources and vcpus should only be parsed wihtout specified instance type Signed-off-by: soer3n <[email protected]> --------- Signed-off-by: soer3n <[email protected]>
1 parent 55336e3 commit e544b77

File tree

4 files changed

+144
-14
lines changed

4 files changed

+144
-14
lines changed

pkg/cloudprovider/provider/kubevirt/provider.go

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ type Config struct {
9999
DNSConfig *corev1.PodDNSConfig
100100
DNSPolicy corev1.DNSPolicy
101101
CPUs string
102+
VCPUs *kubevirtv1.CPU
103+
Resources *corev1.ResourceList
102104
Memory string
103105
Namespace string
104106
OSImageSource *cdiv1beta1.DataVolumeSource
@@ -274,14 +276,23 @@ func (p *provider) getConfig(provSpec clusterv1alpha1.ProviderSpec) (*Config, *p
274276
return nil, nil, fmt.Errorf("failed to decode kubeconfig: %w", err)
275277
}
276278

277-
config.CPUs, err = p.configVarResolver.GetConfigVarStringValue(rawConfig.VirtualMachine.Template.CPUs)
279+
cpus, err := p.configVarResolver.GetConfigVarStringValue(rawConfig.VirtualMachine.Template.CPUs)
278280
if err != nil {
279281
return nil, nil, fmt.Errorf(`failed to get value of "cpus" field: %w`, err)
280282
}
281-
config.Memory, err = p.configVarResolver.GetConfigVarStringValue(rawConfig.VirtualMachine.Template.Memory)
283+
284+
memory, err := p.configVarResolver.GetConfigVarStringValue(rawConfig.VirtualMachine.Template.Memory)
282285
if err != nil {
283286
return nil, nil, fmt.Errorf(`failed to get value of "memory" field: %w`, err)
284287
}
288+
289+
if rawConfig.VirtualMachine.Instancetype == nil {
290+
config.Resources, config.VCPUs, err = parseResources(cpus, memory, rawConfig.VirtualMachine.Template.VCPUs)
291+
if err != nil {
292+
return nil, nil, fmt.Errorf(`failed to configure resource requests and limits and vcpus: %w`, err)
293+
}
294+
}
295+
285296
config.Namespace = getNamespace()
286297
if len(rawConfig.VirtualMachine.Template.PrimaryDisk.ExtraHeaders) > 0 {
287298
config.ExtraHeaders = rawConfig.VirtualMachine.Template.PrimaryDisk.ExtraHeaders
@@ -617,8 +628,16 @@ func (p *provider) Validate(ctx context.Context, _ *zap.SugaredLogger, spec clus
617628
// If instancetype is specified, skip CPU and Memory validation.
618629
// Values will come from instancetype.
619630
if c.Instancetype == nil {
620-
if _, err := parseResources(c.CPUs, c.Memory); err != nil {
621-
return err
631+
if c.Resources == nil {
632+
return fmt.Errorf("no resource requests set for the virtual machine")
633+
}
634+
635+
if c.VCPUs == nil && c.Resources.Cpu().IsZero() {
636+
return fmt.Errorf("no CPUs configured. Either vCPUs or CPUs have to be set")
637+
}
638+
639+
if c.VCPUs != nil && !c.Resources.Cpu().IsZero() {
640+
return fmt.Errorf("vCPUs and CPUs cannot be configured at the same time")
622641
}
623642
}
624643

@@ -754,12 +773,8 @@ func (p *provider) newVirtualMachine(c *Config, pc *providerconfigtypes.Config,
754773

755774
// if no instancetype, resources are from config.
756775
if c.Instancetype == nil {
757-
requestsAndLimits, err := parseResources(c.CPUs, c.Memory)
758-
if err != nil {
759-
return nil, err
760-
}
761-
resourceRequirements.Requests = *requestsAndLimits
762-
resourceRequirements.Limits = *requestsAndLimits
776+
resourceRequirements.Requests = *c.Resources
777+
resourceRequirements.Limits = *c.Resources
763778
}
764779

765780
// Add cluster labels
@@ -841,6 +856,13 @@ func (p *provider) newVirtualMachine(c *Config, pc *providerconfigtypes.Config,
841856
DataVolumeTemplates: getDataVolumeTemplates(c, dataVolumeName, dvAnnotations),
842857
},
843858
}
859+
860+
if c.VCPUs != nil {
861+
virtualMachine.Spec.Template.Spec.Domain.CPU = &kubevirtv1.CPU{
862+
Cores: c.VCPUs.Cores,
863+
}
864+
}
865+
844866
return virtualMachine, nil
845867
}
846868

@@ -868,19 +890,25 @@ func (p *provider) Cleanup(ctx context.Context, _ *zap.SugaredLogger, machine *c
868890
return false, sigClient.Delete(ctx, vm)
869891
}
870892

871-
func parseResources(cpus, memory string) (*corev1.ResourceList, error) {
893+
func parseResources(cpus, memory string, vpcus kubevirttypes.VCPUs) (*corev1.ResourceList, *kubevirtv1.CPU, error) {
872894
memoryResource, err := resource.ParseQuantity(memory)
873895
if err != nil {
874-
return nil, fmt.Errorf("failed to parse memory requests: %w", err)
896+
return nil, nil, fmt.Errorf("failed to parse memory requests: %w", err)
897+
}
898+
899+
if vpcus.Cores != 0 {
900+
return &corev1.ResourceList{corev1.ResourceMemory: memoryResource}, &kubevirtv1.CPU{Cores: uint32(vpcus.Cores)}, nil
875901
}
902+
876903
cpuResource, err := resource.ParseQuantity(cpus)
877904
if err != nil {
878-
return nil, fmt.Errorf("failed to parse cpu request: %w", err)
905+
return nil, nil, fmt.Errorf("failed to parse cpu requests: %w", err)
879906
}
907+
880908
return &corev1.ResourceList{
881909
corev1.ResourceMemory: memoryResource,
882910
corev1.ResourceCPU: cpuResource,
883-
}, nil
911+
}, nil, nil
884912
}
885913

886914
func (p *provider) SetMetricsForMachines(_ clusterv1alpha1.MachineList) error {

pkg/cloudprovider/provider/kubevirt/provider_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ type kubevirtProviderSpecConf struct {
7272
ProviderNetwork *types.ProviderNetwork
7373
ExtraHeadersSet bool
7474
EvictStrategy string
75+
VCPUs uint32
7576
}
7677

7778
func (k kubevirtProviderSpecConf) rawProviderSpec(t *testing.T) []byte {
@@ -132,7 +133,13 @@ func (k kubevirtProviderSpecConf) rawProviderSpec(t *testing.T) []byte {
132133
},
133134
{{- end }}
134135
"template": {
136+
{{- if .VCPUs }}
137+
"vcpus": {
138+
"cores": {{ .VCPUs }}
139+
},
140+
{{- else }}
135141
"cpus": "2",
142+
{{- end }}
136143
"memory": "2Gi",
137144
{{- if .SecondaryDisks }}
138145
"secondaryDisks": [{
@@ -283,6 +290,10 @@ func TestNewVirtualMachine(t *testing.T) {
283290
name: "eviction-strategy-live-migrate",
284291
specConf: kubevirtProviderSpecConf{EvictStrategy: "LiveMigrate"},
285292
},
293+
{
294+
name: "dedicated-vcpus",
295+
specConf: kubevirtProviderSpecConf{VCPUs: 2},
296+
},
286297
}
287298
for _, tt := range tests {
288299
t.Run(tt.name, func(t *testing.T) {
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
apiVersion: kubevirt.io/v1
2+
kind: VirtualMachine
3+
metadata:
4+
annotations:
5+
labels:
6+
cluster.x-k8s.io/cluster-name: cluster-name
7+
cluster.x-k8s.io/role: worker
8+
kubevirt.io/vm: dedicated-vcpus
9+
md: md-name
10+
name: dedicated-vcpus
11+
namespace: test-namespace
12+
spec:
13+
dataVolumeTemplates:
14+
- metadata:
15+
name: dedicated-vcpus
16+
spec:
17+
storage:
18+
accessModes:
19+
- ReadWriteMany
20+
resources:
21+
requests:
22+
storage: 10Gi
23+
storageClassName: longhorn
24+
source:
25+
http:
26+
url: http://x.y.z.t/ubuntu.img
27+
runStrategy: Once
28+
template:
29+
metadata:
30+
creationTimestamp: null
31+
annotations:
32+
"kubevirt.io/allow-pod-bridge-network-live-migration": "true"
33+
"ovn.kubernetes.io/allow_live_migration": "true"
34+
labels:
35+
cluster.x-k8s.io/cluster-name: cluster-name
36+
cluster.x-k8s.io/role: worker
37+
kubevirt.io/vm: dedicated-vcpus
38+
md: md-name
39+
spec:
40+
affinity: {}
41+
domain:
42+
cpu:
43+
cores: 2
44+
devices:
45+
disks:
46+
- disk:
47+
bus: virtio
48+
name: datavolumedisk
49+
- disk:
50+
bus: virtio
51+
name: cloudinitdisk
52+
interfaces:
53+
- name: default
54+
bridge: {}
55+
networkInterfaceMultiqueue: true
56+
resources:
57+
limits:
58+
memory: 2Gi
59+
requests:
60+
memory: 2Gi
61+
networks:
62+
- name: default
63+
pod: {}
64+
terminationGracePeriodSeconds: 30
65+
topologyspreadconstraints:
66+
- maxskew: 1
67+
topologykey: kubernetes.io/hostname
68+
whenunsatisfiable: ScheduleAnyway
69+
labelselector:
70+
matchlabels:
71+
md: md-name
72+
volumes:
73+
- dataVolume:
74+
name: dedicated-vcpus
75+
name: datavolumedisk
76+
- cloudInitNoCloud:
77+
secretRef:
78+
name: udsn
79+
name: cloudinitdisk
80+
evictionStrategy: External

pkg/cloudprovider/provider/kubevirt/types/types.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,23 @@ type Flavor struct {
7070

7171
// Template.
7272
type Template struct {
73+
// VCPUs is to configure vcpus used by a the virtual machine
74+
// when using kubevirts cpuAllocationRatio feature this leads to auto assignment of the
75+
// calculated ratio as resource cpu requests for the pod which launches the virtual machine
76+
VCPUs VCPUs `json:"vcpus,omitempty"`
77+
// CPUs is to configure cpu requests and limits directly for the pod which launches the virtual machine
78+
// and is related to the underlying hardware
7379
CPUs providerconfigtypes.ConfigVarString `json:"cpus,omitempty"`
7480
Memory providerconfigtypes.ConfigVarString `json:"memory,omitempty"`
7581
PrimaryDisk PrimaryDisk `json:"primaryDisk,omitempty"`
7682
SecondaryDisks []SecondaryDisks `json:"secondaryDisks,omitempty"`
7783
}
7884

85+
// VCPUs.
86+
type VCPUs struct {
87+
Cores int `json:"cores,omitempty"`
88+
}
89+
7990
// PrimaryDisk.
8091
type PrimaryDisk struct {
8192
Disk

0 commit comments

Comments
 (0)