diff --git a/addon-resizer/README.md b/addon-resizer/README.md index 3af69588f04fe2d6241ae0f932503d64d9d6ae8b..d2c869d219f6990cf669b1fe360d81127b13dcf9 100644 --- a/addon-resizer/README.md +++ b/addon-resizer/README.md @@ -15,9 +15,13 @@ The cluster size is periodically checked, and used to calculate the expected res Usage of pod_nanny: --config-dir="": The name of directory used to specify resources for scaled container. --container="pod-nanny": The name of the container to watch. This defaults to the nanny itself. + --cpu="MISSING": The base CPU resource requirement. --deployment="": The name of the deployment being monitored. This is required. + --extra-cpu="0": The amount of CPU to add per node. + --extra-memory="0Mi": The amount of memory to add per node. --extra-storage="0Gi": The amount of storage to add per node. --log-flush-frequency=5s: Maximum number of seconds between log flushes + --memory="MISSING": The base memory resource requirement. --namespace=$MY_POD_NAMESPACE: The namespace of the ward. This defaults to the nanny's own pod. --pod=$MY_POD_NAME: The name of the pod to watch. This defaults to the nanny's own pod. --poll-period=10000: The time, in milliseconds, to poll the dependent container. @@ -39,10 +43,6 @@ data: NannyConfiguration: |- apiVersion: nannyconfig/v1alpha1 kind: NannyConfiguration - baseCPU: "80m" - cpuPerNode: "0.5" - baseMemory: "140Mi" - memoryPerNode: "4" --- apiVersion: extensions/v1beta1 kind: Deployment @@ -91,6 +91,10 @@ spec: command: - /pod_nanny - --config-dir=/etc/config + - --cpu=300m + - --extra-cpu=20m + - --memory=200Mi + - --extra-memory=10Mi - --threshold=5 - --deployment=nanny-v1 volumes: diff --git a/addon-resizer/nanny/apis/nannyconfig/v1alpha1/defaults.go b/addon-resizer/nanny/apis/nannyconfig/v1alpha1/defaults.go index 4941c5ccdcd0d49ec5c8c66f16af96fdff55e328..6262d3627d0b2162541239f1dff26e0b897b85e9 100644 --- a/addon-resizer/nanny/apis/nannyconfig/v1alpha1/defaults.go +++ b/addon-resizer/nanny/apis/nannyconfig/v1alpha1/defaults.go @@ -39,3 +39,18 @@ func SetDefaults_NannyConfiguration(obj *NannyConfiguration) { obj.MemoryPerNode = "0" } } + +func FillInDefaults_NannyConfiguration(obj *NannyConfiguration, defaults *NannyConfiguration) { + if obj.BaseCPU == nannyconfig.NoValue { + obj.BaseCPU = defaults.BaseCPU + } + if obj.CPUPerNode == "0" { + obj.CPUPerNode = defaults.CPUPerNode + } + if obj.BaseMemory == nannyconfig.NoValue { + obj.BaseMemory = defaults.BaseMemory + } + if obj.MemoryPerNode == "0" { + obj.MemoryPerNode = defaults.MemoryPerNode + } +} diff --git a/addon-resizer/nanny/main/pod_nanny.go b/addon-resizer/nanny/main/pod_nanny.go index c4c16059a52f2c1b591b66a0aa922f110133b7f7..943f2c376e064e7f67985d562d7d117b0cd1aea8 100644 --- a/addon-resizer/nanny/main/pod_nanny.go +++ b/addon-resizer/nanny/main/pod_nanny.go @@ -40,7 +40,12 @@ import ( var ( // Flags to define the resource requirements. - configDir = flag.String("config-dir", nannyconfig.NoValue, "Path of configuration containing base resource requirements.") + configDir = flag.String("config-dir", nannyconfig.NoValue, "Path of configuration containing base resource requirements.") + // Following empty values ("") will be overwritten by defaults specified in apis/nannyconfig/v1alpha1/defaults.go + baseCPU = flag.String("cpu", "", "The base CPU resource requirement.") + cpuPerNode = flag.String("extra-cpu", "", "The amount of CPU to add per node.") + baseMemory = flag.String("memory", "", "The base memory resource requirement.") + memoryPerNode = flag.String("extra-memory", "", "The amount of memory to add per node.") baseStorage = flag.String("storage", nannyconfig.NoValue, "The base storage resource requirement.") storagePerNode = flag.String("extra-storage", "0Gi", "The amount of storage to add per node.") threshold = flag.Int("threshold", 0, "A number between 0-100. The dependent's resources are rewritten when they deviate from expected by more than threshold.") @@ -83,7 +88,13 @@ func main() { } k8s := nanny.NewKubernetesClient(*podNamespace, *deployment, *podName, *containerName, clientset) - nannycfg, err := loadNannyConfiguration(*configDir) + nannyConfigurationFromFlags := &nannyconfigalpha.NannyConfiguration{ + BaseCPU: *baseCPU, + CPUPerNode: *cpuPerNode, + BaseMemory: *baseMemory, + MemoryPerNode: *memoryPerNode, + } + nannycfg, err := loadNannyConfiguration(*configDir, nannyConfigurationFromFlags) if err != nil { glog.Fatal(err) } @@ -136,21 +147,26 @@ func main() { nanny.PollAPIServer(k8s, est, *containerName, pollPeriod, uint64(*threshold)) } -func loadNannyConfiguration(configDir string) (*nannyconfig.NannyConfiguration, error) { +func loadNannyConfiguration(configDir string, defaultConfig *nannyconfigalpha.NannyConfiguration) (*nannyconfig.NannyConfiguration, error) { path := filepath.Join(configDir, "NannyConfiguration") scheme, codecs, err := nannyscheme.NewSchemeAndCodecs() if err != nil { return nil, err } + // overwrite defaults with flag-specified parameters + nannyconfigalpha.SetDefaults_NannyConfiguration(defaultConfig) + // retrieve config map parameters if present + configMapConfig := &nannyconfigalpha.NannyConfiguration{} data, err := ioutil.ReadFile(path) if err != nil { glog.V(0).Infof("Failed to read data from config file %q: %v, using default parameters", path, err) - config := &nannyconfigalpha.NannyConfiguration{} - nannyconfigalpha.SetDefaults_NannyConfiguration(config) - return convertNannyConfiguration(config, scheme) + } else if configMapConfig, err = decodeNannyConfiguration(data, scheme, codecs); err != nil { + glog.V(0).Infof("Unable to decode Nanny Configuration from config map, using default parameters") } - - return decodeNannyConfiguration(data, scheme, codecs) + glog.Infof("%s", configMapConfig.BaseCPU) + // overwrite defaults with config map parameters + nannyconfigalpha.FillInDefaults_NannyConfiguration(configMapConfig, defaultConfig) + return convertNannyConfiguration(configMapConfig, scheme) } func convertNannyConfiguration(configAlpha *nannyconfigalpha.NannyConfiguration, scheme *runtime.Scheme) (*nannyconfig.NannyConfiguration, error) { @@ -162,7 +178,7 @@ func convertNannyConfiguration(configAlpha *nannyconfigalpha.NannyConfiguration, return config, nil } -func decodeNannyConfiguration(data []byte, scheme *runtime.Scheme, codecs *serializer.CodecFactory) (*nannyconfig.NannyConfiguration, error) { +func decodeNannyConfiguration(data []byte, scheme *runtime.Scheme, codecs *serializer.CodecFactory) (*nannyconfigalpha.NannyConfiguration, error) { obj, err := runtime.Decode(codecs.UniversalDecoder(nannyconfigalpha.SchemeGroupVersion), data) if err != nil { return nil, fmt.Errorf("failed to decode, error: %v", err) @@ -171,5 +187,5 @@ func decodeNannyConfiguration(data []byte, scheme *runtime.Scheme, codecs *seria if !ok { return nil, fmt.Errorf("failed to cast object to NannyConfiguration, object: %#v", obj) } - return convertNannyConfiguration(externalHC, scheme) + return externalHC, nil }