From 5abf3e4dab160e5c3fcbb3b97bcb4f1d23bc1221 Mon Sep 17 00:00:00 2001 From: Martin Necas Date: Fri, 13 Dec 2024 16:12:21 +0100 Subject: [PATCH] MTV-1493 | Add missing resource limits and requests Issue: If the user sets ClusterResourceQuota the Forklift will start failing as it does not have the limits or requests on the pods which are created form the Forklift Controller. Fix: Add a new parameters to Forklift operator which can be configured depedning on the user env. Ref: https://issues.redhat.com/browse/MTV-1493 Signed-off-by: Martin Necas --- .../forkliftcontroller/defaults/main.yml | 13 +++ .../controller/deployment-controller.yml.j2 | 26 +++++ pkg/controller/plan/hook.go | 11 ++ pkg/controller/plan/kubevirt.go | 30 ++++++ pkg/controller/plan/validation.go | 23 +++- pkg/controller/provider/ova-setup.go | 10 ++ pkg/settings/migration.go | 102 ++++++++++++++---- 7 files changed, 193 insertions(+), 22 deletions(-) diff --git a/operator/roles/forkliftcontroller/defaults/main.yml b/operator/roles/forkliftcontroller/defaults/main.yml index 86f7c8b39..e9915adbb 100644 --- a/operator/roles/forkliftcontroller/defaults/main.yml +++ b/operator/roles/forkliftcontroller/defaults/main.yml @@ -115,8 +115,21 @@ virt_v2v_image_fqin: "{{ lookup( 'env', 'VIRT_V2V_IMAGE') or lookup( 'env', 'REL virt_v2v_dont_request_kvm: "{{ lookup( 'env', 'VIRT_V2V_DONT_REQUEST_KVM') }}" virt_v2v_extra_args: "{{ lookup( 'env', 'VIRT_V2V_EXTRA_ARGS') }}" virt_v2v_extra_conf_config_map: "{{ lookup( 'env', 'VIRT_V2V_EXTRA_CONF_CONFIG_MAP') }}" +virt_v2v_container_limits_cpu: "1000m" +virt_v2v_container_limits_memory: "8Gi" +virt_v2v_container_requests_cpu: "1000m" +virt_v2v_container_requests_memory: "1Gi" + +hooks_container_limits_cpu: "1000m" +hooks_container_limits_memory: "1Gi" +hooks_container_requests_cpu: "100m" +hooks_container_requests_memory: "150Mi" ova_provider_server_fqin: "{{ lookup( 'env', 'OVA_PROVIDER_SERVER_IMAGE') or lookup( 'env', 'RELATED_IMAGE_OVA_PROVIDER_SERVER') }}" +ova_container_limits_cpu: "1000m" +ova_container_limits_memory: "1Gi" +ova_container_requests_cpu: "100m" +ova_container_requests_memory: "150Mi" metric_service_name: "{{ app_name }}-metrics" metric_servicemonitor_name: "{{ app_name }}-metrics" diff --git a/operator/roles/forkliftcontroller/templates/controller/deployment-controller.yml.j2 b/operator/roles/forkliftcontroller/templates/controller/deployment-controller.yml.j2 index 28bfbcc77..0c1a5a4cc 100644 --- a/operator/roles/forkliftcontroller/templates/controller/deployment-controller.yml.j2 +++ b/operator/roles/forkliftcontroller/templates/controller/deployment-controller.yml.j2 @@ -143,6 +143,30 @@ spec: value: "{{ virt_v2v_extra_args }}" - name: VIRT_V2V_EXTRA_CONF_CONFIG_MAP value: "{{ virt_v2v_extra_conf_config_map }}" + - name: VIRT_V2V_CONTAINER_LIMITS_CPU + value: "{{ virt_v2v_container_limits_cpu }}" + - name: VIRT_V2V_CONTAINER_LIMITS_MEMORY + value: "{{ virt_v2v_container_limits_memory }}" + - name: VIRT_V2V_CONTAINER_REQUESTS_CPU + value: "{{ virt_v2v_container_requests_cpu }}" + - name: VIRT_V2V_CONTAINER_REQUESTS_MEMORY + value: "{{ virt_v2v_container_requests_memory }}" + - name: HOOKS_CONTAINER_LIMITS_CPU + value: "{{ hooks_container_limits_cpu }}" + - name: HOOKS_CONTAINER_LIMITS_MEMORY + value: "{{ hooks_container_limits_memory }}" + - name: HOOKS_CONTAINER_REQUESTS_CPU + value: "{{ hooks_container_requests_cpu }}" + - name: HOOKS_CONTAINER_REQUESTS_MEMORY + value: "{{ hooks_container_requests_memory }}" + - name: OVA_CONTAINER_LIMITS_CPU + value: "{{ ova_container_limits_cpu }}" + - name: OVA_CONTAINER_LIMITS_MEMORY + value: "{{ ova_container_limits_memory }}" + - name: OVA_CONTAINER_REQUESTS_CPU + value: "{{ ova_container_requests_cpu }}" + - name: OVA_CONTAINER_REQUESTS_MEMORY + value: "{{ ova_container_requests_memory }}" envFrom: - configMapRef: name: {{ controller_configmap_name }} @@ -186,6 +210,8 @@ spec: value: '8082' - name: OVA_PROVIDER_SERVER_IMAGE value: {{ ova_provider_server_fqin }} + - name: OVA_PROVIDER_SERVER_IMAGE + value: {{ ova_provider_server_fqin }} {% if feature_validation|bool %} - name: POLICY_AGENT_URL value: "https://{{ validation_service_name }}.{{ app_namespace }}.svc.cluster.local:8181" diff --git a/pkg/controller/plan/hook.go b/pkg/controller/plan/hook.go index 296b6e5b9..e35550229 100644 --- a/pkg/controller/plan/hook.go +++ b/pkg/controller/plan/hook.go @@ -14,6 +14,7 @@ import ( "gopkg.in/yaml.v2" batch "k8s.io/api/batch/v1" core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/kubernetes/scheme" @@ -181,6 +182,16 @@ func (r *HookRunner) template(mp *core.ConfigMap) (template *core.PodTemplateSpe { Name: "hook", Image: r.hook.Spec.Image, + Resources: core.ResourceRequirements{ + Requests: core.ResourceList{ + core.ResourceCPU: resource.MustParse(Settings.Migration.HooksContainerRequestsCpu), + core.ResourceMemory: resource.MustParse(Settings.Migration.HooksContainerRequestsMemory), + }, + Limits: core.ResourceList{ + core.ResourceCPU: resource.MustParse(Settings.Migration.HooksContainerLimitCpu), + core.ResourceMemory: resource.MustParse(Settings.Migration.HooksContainerLimitMemory), + }, + }, VolumeMounts: []core.VolumeMount{ { Name: "hook", diff --git a/pkg/controller/plan/kubevirt.go b/pkg/controller/plan/kubevirt.go index 74dfd8317..1515a23a9 100644 --- a/pkg/controller/plan/kubevirt.go +++ b/pkg/controller/plan/kubevirt.go @@ -773,6 +773,16 @@ func (r *KubeVirt) createPodToBindPVCs(vm *plan.VMStatus, pvcNames []string) (er // In that case, we could benefit from pulling the image of the conversion pod, so it will be present on the node. Image: Settings.Migration.VirtV2vImage, Command: []string{"/bin/sh"}, + Resources: core.ResourceRequirements{ + Requests: core.ResourceList{ + core.ResourceCPU: resource.MustParse(Settings.Migration.VirtV2vContainerRequestsCpu), + core.ResourceMemory: resource.MustParse(Settings.Migration.VirtV2vContainerRequestsMemory), + }, + Limits: core.ResourceList{ + core.ResourceCPU: resource.MustParse(Settings.Migration.VirtV2vContainerLimitCpu), + core.ResourceMemory: resource.MustParse(Settings.Migration.VirtV2vContainerLimitMemory), + }, + }, SecurityContext: &core.SecurityContext{ AllowPrivilegeEscalation: &allowPrivilageEscalation, RunAsNonRoot: &nonRoot, @@ -1738,6 +1748,16 @@ func (r *KubeVirt) guestConversionPod(vm *plan.VMStatus, vmVolumes []cnv.Volume, MountPath: "/opt", }, }, + Resources: core.ResourceRequirements{ + Requests: core.ResourceList{ + core.ResourceCPU: resource.MustParse("100m"), + core.ResourceMemory: resource.MustParse("150Mi"), + }, + Limits: core.ResourceList{ + core.ResourceCPU: resource.MustParse("100m"), + core.ResourceMemory: resource.MustParse("150Mi"), + }, + }, SecurityContext: &core.SecurityContext{ AllowPrivilegeEscalation: &allowPrivilageEscalation, Capabilities: &core.Capabilities{ @@ -1823,6 +1843,16 @@ func (r *KubeVirt) guestConversionPod(vm *plan.VMStatus, vmVolumes []cnv.Volume, Name: "virt-v2v", Env: environment, ImagePullPolicy: core.PullAlways, + Resources: core.ResourceRequirements{ + Requests: core.ResourceList{ + core.ResourceCPU: resource.MustParse(Settings.Migration.VirtV2vContainerRequestsCpu), + core.ResourceMemory: resource.MustParse(Settings.Migration.VirtV2vContainerRequestsMemory), + }, + Limits: core.ResourceList{ + core.ResourceCPU: resource.MustParse(Settings.Migration.VirtV2vContainerLimitCpu), + core.ResourceMemory: resource.MustParse(Settings.Migration.VirtV2vContainerLimitMemory), + }, + }, EnvFrom: []core.EnvFromSource{ { Prefix: "V2V_", diff --git a/pkg/controller/plan/validation.go b/pkg/controller/plan/validation.go index cbdb61dec..224859f12 100644 --- a/pkg/controller/plan/validation.go +++ b/pkg/controller/plan/validation.go @@ -26,6 +26,7 @@ import ( core "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" k8serr "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" k8svalidation "k8s.io/apimachinery/pkg/util/validation" @@ -1016,6 +1017,16 @@ func createVddkCheckJob(plan *api.Plan) *batchv1.Job { Drop: []core.Capability{"ALL"}, }, }, + Resources: core.ResourceRequirements{ + Requests: core.ResourceList{ + core.ResourceCPU: resource.MustParse("100m"), + core.ResourceMemory: resource.MustParse("150Mi"), + }, + Limits: core.ResourceList{ + core.ResourceCPU: resource.MustParse("1000m"), + core.ResourceMemory: resource.MustParse("500Mi"), + }, + }, }, } @@ -1057,7 +1068,17 @@ func createVddkCheckJob(plan *api.Plan) *batchv1.Job { InitContainers: initContainers, Containers: []core.Container{ { - Name: "validator", + Name: "validator", + Resources: core.ResourceRequirements{ + Requests: core.ResourceList{ + core.ResourceCPU: resource.MustParse("100m"), + core.ResourceMemory: resource.MustParse("150Mi"), + }, + Limits: core.ResourceList{ + core.ResourceCPU: resource.MustParse("1000m"), + core.ResourceMemory: resource.MustParse("500Mi"), + }, + }, Image: Settings.Migration.VirtV2vImage, SecurityContext: &core.SecurityContext{ AllowPrivilegeEscalation: ptr.To(false), diff --git a/pkg/controller/provider/ova-setup.go b/pkg/controller/provider/ova-setup.go index 03b562b73..b6ad37f0c 100644 --- a/pkg/controller/provider/ova-setup.go +++ b/pkg/controller/provider/ova-setup.go @@ -224,6 +224,16 @@ func (r *Reconciler) makeOvaProviderPodSpec(pvcName, providerName, providerNames MountPath: mountPath, }, }, + Resources: core.ResourceRequirements{ + Requests: core.ResourceList{ + core.ResourceCPU: resource.MustParse(Settings.OvaContainerRequestsCpu), + core.ResourceMemory: resource.MustParse(Settings.OvaContainerRequestsMemory), + }, + Limits: core.ResourceList{ + core.ResourceCPU: resource.MustParse(Settings.OvaContainerLimitCpu), + core.ResourceMemory: resource.MustParse(Settings.OvaContainerRequestsMemory), + }, + }, SecurityContext: securityContext, } diff --git a/pkg/settings/migration.go b/pkg/settings/migration.go index 354eadd18..8ecd376c3 100644 --- a/pkg/settings/migration.go +++ b/pkg/settings/migration.go @@ -12,26 +12,38 @@ import ( // Environment variables. const ( - MaxVmInFlight = "MAX_VM_INFLIGHT" - HookRetry = "HOOK_RETRY" - ImporterRetry = "IMPORTER_RETRY" - VirtV2vImage = "VIRT_V2V_IMAGE" - PrecopyInterval = "PRECOPY_INTERVAL" - VirtV2vDontRequestKVM = "VIRT_V2V_DONT_REQUEST_KVM" - SnapshotRemovalTimeout = "SNAPSHOT_REMOVAL_TIMEOUT" - SnapshotStatusCheckRate = "SNAPSHOT_STATUS_CHECK_RATE" - CDIExportTokenTTL = "CDI_EXPORT_TOKEN_TTL" - FileSystemOverhead = "FILESYSTEM_OVERHEAD" - BlockOverhead = "BLOCK_OVERHEAD" - CleanupRetries = "CLEANUP_RETRIES" - DvStatusCheckRetries = "DV_STATUS_CHECK_RETRIES" - SnapshotRemovalCheckRetries = "SNAPSHOT_REMOVAL_CHECK_RETRIES" - OvirtOsConfigMap = "OVIRT_OS_MAP" - VsphereOsConfigMap = "VSPHERE_OS_MAP" - VirtCustomizeConfigMap = "VIRT_CUSTOMIZE_MAP" - VddkJobActiveDeadline = "VDDK_JOB_ACTIVE_DEADLINE" - VirtV2vExtraArgs = "VIRT_V2V_EXTRA_ARGS" - VirtV2vExtraConfConfigMap = "VIRT_V2V_EXTRA_CONF_CONFIG_MAP" + MaxVmInFlight = "MAX_VM_INFLIGHT" + HookRetry = "HOOK_RETRY" + ImporterRetry = "IMPORTER_RETRY" + VirtV2vImage = "VIRT_V2V_IMAGE" + PrecopyInterval = "PRECOPY_INTERVAL" + VirtV2vDontRequestKVM = "VIRT_V2V_DONT_REQUEST_KVM" + SnapshotRemovalTimeout = "SNAPSHOT_REMOVAL_TIMEOUT" + SnapshotStatusCheckRate = "SNAPSHOT_STATUS_CHECK_RATE" + CDIExportTokenTTL = "CDI_EXPORT_TOKEN_TTL" + FileSystemOverhead = "FILESYSTEM_OVERHEAD" + BlockOverhead = "BLOCK_OVERHEAD" + CleanupRetries = "CLEANUP_RETRIES" + DvStatusCheckRetries = "DV_STATUS_CHECK_RETRIES" + SnapshotRemovalCheckRetries = "SNAPSHOT_REMOVAL_CHECK_RETRIES" + OvirtOsConfigMap = "OVIRT_OS_MAP" + VsphereOsConfigMap = "VSPHERE_OS_MAP" + VirtCustomizeConfigMap = "VIRT_CUSTOMIZE_MAP" + VddkJobActiveDeadline = "VDDK_JOB_ACTIVE_DEADLINE" + VirtV2vExtraArgs = "VIRT_V2V_EXTRA_ARGS" + VirtV2vExtraConfConfigMap = "VIRT_V2V_EXTRA_CONF_CONFIG_MAP" + VirtV2vContainerLimitCpu = "VIRT_V2V_CONTAINER_LIMITS_CPU" + VirtV2vContainerLimitMemory = "VIRT_V2V_CONTAINER_LIMITS_MEMORY" + VirtV2vContainerRequestsCpu = "VIRT_V2V_CONTAINER_REQUESTS_CPU" + VirtV2vContainerRequestsMemory = "VIRT_V2V_CONTAINER_REQUESTS_MEMORY" + HooksContainerLimitCpu = "HOOKS_CONTAINER_LIMITS_CPU" + HooksContainerLimitMemory = "HOOKS_CONTAINER_LIMITS_MEMORY" + HooksContainerRequestsCpu = "HOOKS_CONTAINER_REQUESTS_CPU" + HooksContainerRequestsMemory = "HOOKS_CONTAINER_REQUESTS_MEMORY" + OvaContainerLimitCpu = "OVA_CONTAINER_LIMITS_CPU" + OvaContainerLimitMemory = "OVA_CONTAINER_LIMITS_MEMORY" + OvaContainerRequestsCpu = "OVA_CONTAINER_REQUESTS_CPU" + OvaContainerRequestsMemory = "OVA_CONTAINER_REQUESTS_MEMORY" ) // Migration settings @@ -75,7 +87,19 @@ type Migration struct { // Additional arguments for virt-v2v VirtV2vExtraArgs string // Additional configuration for virt-v2v - VirtV2vExtraConfConfigMap string + VirtV2vExtraConfConfigMap string + VirtV2vContainerLimitCpu string + VirtV2vContainerLimitMemory string + VirtV2vContainerRequestsCpu string + VirtV2vContainerRequestsMemory string + HooksContainerLimitCpu string + HooksContainerLimitMemory string + HooksContainerRequestsCpu string + HooksContainerRequestsMemory string + OvaContainerLimitCpu string + OvaContainerLimitMemory string + OvaContainerRequestsCpu string + OvaContainerRequestsMemory string } // Load settings. @@ -157,5 +181,41 @@ func (r *Migration) Load() (err error) { if val, found := os.LookupEnv(VirtV2vExtraConfConfigMap); found { r.VirtV2vExtraConfConfigMap = val } + if val, found := os.LookupEnv(VirtV2vContainerLimitCpu); found { + r.VirtV2vContainerLimitCpu = val + } + if val, found := os.LookupEnv(VirtV2vContainerLimitMemory); found { + r.VirtV2vContainerLimitMemory = val + } + if val, found := os.LookupEnv(VirtV2vContainerRequestsCpu); found { + r.VirtV2vContainerRequestsCpu = val + } + if val, found := os.LookupEnv(VirtV2vContainerRequestsMemory); found { + r.VirtV2vContainerRequestsMemory = val + } + if val, found := os.LookupEnv(HooksContainerLimitCpu); found { + r.HooksContainerLimitCpu = val + } + if val, found := os.LookupEnv(HooksContainerLimitMemory); found { + r.HooksContainerLimitMemory = val + } + if val, found := os.LookupEnv(HooksContainerRequestsCpu); found { + r.HooksContainerRequestsCpu = val + } + if val, found := os.LookupEnv(HooksContainerRequestsMemory); found { + r.HooksContainerRequestsMemory = val + } + if val, found := os.LookupEnv(OvaContainerLimitCpu); found { + r.HooksContainerLimitCpu = val + } + if val, found := os.LookupEnv(OvaContainerLimitMemory); found { + r.HooksContainerLimitMemory = val + } + if val, found := os.LookupEnv(OvaContainerRequestsCpu); found { + r.HooksContainerRequestsCpu = val + } + if val, found := os.LookupEnv(OvaContainerRequestsMemory); found { + r.HooksContainerRequestsMemory = val + } return }