123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- /*
- Copyright 2017 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package validation
- import (
- "fmt"
- "time"
- utilerrors "k8s.io/apimachinery/pkg/util/errors"
- utilvalidation "k8s.io/apimachinery/pkg/util/validation"
- utilfeature "k8s.io/apiserver/pkg/util/feature"
- "k8s.io/kubernetes/pkg/features"
- kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
- kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
- )
- // ValidateKubeletConfiguration validates `kc` and returns an error if it is invalid
- func ValidateKubeletConfiguration(kc *kubeletconfig.KubeletConfiguration) error {
- allErrors := []error{}
- // Make a local copy of the global feature gates and combine it with the gates set by this configuration.
- // This allows us to validate the config against the set of gates it will actually run against.
- localFeatureGate := utilfeature.DefaultFeatureGate.DeepCopy()
- if err := localFeatureGate.SetFromMap(kc.FeatureGates); err != nil {
- return err
- }
- if kc.NodeLeaseDurationSeconds <= 0 {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: NodeLeaseDurationSeconds must be greater than 0"))
- }
- if !kc.CgroupsPerQOS && len(kc.EnforceNodeAllocatable) > 0 {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: EnforceNodeAllocatable (--enforce-node-allocatable) is not supported unless CgroupsPerQOS (--cgroups-per-qos) feature is turned on"))
- }
- if kc.SystemCgroups != "" && kc.CgroupRoot == "" {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: SystemCgroups (--system-cgroups) was specified and CgroupRoot (--cgroup-root) was not specified"))
- }
- if kc.EventBurst < 0 {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: EventBurst (--event-burst) %v must not be a negative number", kc.EventBurst))
- }
- if kc.EventRecordQPS < 0 {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: EventRecordQPS (--event-qps) %v must not be a negative number", kc.EventRecordQPS))
- }
- if kc.HealthzPort != 0 && utilvalidation.IsValidPortNum(int(kc.HealthzPort)) != nil {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: HealthzPort (--healthz-port) %v must be between 1 and 65535, inclusive", kc.HealthzPort))
- }
- if localFeatureGate.Enabled(features.CPUCFSQuotaPeriod) && utilvalidation.IsInRange(int(kc.CPUCFSQuotaPeriod.Duration), int(1*time.Microsecond), int(time.Second)) != nil {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: CPUCFSQuotaPeriod (--cpu-cfs-quota-period) %v must be between 1usec and 1sec, inclusive", kc.CPUCFSQuotaPeriod))
- }
- if utilvalidation.IsInRange(int(kc.ImageGCHighThresholdPercent), 0, 100) != nil {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: ImageGCHighThresholdPercent (--image-gc-high-threshold) %v must be between 0 and 100, inclusive", kc.ImageGCHighThresholdPercent))
- }
- if utilvalidation.IsInRange(int(kc.ImageGCLowThresholdPercent), 0, 100) != nil {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: ImageGCLowThresholdPercent (--image-gc-low-threshold) %v must be between 0 and 100, inclusive", kc.ImageGCLowThresholdPercent))
- }
- if kc.ImageGCLowThresholdPercent >= kc.ImageGCHighThresholdPercent {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: ImageGCLowThresholdPercent (--image-gc-low-threshold) %v must be less than ImageGCHighThresholdPercent (--image-gc-high-threshold) %v", kc.ImageGCLowThresholdPercent, kc.ImageGCHighThresholdPercent))
- }
- if utilvalidation.IsInRange(int(kc.IPTablesDropBit), 0, 31) != nil {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: IPTablesDropBit (--iptables-drop-bit) %v must be between 0 and 31, inclusive", kc.IPTablesDropBit))
- }
- if utilvalidation.IsInRange(int(kc.IPTablesMasqueradeBit), 0, 31) != nil {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: IPTablesMasqueradeBit (--iptables-masquerade-bit) %v must be between 0 and 31, inclusive", kc.IPTablesMasqueradeBit))
- }
- if kc.KubeAPIBurst < 0 {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: KubeAPIBurst (--kube-api-burst) %v must not be a negative number", kc.KubeAPIBurst))
- }
- if kc.KubeAPIQPS < 0 {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: KubeAPIQPS (--kube-api-qps) %v must not be a negative number", kc.KubeAPIQPS))
- }
- if kc.MaxOpenFiles < 0 {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: MaxOpenFiles (--max-open-files) %v must not be a negative number", kc.MaxOpenFiles))
- }
- if kc.MaxPods < 0 {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: MaxPods (--max-pods) %v must not be a negative number", kc.MaxPods))
- }
- if utilvalidation.IsInRange(int(kc.OOMScoreAdj), -1000, 1000) != nil {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: OOMScoreAdj (--oom-score-adj) %v must be between -1000 and 1000, inclusive", kc.OOMScoreAdj))
- }
- if kc.PodsPerCore < 0 {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: PodsPerCore (--pods-per-core) %v must not be a negative number", kc.PodsPerCore))
- }
- if utilvalidation.IsValidPortNum(int(kc.Port)) != nil {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: Port (--port) %v must be between 1 and 65535, inclusive", kc.Port))
- }
- if kc.ReadOnlyPort != 0 && utilvalidation.IsValidPortNum(int(kc.ReadOnlyPort)) != nil {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: ReadOnlyPort (--read-only-port) %v must be between 0 and 65535, inclusive", kc.ReadOnlyPort))
- }
- if kc.RegistryBurst < 0 {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: RegistryBurst (--registry-burst) %v must not be a negative number", kc.RegistryBurst))
- }
- if kc.RegistryPullQPS < 0 {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: RegistryPullQPS (--registry-qps) %v must not be a negative number", kc.RegistryPullQPS))
- }
- if kc.RotateCertificates && !localFeatureGate.Enabled(features.RotateKubeletClientCertificate) {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: RotateCertificates %v requires feature gate RotateKubeletClientCertificate", kc.RotateCertificates))
- }
- if kc.ServerTLSBootstrap && !localFeatureGate.Enabled(features.RotateKubeletServerCertificate) {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: ServerTLSBootstrap %v requires feature gate RotateKubeletServerCertificate", kc.ServerTLSBootstrap))
- }
- for _, val := range kc.EnforceNodeAllocatable {
- switch val {
- case kubetypes.NodeAllocatableEnforcementKey:
- case kubetypes.SystemReservedEnforcementKey:
- if kc.SystemReservedCgroup == "" {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: systemReservedCgroup (--system-reserved-cgroup) must be specified when system-reserved contained in EnforceNodeAllocatable (--enforce-node-allocatable)"))
- }
- case kubetypes.KubeReservedEnforcementKey:
- if kc.KubeReservedCgroup == "" {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: kubeReservedCgroup (--kube-reserved-cgroup) must be specified when kube-reserved contained in EnforceNodeAllocatable (--enforce-node-allocatable)"))
- }
- case kubetypes.NodeAllocatableNoneKey:
- if len(kc.EnforceNodeAllocatable) > 1 {
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: EnforceNodeAllocatable (--enforce-node-allocatable) may not contain additional enforcements when '%s' is specified", kubetypes.NodeAllocatableNoneKey))
- }
- default:
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: option %q specified for EnforceNodeAllocatable (--enforce-node-allocatable). Valid options are %q, %q, %q, or %q",
- val, kubetypes.NodeAllocatableEnforcementKey, kubetypes.SystemReservedEnforcementKey, kubetypes.KubeReservedEnforcementKey, kubetypes.NodeAllocatableNoneKey))
- }
- }
- switch kc.HairpinMode {
- case kubeletconfig.HairpinNone:
- case kubeletconfig.HairpinVeth:
- case kubeletconfig.PromiscuousBridge:
- default:
- allErrors = append(allErrors, fmt.Errorf("invalid configuration: option %q specified for HairpinMode (--hairpin-mode). Valid options are %q, %q or %q",
- kc.HairpinMode, kubeletconfig.HairpinNone, kubeletconfig.HairpinVeth, kubeletconfig.PromiscuousBridge))
- }
- if err := validateKubeletOSConfiguration(kc); err != nil {
- allErrors = append(allErrors, err)
- }
- return utilerrors.NewAggregate(allErrors)
- }
|