mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			146 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
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()
 | 
						|
	localFeatureGate.SetFromMap(kc.FeatureGates)
 | 
						|
 | 
						|
	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)
 | 
						|
}
 |