Skip to content

Commit

Permalink
Merge pull request kubevirt#6052 from kubevirt-bot/cherry-pick-6005-t…
Browse files Browse the repository at this point in the history
…o-release-0.43

[release-0.43] virt-config: make containerDisk validation memory usage limit configurable
  • Loading branch information
kubevirt-bot authored Jul 16, 2021
2 parents 7c7a2f4 + 41deff6 commit b277ca9
Show file tree
Hide file tree
Showing 18 changed files with 221 additions and 21 deletions.
15 changes: 15 additions & 0 deletions api/openapi-spec/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -9418,6 +9418,9 @@
"type": "integer",
"format": "int32"
},
"diskVerification": {
"$ref": "#/definitions/v1.DiskVerification"
},
"featureGates": {
"type": "array",
"items": {
Expand Down Expand Up @@ -9619,6 +9622,18 @@
}
}
},
"v1.DiskVerification": {
"description": "DiskVerification holds container disks verification limits",
"type": "object",
"required": [
"memoryLimit"
],
"properties": {
"memoryLimit": {
"$ref": "#/definitions/k8s.io.apimachinery.pkg.api.resource.Quantity"
}
}
},
"v1.DomainSpec": {
"type": "object",
"required": [
Expand Down
24 changes: 13 additions & 11 deletions cmd/virt-chroot/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import (
"golang.org/x/sys/unix"
)

var mntNamespace string
var cpuTime uint32
var megabyte uint32
var targetUser string
var (
mntNamespace string
cpuTime uint64
memoryBytes uint64
targetUser string
)

func init() {
// main needs to be locked on one thread and no go routines
Expand Down Expand Up @@ -57,19 +59,19 @@ func main() {

if cpuTime > 0 {
value := &syscall.Rlimit{
Cur: uint64(cpuTime),
Max: uint64(cpuTime),
Cur: cpuTime,
Max: cpuTime,
}
err := syscall.Setrlimit(unix.RLIMIT_CPU, value)
if err != nil {
return fmt.Errorf("error setting prlimit on cpu time with value %d: %v", value, err)
}
}

if megabyte > 0 {
if memoryBytes > 0 {
value := &syscall.Rlimit{
Cur: uint64(megabyte) * 1000000,
Max: uint64(megabyte) * 1000000,
Cur: memoryBytes,
Max: memoryBytes,
}
err := syscall.Setrlimit(unix.RLIMIT_AS, value)
if err != nil {
Expand Down Expand Up @@ -108,8 +110,8 @@ func main() {
},
}

rootCmd.PersistentFlags().Uint32Var(&cpuTime, "cpu", 0, "cpu time in seconds for the process")
rootCmd.PersistentFlags().Uint32Var(&megabyte, "memory", 0, "memory in megabyte for the process")
rootCmd.PersistentFlags().Uint64Var(&cpuTime, "cpu", 0, "cpu time in seconds for the process")
rootCmd.PersistentFlags().Uint64Var(&memoryBytes, "memory", 0, "memory in bytes for the process")
rootCmd.PersistentFlags().StringVar(&mntNamespace, "mount", "", "mount namespace to use")
rootCmd.PersistentFlags().StringVar(&targetUser, "user", "", "switch to this targetUser to e.g. drop privileges")

Expand Down
26 changes: 26 additions & 0 deletions manifests/generated/kv-resource.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,19 @@ spec:
properties:
cpuAllocationRatio:
type: integer
diskVerification:
description: DiskVerification holds container disks verification
limits
properties:
memoryLimit:
anyOf:
- type: integer
- type: string
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
required:
- memoryLimit
type: object
featureGates:
items:
type: string
Expand Down Expand Up @@ -1985,6 +1998,19 @@ spec:
properties:
cpuAllocationRatio:
type: integer
diskVerification:
description: DiskVerification holds container disks verification
limits
properties:
memoryLimit:
anyOf:
- type: integer
- type: string
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
required:
- memoryLimit
type: object
featureGates:
items:
type: string
Expand Down
1 change: 1 addition & 0 deletions pkg/virt-config/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ go_test(
"//vendor/github.com/onsi/ginkgo/extensions/table:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/rand:go_default_library",
"//vendor/k8s.io/utils/pointer:go_default_library",
Expand Down
4 changes: 4 additions & 0 deletions pkg/virt-config/config-map.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ func defaultClusterConfig(cpuArch string) *v1.KubeVirtConfiguration {
}
supportedQEMUGuestAgentVersions := strings.Split(strings.TrimRight(SupportedGuestAgentVersions, ","), ",")
DefaultOVMFPath, DefaultMachineType, emulatedMachinesDefault := getCPUArchSpecificDefault(cpuArch)
defaultDiskVerification := &v1.DiskVerification{
MemoryLimit: resource.NewScaledQuantity(DefaultDiskVerificationMemoryLimitMBytes, resource.Mega),
}

return &v1.KubeVirtConfiguration{
ImagePullPolicy: DefaultImagePullPolicy,
Expand All @@ -205,6 +208,7 @@ func defaultClusterConfig(cpuArch string) *v1.KubeVirtConfiguration {
MinimumReservePVCBytes: DefaultMinimumReservePVCBytes,
NodeSelectors: nodeSelectorsDefault,
CPUAllocationRatio: DefaultCPUAllocationRatio,
DiskVerification: defaultDiskVerification,
LogVerbosity: &v1.LogVerbosity{
VirtAPI: DefaultVirtAPILogVerbosity,
VirtOperator: DefaultVirtOperatorLogVerbosity,
Expand Down
6 changes: 5 additions & 1 deletion pkg/virt-config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega"
kubev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/rand"
"k8s.io/utils/pointer"
Expand Down Expand Up @@ -442,12 +443,15 @@ var _ = Describe("ConfigMap", func() {
NodeSelectors: map[string]string{"test": "test"},
UseEmulation: true,
CPUAllocationRatio: 25,
DiskVerification: &v1.DiskVerification{
MemoryLimit: resource.NewScaledQuantity(1, resource.Giga),
},
},
},
func(c *v1.KubeVirtConfiguration) interface{} {
return c.DeveloperConfiguration
},
`{"featureGates":["test1","test2"],"pvcTolerateLessSpaceUpToPercent":5,"minimumReservePVCBytes":131072,"memoryOvercommit":150,"nodeSelectors":{"test":"test"},"useEmulation":true,"cpuAllocationRatio":25,"logVerbosity":{"virtAPI":2,"virtController":2,"virtHandler":2,"virtLauncher":2,"virtOperator":2}}`),
`{"featureGates":["test1","test2"],"pvcTolerateLessSpaceUpToPercent":5,"minimumReservePVCBytes":131072,"memoryOvercommit":150,"nodeSelectors":{"test":"test"},"useEmulation":true,"cpuAllocationRatio":25,"diskVerification":{"memoryLimit":"1G"},"logVerbosity":{"virtAPI":2,"virtController":2,"virtHandler":2,"virtLauncher":2,"virtOperator":2}}`),
table.Entry("when networkConfiguration set, should equal to result",
v1.KubeVirtConfiguration{
NetworkConfiguration: &v1.NetworkConfiguration{
Expand Down
5 changes: 5 additions & 0 deletions pkg/virt-config/virt-config.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const (
DefaultAARCH64OVMFPath = "/usr/share/AAVMF"
DefaultMemBalloonStatsPeriod uint32 = 10
DefaultCPUAllocationRatio = 10
DefaultDiskVerificationMemoryLimitMBytes = 1200
DefaultVirtAPILogVerbosity = 2
DefaultVirtControllerLogVerbosity = 2
DefaultVirtHandlerLogVerbosity = 2
Expand Down Expand Up @@ -126,6 +127,10 @@ func (c *ClusterConfig) GetCPURequest() *resource.Quantity {
return c.GetConfig().CPURequest
}

func (c *ClusterConfig) GetDiskVerification() *v1.DiskVerification {
return c.GetConfig().DeveloperConfiguration.DiskVerification
}

func (c *ClusterConfig) GetMemoryOvercommit() int {
return c.GetConfig().DeveloperConfiguration.MemoryOvercommit
}
Expand Down
1 change: 1 addition & 0 deletions pkg/virt-handler/container-disk/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ go_library(
"//pkg/container-disk:go_default_library",
"//pkg/ephemeral-disk-utils:go_default_library",
"//pkg/util:go_default_library",
"//pkg/virt-config:go_default_library",
"//pkg/virt-handler/isolation:go_default_library",
"//pkg/virt-handler/virt-chroot:go_default_library",
"//staging/src/kubevirt.io/client-go/api/v1:go_default_library",
Expand Down
7 changes: 5 additions & 2 deletions pkg/virt-handler/container-disk/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"kubevirt.io/kubevirt/pkg/util"
virtconfig "kubevirt.io/kubevirt/pkg/virt-config"
virt_chroot "kubevirt.io/kubevirt/pkg/virt-handler/virt-chroot"

"kubevirt.io/client-go/log"
Expand All @@ -33,6 +34,7 @@ type mounter struct {
suppressWarningTimeout time.Duration
socketPathGetter containerdisk.SocketPathGetter
kernelBootSocketPathGetter containerdisk.KernelBootSocketPathGetter
clusterConfig *virtconfig.ClusterConfig
}

type Mounter interface {
Expand All @@ -52,14 +54,15 @@ type vmiMountTargetRecord struct {
MountTargetEntries []vmiMountTargetEntry `json:"mountTargetEntries"`
}

func NewMounter(isoDetector isolation.PodIsolationDetector, mountStateDir string) Mounter {
func NewMounter(isoDetector isolation.PodIsolationDetector, mountStateDir string, clusterConfig *virtconfig.ClusterConfig) Mounter {
return &mounter{
mountRecords: make(map[types.UID]*vmiMountTargetRecord),
podIsolationDetector: isoDetector,
mountStateDir: mountStateDir,
suppressWarningTimeout: 1 * time.Minute,
socketPathGetter: containerdisk.NewSocketPathGetter(""),
kernelBootSocketPathGetter: containerdisk.NewKernelBootSocketPathGetter(""),
clusterConfig: clusterConfig,
}
}

Expand Down Expand Up @@ -258,7 +261,7 @@ func (m *mounter) Mount(vmi *v1.VirtualMachineInstance, verify bool) error {
if err != nil {
return fmt.Errorf("failed to detect VMI pod: %v", err)
}
imageInfo, err := isolation.GetImageInfo(containerdisk.GetDiskTargetPathFromLauncherView(i), res)
imageInfo, err := isolation.GetImageInfo(containerdisk.GetDiskTargetPathFromLauncherView(i), res, m.clusterConfig.GetDiskVerification())
if err != nil {
return fmt.Errorf("failed to get image info: %v", err)
}
Expand Down
7 changes: 5 additions & 2 deletions pkg/virt-handler/isolation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os/exec"

v1 "kubevirt.io/client-go/api/v1"
virt_chroot "kubevirt.io/kubevirt/pkg/virt-handler/virt-chroot"

containerdisk "kubevirt.io/kubevirt/pkg/container-disk"
Expand All @@ -14,10 +15,12 @@ const (
QEMUIMGPath = "/usr/bin/qemu-img"
)

func GetImageInfo(imagePath string, context IsolationResult) (*containerdisk.DiskInfo, error) {
func GetImageInfo(imagePath string, context IsolationResult, config *v1.DiskVerification) (*containerdisk.DiskInfo, error) {
memoryLimit := fmt.Sprintf("%d", config.MemoryLimit.Value())

// #nosec g204 no risk to use MountNamespace() argument as it returns a fixed string of "/proc/<pid>/ns/mnt"
out, err := virt_chroot.ExecChroot(
"--user", "qemu", "--memory", "1200", "--cpu", "10", "--mount", context.MountNamespace(), "exec", "--",
"--user", "qemu", "--memory", memoryLimit, "--cpu", "10", "--mount", context.MountNamespace(), "exec", "--",
QEMUIMGPath, "info", imagePath, "--output", "json",
).Output()
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/virt-handler/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func NewController(
watchdogTimeoutSeconds: watchdogTimeoutSeconds,
migrationProxy: migrationProxy,
podIsolationDetector: podIsolationDetector,
containerDiskMounter: container_disk.NewMounter(podIsolationDetector, virtPrivateDir+"/container-disk-mount-state"),
containerDiskMounter: container_disk.NewMounter(podIsolationDetector, virtPrivateDir+"/container-disk-mount-state", clusterConfig),
hotplugVolumeMounter: hotplug_volume.NewVolumeMounter(podIsolationDetector, virtPrivateDir+"/hotplug-volume-mount-state"),
clusterConfig: clusterConfig,
networkCacheStoreFactory: netcache.NewInterfaceCacheFactory(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,19 @@ var CRDsValidation map[string]string = map[string]string{
properties:
cpuAllocationRatio:
type: integer
diskVerification:
description: DiskVerification holds container disks verification
limits
properties:
memoryLimit:
anyOf:
- type: integer
- type: string
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
required:
- memoryLimit
type: object
featureGates:
items:
type: string
Expand Down
26 changes: 26 additions & 0 deletions staging/src/kubevirt.io/client-go/api/v1/deepcopy_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 28 additions & 1 deletion staging/src/kubevirt.io/client-go/api/v1/openapi_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b277ca9

Please sign in to comment.