Automatically scale the default memory allocation
parent
8c046fd091
commit
c2c1807c93
|
@ -38,9 +38,11 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
"github.com/shirou/gopsutil/cpu"
|
||||
gopshost "github.com/shirou/gopsutil/host"
|
||||
"github.com/shirou/gopsutil/mem"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
cmdcfg "k8s.io/minikube/cmd/minikube/cmd/config"
|
||||
"k8s.io/minikube/pkg/drivers/kic/oci"
|
||||
"k8s.io/minikube/pkg/minikube/bootstrapper/bsutil"
|
||||
"k8s.io/minikube/pkg/minikube/bootstrapper/images"
|
||||
"k8s.io/minikube/pkg/minikube/cluster"
|
||||
|
@ -83,7 +85,6 @@ const (
|
|||
kvmGPU = "kvm-gpu"
|
||||
kvmHidden = "kvm-hidden"
|
||||
minikubeEnvPrefix = "MINIKUBE"
|
||||
defaultMemorySize = "2000mb"
|
||||
installAddons = "install-addons"
|
||||
defaultDiskSize = "20000mb"
|
||||
keepContext = "keep-context"
|
||||
|
@ -112,7 +113,8 @@ const (
|
|||
interactive = "interactive"
|
||||
waitTimeout = "wait-timeout"
|
||||
nativeSSH = "native-ssh"
|
||||
minimumMemorySize = "1024mb"
|
||||
minUsableMem = 1024 // Kubernetes will not start with less than 1GB
|
||||
minRecommendedMem = 2000 // Warn at no lower than existing configurations
|
||||
minimumCPUS = 2
|
||||
minimumDiskSize = "2000mb"
|
||||
autoUpdate = "auto-update-drivers"
|
||||
|
@ -149,8 +151,8 @@ func initMinikubeFlags() {
|
|||
startCmd.Flags().Bool(interactive, true, "Allow user prompts for more information")
|
||||
startCmd.Flags().Bool(dryRun, false, "dry-run mode. Validates configuration, but does not mutate system state")
|
||||
|
||||
startCmd.Flags().Int(cpus, 2, "Number of CPUs allocated to the minikube VM.")
|
||||
startCmd.Flags().String(memory, defaultMemorySize, "Amount of RAM allocated to the minikube VM (format: <number>[<unit>], where unit = b, k, m or g).")
|
||||
startCmd.Flags().Int(cpus, 2, "Number of CPUs allocated to Kubernetes.")
|
||||
startCmd.Flags().String(memory, "", "Amount of RAM to allocate to Kubernetes (format: <number>[<unit>], where unit = b, k, m or g).")
|
||||
startCmd.Flags().String(humanReadableDiskSize, defaultDiskSize, "Disk size allocated to the minikube VM (format: <number>[<unit>], where unit = b, k, m or g).")
|
||||
startCmd.Flags().Bool(downloadOnly, false, "If true, only download and cache files for later use - don't install or start anything.")
|
||||
startCmd.Flags().Bool(cacheImages, true, "If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --driver=none.")
|
||||
|
@ -638,23 +640,50 @@ func validateUser(drvName string) {
|
|||
}
|
||||
}
|
||||
|
||||
// validateDiskSize validates the disk size matches the minimum recommended
|
||||
func validateDiskSize() {
|
||||
diskSizeMB := pkgutil.CalculateSizeInMB(viper.GetString(humanReadableDiskSize))
|
||||
if diskSizeMB < pkgutil.CalculateSizeInMB(minimumDiskSize) && !viper.GetBool(force) {
|
||||
exit.WithCodeT(exit.Config, "Requested disk size {{.requested_size}} is less than minimum of {{.minimum_size}}", out.V{"requested_size": diskSizeMB, "minimum_size": pkgutil.CalculateSizeInMB(minimumDiskSize)})
|
||||
// defaultMemorySize calculates the default memory footprint in MB
|
||||
func defaultMemorySize(drvName string) int {
|
||||
fallback := 2200
|
||||
maximum := 6000
|
||||
|
||||
v, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
return fallback
|
||||
}
|
||||
available := v.Total / 1024 / 1024
|
||||
|
||||
// For KIC, do not allocate more memory than the container has available (+ some slack)
|
||||
if driver.IsKIC(drvName) {
|
||||
s, err := oci.DaemonInfo(drvName)
|
||||
if err != nil {
|
||||
return fallback
|
||||
}
|
||||
maximum = int(s.TotalMemory/1024/1024) - 128
|
||||
}
|
||||
|
||||
suggested := int(available / 4)
|
||||
|
||||
if suggested > maximum {
|
||||
suggested = maximum
|
||||
}
|
||||
|
||||
if suggested < fallback {
|
||||
suggested = fallback
|
||||
}
|
||||
|
||||
glog.Infof("Selecting memory default of %dMB, given %dMB available and %dMB maximum", suggested, available, maximum)
|
||||
return suggested
|
||||
}
|
||||
|
||||
// validateMemorySize validates the memory size matches the minimum recommended
|
||||
func validateMemorySize() {
|
||||
memorySizeMB := pkgutil.CalculateSizeInMB(viper.GetString(memory))
|
||||
if memorySizeMB < pkgutil.CalculateSizeInMB(minimumMemorySize) && !viper.GetBool(force) {
|
||||
exit.WithCodeT(exit.Config, "Requested memory allocation {{.requested_size}} is less than the minimum allowed of {{.minimum_size}}", out.V{"requested_size": memorySizeMB, "minimum_size": pkgutil.CalculateSizeInMB(minimumMemorySize)})
|
||||
req := pkgutil.CalculateSizeInMB(viper.GetString(memory))
|
||||
if req < minUsableMem && !viper.GetBool(force) {
|
||||
exit.WithCodeT(exit.Config, "Requested memory allocation {{.requested}}MB is less than the usable minimum of {{.minimum}}MB",
|
||||
out.V{"requested": req, "mininum": minUsableMem})
|
||||
}
|
||||
if memorySizeMB < pkgutil.CalculateSizeInMB(defaultMemorySize) && !viper.GetBool(force) {
|
||||
out.T(out.Notice, "Requested memory allocation ({{.memory}}MB) is less than the default memory allocation of {{.default_memorysize}}MB. Beware that minikube might not work correctly or crash unexpectedly.",
|
||||
out.V{"memory": memorySizeMB, "default_memorysize": pkgutil.CalculateSizeInMB(defaultMemorySize)})
|
||||
if req < minRecommendedMem && !viper.GetBool(force) {
|
||||
out.T(out.Notice, "Requested memory allocation ({{.requested}}MB) is less than the recommended minimum {{.recommended}}MB. Kubernetes may crash unexpectedly.",
|
||||
out.V{"requested": req, "recommended": minRecommendedMem})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -679,14 +708,23 @@ func validateCPUCount(local bool) {
|
|||
|
||||
// validateFlags validates the supplied flags against known bad combinations
|
||||
func validateFlags(cmd *cobra.Command, drvName string) {
|
||||
validateDiskSize()
|
||||
validateMemorySize()
|
||||
if cmd.Flags().Changed(humanReadableDiskSize) {
|
||||
diskSizeMB := pkgutil.CalculateSizeInMB(viper.GetString(humanReadableDiskSize))
|
||||
if diskSizeMB < pkgutil.CalculateSizeInMB(minimumDiskSize) && !viper.GetBool(force) {
|
||||
exit.WithCodeT(exit.Config, "Requested disk size {{.requested_size}} is less than minimum of {{.minimum_size}}", out.V{"requested_size": diskSizeMB, "minimum_size": pkgutil.CalculateSizeInMB(minimumDiskSize)})
|
||||
}
|
||||
}
|
||||
|
||||
if !driver.HasResourceLimits(drvName) {
|
||||
if cmd.Flags().Changed(cpus) {
|
||||
if cmd.Flags().Changed(cpus) {
|
||||
validateCPUCount(driver.BareMetal(drvName))
|
||||
if !driver.HasResourceLimits(drvName) {
|
||||
out.WarningT("The '{{.name}}' driver does not respect the --cpus flag", out.V{"name": drvName})
|
||||
}
|
||||
if cmd.Flags().Changed(memory) {
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed(memory) {
|
||||
validateMemorySize()
|
||||
if !driver.HasResourceLimits(drvName) {
|
||||
out.WarningT("The '{{.name}}' driver does not respect the --memory flag", out.V{"name": drvName})
|
||||
}
|
||||
}
|
||||
|
@ -702,8 +740,6 @@ func validateFlags(cmd *cobra.Command, drvName string) {
|
|||
}
|
||||
}
|
||||
|
||||
validateCPUCount(driver.BareMetal(drvName))
|
||||
|
||||
// check that kubeadm extra args contain only whitelisted parameters
|
||||
for param := range node.ExtraOptions.AsMap().Get(bsutil.Kubeadm) {
|
||||
if !config.ContainsParam(bsutil.KubeadmExtraArgsWhitelist[bsutil.KubeadmCmdParam], param) &&
|
||||
|
@ -783,6 +819,11 @@ func generateCfgFromFlags(cmd *cobra.Command, k8sVersion string, drvName string)
|
|||
kubeNodeName = "m01"
|
||||
}
|
||||
|
||||
mem := defaultMemorySize(drvName)
|
||||
if viper.GetString(memory) != "" {
|
||||
mem = pkgutil.CalculateSizeInMB(viper.GetString(memory))
|
||||
}
|
||||
|
||||
// Create the initial node, which will necessarily be a control plane
|
||||
cp := config.Node{
|
||||
Port: viper.GetInt(apiServerPort),
|
||||
|
@ -797,7 +838,7 @@ func generateCfgFromFlags(cmd *cobra.Command, k8sVersion string, drvName string)
|
|||
KeepContext: viper.GetBool(keepContext),
|
||||
EmbedCerts: viper.GetBool(embedCerts),
|
||||
MinikubeISO: viper.GetString(isoURL),
|
||||
Memory: pkgutil.CalculateSizeInMB(viper.GetString(memory)),
|
||||
Memory: mem,
|
||||
CPUs: viper.GetInt(cpus),
|
||||
DiskSize: pkgutil.CalculateSizeInMB(viper.GetString(humanReadableDiskSize)),
|
||||
Driver: drvName,
|
||||
|
|
Loading…
Reference in New Issue