Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Respect memory being set in the minikube config #11014

Merged
merged 2 commits into from
Apr 7, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
274 changes: 142 additions & 132 deletions cmd/minikube/cmd/start_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,139 +251,8 @@ func generateClusterConfig(cmd *cobra.Command, existing *config.ClusterConfig, k
cc = updateExistingConfigFromFlags(cmd, existing)
} else {
klog.Info("no existing cluster config was found, will generate one from the flags ")
sysLimit, containerLimit, err := memoryLimits(drvName)
if err != nil {
klog.Warningf("Unable to query memory limits: %+v", err)
}

mem := suggestMemoryAllocation(sysLimit, containerLimit, viper.GetInt(nodes))
if cmd.Flags().Changed(memory) {
var err error
mem, err = pkgutil.CalculateSizeInMB(viper.GetString(memory))
if err != nil {
exit.Message(reason.Usage, "Generate unable to parse memory '{{.memory}}': {{.error}}", out.V{"memory": viper.GetString(memory), "error": err})
}
if driver.IsKIC(drvName) && mem > containerLimit {
exit.Message(reason.Usage, "{{.driver_name}} has only {{.container_limit}}MB memory but you specified {{.specified_memory}}MB", out.V{"container_limit": containerLimit, "specified_memory": mem, "driver_name": driver.FullName(drvName)})
}
} else {
validateRequestedMemorySize(mem, drvName)
klog.Infof("Using suggested %dMB memory alloc based on sys=%dMB, container=%dMB", mem, sysLimit, containerLimit)
}

diskSize, err := pkgutil.CalculateSizeInMB(viper.GetString(humanReadableDiskSize))
if err != nil {
exit.Message(reason.Usage, "Generate unable to parse disk size '{{.diskSize}}': {{.error}}", out.V{"diskSize": viper.GetString(humanReadableDiskSize), "error": err})
}

repository := viper.GetString(imageRepository)
mirrorCountry := strings.ToLower(viper.GetString(imageMirrorCountry))
if strings.ToLower(repository) == "auto" || (mirrorCountry != "" && repository == "") {
found, autoSelectedRepository, err := selectImageRepository(mirrorCountry, semver.MustParse(strings.TrimPrefix(k8sVersion, version.VersionPrefix)))
if err != nil {
exit.Error(reason.InetRepo, "Failed to check main repository and mirrors for images", err)
}

if !found {
if autoSelectedRepository == "" {
exit.Message(reason.InetReposUnavailable, "None of the known repositories are accessible. Consider specifying an alternative image repository with --image-repository flag")
} else {
out.WarningT("None of the known repositories in your location are accessible. Using {{.image_repository_name}} as fallback.", out.V{"image_repository_name": autoSelectedRepository})
}
}
cc = generateNewConfigFromFlags(cmd, k8sVersion, drvName)

repository = autoSelectedRepository
}

if cmd.Flags().Changed(imageRepository) || cmd.Flags().Changed(imageMirrorCountry) {
out.Styled(style.Success, "Using image repository {{.name}}", out.V{"name": repository})
}

// Backwards compatibility with --enable-default-cni
chosenCNI := viper.GetString(cniFlag)
if viper.GetBool(enableDefaultCNI) && !cmd.Flags().Changed(cniFlag) {
klog.Errorf("Found deprecated --enable-default-cni flag, setting --cni=bridge")
chosenCNI = "bridge"
}
// networkPlugin cni deprecation warning
chosenNetworkPlugin := viper.GetString(networkPlugin)
if chosenNetworkPlugin == "cni" {
out.WarningT("With --network-plugin=cni, you will need to provide your own CNI. See --cni flag as a user-friendly alternative")
}

if !(driver.IsKIC(drvName) || driver.IsKVM(drvName)) && viper.GetString(network) != "" {
out.WarningT("--network flag is only valid with the docker/podman and KVM drivers, it will be ignored")
}

checkNumaCount(k8sVersion)

cc = config.ClusterConfig{
Name: ClusterFlagValue(),
KeepContext: viper.GetBool(keepContext),
EmbedCerts: viper.GetBool(embedCerts),
MinikubeISO: viper.GetString(isoURL),
KicBaseImage: viper.GetString(kicBaseImage),
Network: viper.GetString(network),
Memory: mem,
CPUs: viper.GetInt(cpus),
DiskSize: diskSize,
Driver: drvName,
ListenAddress: viper.GetString(listenAddress),
HyperkitVpnKitSock: viper.GetString(vpnkitSock),
HyperkitVSockPorts: viper.GetStringSlice(vsockPorts),
NFSShare: viper.GetStringSlice(nfsShare),
NFSSharesRoot: viper.GetString(nfsSharesRoot),
DockerEnv: config.DockerEnv,
DockerOpt: config.DockerOpt,
InsecureRegistry: insecureRegistry,
RegistryMirror: registryMirror,
HostOnlyCIDR: viper.GetString(hostOnlyCIDR),
HypervVirtualSwitch: viper.GetString(hypervVirtualSwitch),
HypervUseExternalSwitch: viper.GetBool(hypervUseExternalSwitch),
HypervExternalAdapter: viper.GetString(hypervExternalAdapter),
KVMNetwork: viper.GetString(kvmNetwork),
KVMQemuURI: viper.GetString(kvmQemuURI),
KVMGPU: viper.GetBool(kvmGPU),
KVMHidden: viper.GetBool(kvmHidden),
KVMNUMACount: viper.GetInt(kvmNUMACount),
DisableDriverMounts: viper.GetBool(disableDriverMounts),
UUID: viper.GetString(uuid),
NoVTXCheck: viper.GetBool(noVTXCheck),
DNSProxy: viper.GetBool(dnsProxy),
HostDNSResolver: viper.GetBool(hostDNSResolver),
HostOnlyNicType: viper.GetString(hostOnlyNicType),
NatNicType: viper.GetString(natNicType),
StartHostTimeout: viper.GetDuration(waitTimeout),
ExposedPorts: viper.GetStringSlice(ports),
SSHIPAddress: viper.GetString(sshIPAddress),
SSHUser: viper.GetString(sshSSHUser),
SSHKey: viper.GetString(sshSSHKey),
SSHPort: viper.GetInt(sshSSHPort),
KubernetesConfig: config.KubernetesConfig{
KubernetesVersion: k8sVersion,
ClusterName: ClusterFlagValue(),
Namespace: viper.GetString(startNamespace),
APIServerName: viper.GetString(apiServerName),
APIServerNames: apiServerNames,
APIServerIPs: apiServerIPs,
DNSDomain: viper.GetString(dnsDomain),
FeatureGates: viper.GetString(featureGates),
ContainerRuntime: viper.GetString(containerRuntime),
CRISocket: viper.GetString(criSocket),
NetworkPlugin: chosenNetworkPlugin,
ServiceCIDR: viper.GetString(serviceCIDR),
ImageRepository: repository,
ExtraOptions: config.ExtraOptions,
ShouldLoadCachedImages: viper.GetBool(cacheImages),
CNI: chosenCNI,
NodePort: viper.GetInt(apiServerPort),
},
MultiNodeRequested: viper.GetInt(nodes) > 1,
}
cc.VerifyComponents = interpretWaitFlag(*cmd)
if viper.GetBool(createMount) && driver.IsKIC(drvName) {
cc.ContainerVolumeMounts = []string{viper.GetString(mountString)}
}
cnm, err := cni.New(cc)
if err != nil {
return cc, config.Node{}, errors.Wrap(err, "cni")
Expand Down Expand Up @@ -418,6 +287,147 @@ func generateClusterConfig(cmd *cobra.Command, existing *config.ClusterConfig, k
return createNode(cc, kubeNodeName, existing)
}

// generateNewConfigFromFlags generate a config.ClusterConfig based on flags
func generateNewConfigFromFlags(cmd *cobra.Command, k8sVersion string, drvName string) config.ClusterConfig {
var cc config.ClusterConfig

sysLimit, containerLimit, err := memoryLimits(drvName)
if err != nil {
klog.Warningf("Unable to query memory limits: %+v", err)
}

mem := suggestMemoryAllocation(sysLimit, containerLimit, viper.GetInt(nodes))
if cmd.Flags().Changed(memory) || viper.IsSet(memory) {
var err error
mem, err = pkgutil.CalculateSizeInMB(viper.GetString(memory))
if err != nil {
exit.Message(reason.Usage, "Generate unable to parse memory '{{.memory}}': {{.error}}", out.V{"memory": viper.GetString(memory), "error": err})
}
if driver.IsKIC(drvName) && mem > containerLimit {
exit.Message(reason.Usage, "{{.driver_name}} has only {{.container_limit}}MB memory but you specified {{.specified_memory}}MB", out.V{"container_limit": containerLimit, "specified_memory": mem, "driver_name": driver.FullName(drvName)})
}
} else {
validateRequestedMemorySize(mem, drvName)
klog.Infof("Using suggested %dMB memory alloc based on sys=%dMB, container=%dMB", mem, sysLimit, containerLimit)
}

diskSize, err := pkgutil.CalculateSizeInMB(viper.GetString(humanReadableDiskSize))
if err != nil {
exit.Message(reason.Usage, "Generate unable to parse disk size '{{.diskSize}}': {{.error}}", out.V{"diskSize": viper.GetString(humanReadableDiskSize), "error": err})
}

repository := viper.GetString(imageRepository)
mirrorCountry := strings.ToLower(viper.GetString(imageMirrorCountry))
if strings.ToLower(repository) == "auto" || (mirrorCountry != "" && repository == "") {
found, autoSelectedRepository, err := selectImageRepository(mirrorCountry, semver.MustParse(strings.TrimPrefix(k8sVersion, version.VersionPrefix)))
if err != nil {
exit.Error(reason.InetRepo, "Failed to check main repository and mirrors for images", err)
}

if !found {
if autoSelectedRepository == "" {
exit.Message(reason.InetReposUnavailable, "None of the known repositories are accessible. Consider specifying an alternative image repository with --image-repository flag")
} else {
out.WarningT("None of the known repositories in your location are accessible. Using {{.image_repository_name}} as fallback.", out.V{"image_repository_name": autoSelectedRepository})
}
}

repository = autoSelectedRepository
}

if cmd.Flags().Changed(imageRepository) || cmd.Flags().Changed(imageMirrorCountry) {
out.Styled(style.Success, "Using image repository {{.name}}", out.V{"name": repository})
}

// Backwards compatibility with --enable-default-cni
chosenCNI := viper.GetString(cniFlag)
if viper.GetBool(enableDefaultCNI) && !cmd.Flags().Changed(cniFlag) {
klog.Errorf("Found deprecated --enable-default-cni flag, setting --cni=bridge")
chosenCNI = "bridge"
}
// networkPlugin cni deprecation warning
chosenNetworkPlugin := viper.GetString(networkPlugin)
if chosenNetworkPlugin == "cni" {
out.WarningT("With --network-plugin=cni, you will need to provide your own CNI. See --cni flag as a user-friendly alternative")
}

if !(driver.IsKIC(drvName) || driver.IsKVM(drvName)) && viper.GetString(network) != "" {
out.WarningT("--network flag is only valid with the docker/podman and KVM drivers, it will be ignored")
}

checkNumaCount(k8sVersion)

cc = config.ClusterConfig{
Name: ClusterFlagValue(),
KeepContext: viper.GetBool(keepContext),
EmbedCerts: viper.GetBool(embedCerts),
MinikubeISO: viper.GetString(isoURL),
KicBaseImage: viper.GetString(kicBaseImage),
Network: viper.GetString(network),
Memory: mem,
CPUs: viper.GetInt(cpus),
DiskSize: diskSize,
Driver: drvName,
ListenAddress: viper.GetString(listenAddress),
HyperkitVpnKitSock: viper.GetString(vpnkitSock),
HyperkitVSockPorts: viper.GetStringSlice(vsockPorts),
NFSShare: viper.GetStringSlice(nfsShare),
NFSSharesRoot: viper.GetString(nfsSharesRoot),
DockerEnv: config.DockerEnv,
DockerOpt: config.DockerOpt,
InsecureRegistry: insecureRegistry,
RegistryMirror: registryMirror,
HostOnlyCIDR: viper.GetString(hostOnlyCIDR),
HypervVirtualSwitch: viper.GetString(hypervVirtualSwitch),
HypervUseExternalSwitch: viper.GetBool(hypervUseExternalSwitch),
HypervExternalAdapter: viper.GetString(hypervExternalAdapter),
KVMNetwork: viper.GetString(kvmNetwork),
KVMQemuURI: viper.GetString(kvmQemuURI),
KVMGPU: viper.GetBool(kvmGPU),
KVMHidden: viper.GetBool(kvmHidden),
KVMNUMACount: viper.GetInt(kvmNUMACount),
DisableDriverMounts: viper.GetBool(disableDriverMounts),
UUID: viper.GetString(uuid),
NoVTXCheck: viper.GetBool(noVTXCheck),
DNSProxy: viper.GetBool(dnsProxy),
HostDNSResolver: viper.GetBool(hostDNSResolver),
HostOnlyNicType: viper.GetString(hostOnlyNicType),
NatNicType: viper.GetString(natNicType),
StartHostTimeout: viper.GetDuration(waitTimeout),
ExposedPorts: viper.GetStringSlice(ports),
SSHIPAddress: viper.GetString(sshIPAddress),
SSHUser: viper.GetString(sshSSHUser),
SSHKey: viper.GetString(sshSSHKey),
SSHPort: viper.GetInt(sshSSHPort),
KubernetesConfig: config.KubernetesConfig{
KubernetesVersion: k8sVersion,
ClusterName: ClusterFlagValue(),
Namespace: viper.GetString(startNamespace),
APIServerName: viper.GetString(apiServerName),
APIServerNames: apiServerNames,
APIServerIPs: apiServerIPs,
DNSDomain: viper.GetString(dnsDomain),
FeatureGates: viper.GetString(featureGates),
ContainerRuntime: viper.GetString(containerRuntime),
CRISocket: viper.GetString(criSocket),
NetworkPlugin: chosenNetworkPlugin,
ServiceCIDR: viper.GetString(serviceCIDR),
ImageRepository: repository,
ExtraOptions: config.ExtraOptions,
ShouldLoadCachedImages: viper.GetBool(cacheImages),
CNI: chosenCNI,
NodePort: viper.GetInt(apiServerPort),
},
MultiNodeRequested: viper.GetInt(nodes) > 1,
}
cc.VerifyComponents = interpretWaitFlag(*cmd)
if viper.GetBool(createMount) && driver.IsKIC(drvName) {
cc.ContainerVolumeMounts = []string{viper.GetString(mountString)}
}

return cc
}

// setCNIConfDir sets kubelet's '--cni-conf-dir' flag to custom CNI Config Directory path (same used also by CNI Deployment) to avoid conflicting CNI configs.
// ref: https://github.com/kubernetes/minikube/issues/10984
// Note: currently, this change affects only Kindnet CNI (and all multinodes using it), but it can be easily expanded to other/all CNIs if needed.
Expand Down