diff --git a/cmd/kubelet/app/options/options.go b/cmd/kubelet/app/options/options.go index d5a33cbc76b..e4566dabc38 100644 --- a/cmd/kubelet/app/options/options.go +++ b/cmd/kubelet/app/options/options.go @@ -115,6 +115,7 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&s.ClusterDNS, "cluster-dns", s.ClusterDNS, "IP address for a cluster DNS server. This value is used for containers' DNS server in case of Pods with \"dnsPolicy=ClusterFirst\"") fs.DurationVar(&s.StreamingConnectionIdleTimeout.Duration, "streaming-connection-idle-timeout", s.StreamingConnectionIdleTimeout.Duration, "Maximum time a streaming connection can be idle before the connection is automatically closed. 0 indicates no timeout. Example: '5m'") fs.DurationVar(&s.NodeStatusUpdateFrequency.Duration, "node-status-update-frequency", s.NodeStatusUpdateFrequency.Duration, "Specifies how often kubelet posts node status to master. Note: be cautious when changing the constant, it must work with nodeMonitorGracePeriod in nodecontroller. Default: 10s") + s.NodeLabels = make(map[string]string) bindableNodeLabels := utilconfig.ConfigurationMap(s.NodeLabels) fs.Var(&bindableNodeLabels, "node-labels", " Labels to add when registering the node in the cluster. Labels must be key=value pairs separated by ','.") fs.DurationVar(&s.ImageMinimumGCAge.Duration, "minimum-image-ttl-duration", s.ImageMinimumGCAge.Duration, "Minimum age for a unused image before it is garbage collected. Examples: '300ms', '10s' or '2h45m'. Default: '2m'") diff --git a/pkg/api/conversion.go b/pkg/api/conversion.go index 304034b1cfb..399a4257a84 100644 --- a/pkg/api/conversion.go +++ b/pkg/api/conversion.go @@ -38,25 +38,71 @@ func init() { ) Scheme.AddConversionFuncs( Convert_unversioned_TypeMeta_To_unversioned_TypeMeta, + Convert_unversioned_ListMeta_To_unversioned_ListMeta, + Convert_intstr_IntOrString_To_intstr_IntOrString, + Convert_unversioned_Time_To_unversioned_Time, + Convert_Slice_string_To_unversioned_Time, + + Convert_resource_Quantity_To_resource_Quantity, + Convert_string_To_labels_Selector, + Convert_labels_Selector_To_string, + Convert_string_To_fields_Selector, + Convert_fields_Selector_To_string, + Convert_Pointer_bool_To_bool, Convert_bool_To_Pointer_bool, + Convert_Pointer_string_To_string, Convert_string_To_Pointer_string, - Convert_labels_Selector_To_string, - Convert_fields_Selector_To_string, - Convert_int64_ref_To_int, - Convert_int_To_int64_ref, - Convert_resource_Quantity_To_resource_Quantity, + + Convert_Pointer_int64_To_int, + Convert_int_To_Pointer_int64, + + Convert_Pointer_int32_To_int32, + Convert_int32_To_Pointer_int32, + + Convert_Pointer_float64_To_float64, + Convert_float64_To_Pointer_float64, ) } -func Convert_int64_ref_To_int(in **int64, out *int, s conversion.Scope) error { +func Convert_Pointer_float64_To_float64(in **float64, out *float64, s conversion.Scope) error { + if *in == nil { + *out = 0 + return nil + } + *out = float64(**in) + return nil +} + +func Convert_float64_To_Pointer_float64(in *float64, out **float64, s conversion.Scope) error { + temp := float64(*in) + *out = &temp + return nil +} + +func Convert_Pointer_int32_To_int32(in **int32, out *int32, s conversion.Scope) error { + if *in == nil { + *out = 0 + return nil + } + *out = int32(**in) + return nil +} + +func Convert_int32_To_Pointer_int32(in *int32, out **int32, s conversion.Scope) error { + temp := int32(*in) + *out = &temp + return nil +} + +func Convert_Pointer_int64_To_int(in **int64, out *int, s conversion.Scope) error { if *in == nil { *out = 0 return nil @@ -65,7 +111,7 @@ func Convert_int64_ref_To_int(in **int64, out *int, s conversion.Scope) error { return nil } -func Convert_int_To_int64_ref(in *int, out **int64, s conversion.Scope) error { +func Convert_int_To_Pointer_int64(in *int, out **int64, s conversion.Scope) error { temp := int64(*in) *out = &temp return nil diff --git a/pkg/apis/componentconfig/types.go b/pkg/apis/componentconfig/types.go index 9c85dfe9862..14e569fa2c9 100644 --- a/pkg/apis/componentconfig/types.go +++ b/pkg/apis/componentconfig/types.go @@ -159,7 +159,8 @@ type KubeletConfiguration struct { // Defaults to false. AllowPrivileged bool `json:"allowPrivileged"` // hostNetworkSources is a comma-separated list of sources from which the - // Kubelet allows pods to use of host network. Defaults to "*". + // Kubelet allows pods to use of host network. Defaults to "*". Valid + // options are "file", "http", "api", and "*" (all sources). HostNetworkSources []string `json:"hostNetworkSources"` // hostPIDSources is a comma-separated list of sources from which the // Kubelet allows pods to use the host pid namespace. Defaults to "*". diff --git a/pkg/apis/componentconfig/v1alpha1/defaults.go b/pkg/apis/componentconfig/v1alpha1/defaults.go index a9dfc820973..3fe815d1aad 100644 --- a/pkg/apis/componentconfig/v1alpha1/defaults.go +++ b/pkg/apis/componentconfig/v1alpha1/defaults.go @@ -17,6 +17,7 @@ limitations under the License. package v1alpha1 import ( + "path/filepath" "runtime" "time" @@ -28,19 +29,21 @@ import ( kruntime "k8s.io/kubernetes/pkg/runtime" ) -var zeroDuration = unversioned.Duration{} +const ( + defaultRootDir = "/var/lib/kubelet" -var defaultPodInfraConatinerImage = func() string { - const ( - defaultPodInfraContainerImageName = "gcr.io/google_containers/pause" - defaultPodInfraContainerImageVersion = "2.0" - ) - if runtime.GOARCH == "amd64" { - return defaultPodInfraContainerImageName + ":" + defaultPodInfraContainerImageVersion - } else { - return defaultPodInfraContainerImageName + "-" + runtime.GOARCH + ":" + defaultPodInfraContainerImageVersion - } -}() + // When these values are updated, also update test/e2e/framework/util.go + defaultPodInfraContainerImageName = "gcr.io/google_containers/pause" + defaultPodInfraContainerImageVersion = "3.0" + defaultPodInfraContainerImage = defaultPodInfraContainerImageName + + "-" + runtime.GOARCH + ":" + + defaultPodInfraContainerImageVersion + + // From pkg/kubelet/rkt/rkt.go to avoid circular import + defaultRktAPIServiceEndpoint = "localhost:15441" +) + +var zeroDuration = unversioned.Duration{} func addDefaultingFuncs(scheme *kruntime.Scheme) { scheme.AddDefaultingFuncs( @@ -141,7 +144,7 @@ func SetDefaults_KubeletConfiguration(obj *KubeletConfiguration) { obj.CAdvisorPort = 4194 } if obj.VolumeStatsAggPeriod == zeroDuration { - obj.VolumeStatsAggPeriod = unversioned.Duration{1 * time.Minute} + obj.VolumeStatsAggPeriod = unversioned.Duration{Duration: time.Minute} } if obj.CertDirectory == "" { obj.CertDirectory = "/var/run/kubernetes" @@ -152,6 +155,9 @@ func SetDefaults_KubeletConfiguration(obj *KubeletConfiguration) { if obj.ContainerRuntime == "" { obj.ContainerRuntime = "docker" } + if obj.RuntimeRequestTimeout == zeroDuration { + obj.RuntimeRequestTimeout = unversioned.Duration{Duration: 2 * time.Minute} + } if obj.CPUCFSQuota == nil { obj.CPUCFSQuota = boolVar(true) } @@ -167,6 +173,9 @@ func SetDefaults_KubeletConfiguration(obj *KubeletConfiguration) { if obj.EventRecordQPS == 0 { obj.EventRecordQPS = 5.0 } + if obj.EnableControllerAttachDetach == nil { + obj.EnableControllerAttachDetach = boolVar(true) + } if obj.EnableDebuggingHandlers == nil { obj.EnableDebuggingHandlers = boolVar(true) } @@ -174,7 +183,7 @@ func SetDefaults_KubeletConfiguration(obj *KubeletConfiguration) { obj.EnableServer = boolVar(true) } if obj.FileCheckFrequency == zeroDuration { - obj.FileCheckFrequency = unversioned.Duration{20 * time.Second} + obj.FileCheckFrequency = unversioned.Duration{Duration: 20 * time.Second} } if obj.HealthzBindAddress == "" { obj.HealthzBindAddress = "127.0.0.1" @@ -192,13 +201,18 @@ func SetDefaults_KubeletConfiguration(obj *KubeletConfiguration) { obj.HostIPCSources = []string{kubetypes.AllSource} } if obj.HTTPCheckFrequency == zeroDuration { - obj.HTTPCheckFrequency = unversioned.Duration{20 * time.Second} + obj.HTTPCheckFrequency = unversioned.Duration{Duration: 20 * time.Second} + } + if obj.ImageMinimumGCAge == zeroDuration { + obj.ImageMinimumGCAge = unversioned.Duration{Duration: 2 * time.Minute} } if obj.ImageGCHighThresholdPercent == nil { - obj.ImageGCHighThresholdPercent = 90 + temp := int32(90) + obj.ImageGCHighThresholdPercent = &temp } if obj.ImageGCLowThresholdPercent == nil { - obj.ImageGCLowThresholdPercent = 80 + temp := int32(80) + obj.ImageGCLowThresholdPercent = &temp } if obj.LowDiskSpaceThresholdMB == 0 { obj.LowDiskSpaceThresholdMB = 256 @@ -207,11 +221,11 @@ func SetDefaults_KubeletConfiguration(obj *KubeletConfiguration) { obj.MasterServiceNamespace = api.NamespaceDefault } if obj.MaxContainerCount == nil { - temp := int64(100) + temp := int32(-1) obj.MaxContainerCount = &temp } if obj.MaxPerPodContainerCount == 0 { - obj.MaxPerPodContainerCount = 2 + obj.MaxPerPodContainerCount = 1 } if obj.MaxOpenFiles == 0 { obj.MaxOpenFiles = 1000000 @@ -220,7 +234,7 @@ func SetDefaults_KubeletConfiguration(obj *KubeletConfiguration) { obj.MaxPods = 110 } if obj.MinimumGCAge == zeroDuration { - obj.MinimumGCAge = unversioned.Duration{1 * time.Minute} + obj.MinimumGCAge = unversioned.Duration{Duration: 0} } if obj.NetworkPluginDir == "" { obj.NetworkPluginDir = "/usr/libexec/kubernetes/kubelet-plugins/net/exec/" @@ -232,13 +246,14 @@ func SetDefaults_KubeletConfiguration(obj *KubeletConfiguration) { obj.VolumePluginDir = "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/" } if obj.NodeStatusUpdateFrequency == zeroDuration { - obj.NodeStatusUpdateFrequency = unversioned.Duration{10 * time.Second} + obj.NodeStatusUpdateFrequency = unversioned.Duration{Duration: 10 * time.Second} } - if obj.OOMScoreAdj == 0 { - obj.OOMScoreAdj = int32(qos.KubeletOOMScoreAdj) + if obj.OOMScoreAdj == nil { + temp := int32(qos.KubeletOOMScoreAdj) + obj.OOMScoreAdj = &temp } if obj.PodInfraContainerImage == "" { - obj.PodInfraContainerImage = defaultPodInfraContainer + obj.PodInfraContainerImage = defaultPodInfraContainerImage } if obj.Port == 0 { obj.Port = ports.KubeletPort @@ -255,42 +270,55 @@ func SetDefaults_KubeletConfiguration(obj *KubeletConfiguration) { if obj.RegistryBurst == 0 { obj.RegistryBurst = 10 } - if obj.RegistryPullQPS == 0 { - obj.RegistryPullQPS = 5 + if obj.RegistryPullQPS == nil { + temp := float64(5) + obj.RegistryPullQPS = &temp + } + if obj.ResolverConfig == "" { + obj.ResolverConfig = kubetypes.ResolvConfDefault } if obj.RktAPIEndpoint == "" { - obj.RktAPIEndpoint = "localhost:15441" + obj.RktAPIEndpoint = defaultRktAPIServiceEndpoint } if obj.RootDirectory == "" { - obj.RootDirectory = "/var/lib/kubelet" + obj.RootDirectory = defaultRootDir } if obj.SerializeImagePulls == nil { obj.SerializeImagePulls = boolVar(true) } + if obj.SeccompProfileRoot == "" { + filepath.Join(defaultRootDir, "seccomp") + } if obj.StreamingConnectionIdleTimeout == zeroDuration { - obj.StreamingConnectionIdleTimeout = unversioned.Duration{4 * time.Hour} + obj.StreamingConnectionIdleTimeout = unversioned.Duration{Duration: 4 * time.Hour} } if obj.SyncFrequency == zeroDuration { - obj.SyncFrequency = unversioned.Duration{1 * time.Minute} + obj.SyncFrequency = unversioned.Duration{Duration: 1 * time.Minute} } if obj.ReconcileCIDR == nil { obj.ReconcileCIDR = boolVar(true) } + if obj.ContentType == "" { + obj.ContentType = "application/vnd.kubernetes.protobuf" + } if obj.KubeAPIQPS == 0 { obj.KubeAPIQPS = 5 } if obj.KubeAPIBurst == 0 { obj.KubeAPIBurst = 10 } - if obj.ExperimentalFlannelOverlay == nil { - obj.ExperimentalFlannelOverlay = boolVar(false) - } if obj.OutOfDiskTransitionFrequency == zeroDuration { - obj.OutOfDiskTransitionFrequency = unversioned.Duration{5 * time.Minute} + obj.OutOfDiskTransitionFrequency = unversioned.Duration{Duration: 5 * time.Minute} } if string(obj.HairpinMode) == "" { obj.HairpinMode = PromiscuousBridge } + if obj.EvictionHard == nil { + obj.EvictionHard = &"memory.available<100Mi" + } + if obj.EvictionPressureTransitionPeriod == zeroDuration { + obj.EvictionPressureTransitionPeriod = unversioned.Duration{Duration: 5 * time.Minute} + } } func boolVar(b bool) *bool { diff --git a/pkg/apis/componentconfig/v1alpha1/types.go b/pkg/apis/componentconfig/v1alpha1/types.go index 32f220304cc..1c6ef0f6371 100644 --- a/pkg/apis/componentconfig/v1alpha1/types.go +++ b/pkg/apis/componentconfig/v1alpha1/types.go @@ -210,11 +210,14 @@ type KubeletConfiguration struct { // rootDirectory is the directory path to place kubelet files (volume // mounts,etc). RootDirectory string `json:"rootDirectory"` + // seccompProfileRoot is the directory path for seccomp profiles. + SeccompProfileRoot string `json:"seccompProfileRoot"` // allowPrivileged enables containers to request privileged mode. // Defaults to false. AllowPrivileged *bool `json:"allowPrivileged"` // hostNetworkSources is a comma-separated list of sources from which the - // Kubelet allows pods to use of host network. Defaults to "*". + // Kubelet allows pods to use of host network. Defaults to "*". Valid + // options are "file", "http", "api", and "*" (all sources). HostNetworkSources []string `json:"hostNetworkSources"` // hostPIDSources is a comma-separated list of sources from which the // Kubelet allows pods to use the host pid namespace. Defaults to "*". @@ -224,7 +227,7 @@ type KubeletConfiguration struct { HostIPCSources []string `json:"hostIPCSources"` // registryPullQPS is the limit of registry pulls per second. If 0, // unlimited. Set to 0 for no limit. Defaults to 5.0. - RegistryPullQPS float64 `json:"registryPullQPS"` + RegistryPullQPS *float64 `json:"registryPullQPS"` // registryBurst is the maximum size of a bursty pulls, temporarily allows // pulls to burst to this number, while still not exceeding registryQps. // Only used if registryQps > 0. @@ -247,7 +250,7 @@ type KubeletConfiguration struct { MaxPerPodContainerCount int64 `json:"maxPerPodContainerCount"` // maxContainerCount is the maximum number of old instances of containers // to retain globally. Each container takes up some disk space. - MaxContainerCount *int64 `json:"maxContainerCount"` + MaxContainerCount *int32 `json:"maxContainerCount"` // cAdvisorPort is the port of the localhost cAdvisor endpoint CAdvisorPort int32 `json:"cAdvisorPort"` // healthzPort is the port of the localhost healthz endpoint @@ -257,7 +260,7 @@ type KubeletConfiguration struct { HealthzBindAddress string `json:"healthzBindAddress"` // oomScoreAdj is The oom-score-adj value for kubelet process. Values // must be within the range [-1000, 1000]. - OOMScoreAdj int32 `json:"oomScoreAdj"` + OOMScoreAdj *int32 `json:"oomScoreAdj"` // registerNode enables automatic registration with the apiserver. RegisterNode *bool `json:"registerNode"` // clusterDomain is the DNS domain for this cluster. If set, kubelet will @@ -284,17 +287,17 @@ type KubeletConfiguration struct { // imageGCHighThresholdPercent is the percent of disk usage after which // image garbage collection is always run. The percent is calculated as // this field value out of 100. - ImageGCHighThresholdPercent int32 `json:"imageGCHighThresholdPercent"` + ImageGCHighThresholdPercent *int32 `json:"imageGCHighThresholdPercent"` // imageGCLowThresholdPercent is the percent of disk usage before which // image garbage collection is never run. Lowest disk usage to garbage // collect to. The percent is calculated as this field value out of 100. - ImageGCLowThresholdPercent int32 `json:"imageGCLowThresholdPercent"` + ImageGCLowThresholdPercent *int32 `json:"imageGCLowThresholdPercent"` // lowDiskSpaceThresholdMB is the absolute free disk space, in MB, to // maintain. When disk space falls below this threshold, new pods would // be rejected. LowDiskSpaceThresholdMB int64 `json:"lowDiskSpaceThresholdMB"` // How frequently to calculate and cache volume disk usage for all pods - VolumeStatsAggPeriod unversioned.Duration `json:volumeStatsAggPeriod` + VolumeStatsAggPeriod unversioned.Duration `json:"volumeStatsAggPeriod"` // networkPluginName is the name of the network plugin to be invoked for // various events in kubelet/pod lifecycle NetworkPluginName string `json:"networkPluginName"` @@ -309,28 +312,38 @@ type KubeletConfiguration struct { // cloudConfigFile is the path to the cloud provider configuration file. CloudConfigFile string `json:"cloudConfigFile"` // kubeletCgroups is the absolute name of cgroups to isolate the kubelet in. - KubeletCgroups string `json:"kubeletCgroups,omitempty"` + KubeletCgroups string `json:"kubeletCgroups"` // runtimeCgroups are cgroups that container runtime is expected to be isolated in. - RuntimeCgroups string `json:"runtimeCgroups,omitempty"` + RuntimeCgroups string `json:"runtimeCgroups"` // systemCgroups is absolute name of cgroups in which to place // all non-kernel processes that are not already in a container. Empty // for no container. Rolling back the flag requires a reboot. - SystemCgroups string `json:"systemCgroups,omitempty"` + SystemCgroups string `json:"systemCgroups"` // cgroupRoot is the root cgroup to use for pods. This is handled by the // container runtime on a best effort basis. CgroupRoot string `json:"cgroupRoot"` // containerRuntime is the container runtime to use. ContainerRuntime string `json:"containerRuntime"` - // rktPath is hte path of rkt binary. Leave empty to use the first rkt in + // runtimeRequestTimeout is the timeout for all runtime requests except long running + // requests - pull, logs, exec and attach. + RuntimeRequestTimeout unversioned.Duration `json:"runtimeRequestTimeout"` + // rktPath is the path of rkt binary. Leave empty to use the first rkt in // $PATH. RktPath string `json:"rktPath"` + // rktApiEndpoint is the endpoint of the rkt API service to communicate with. + RktAPIEndpoint string `json:"rktAPIEndpoint"` + // rktStage1Image is the image to use as stage1. Local paths and + // http/https URLs are supported. + RktStage1Image string `json:"rktStage1Image"` // lockFilePath is the path that kubelet will use to as a lock file. // It uses this file as a lock to synchronize with other kubelet processes // that may be running. LockFilePath *string `json:"lockFilePath"` - // rktStage1Image is the image to use as stage1. Local paths and - // http/https URLs are supported. - RktStage1Image string `json:"rktStage1Image"` + // ExitOnLockContention is a flag that signifies to the kubelet that it is running + // in "bootstrap" mode. This requires that 'LockFilePath' has been set. + // This will cause the kubelet to listen to inotify events on the lock file, + // releasing it and exiting when another process tries to open that file. + ExitOnLockContention bool `json:"exitOnLockContention"` // configureCBR0 enables the kublet to configure cbr0 based on // Node.Spec.PodCIDR. ConfigureCBR0 *bool `json:"configureCbr0"` @@ -344,8 +357,12 @@ type KubeletConfiguration struct { // one must set --hairpin-mode=veth-flag, because bridge assumes the // existence of a container bridge named cbr0. HairpinMode string `json:"hairpinMode"` + // The node has babysitter process monitoring docker and kubelet. + BabysitDaemons bool `json:"babysitDaemons"` // maxPods is the number of pods that can run on this Kubelet. MaxPods int32 `json:"maxPods"` + // nvidiaGPUs is the number of NVIDIA GPU devices on this node. + NvidiaGPUs int32 `json:"nvidiaGPUs"` // dockerExecHandlerName is the handler to use when executing a command // in a container. Valid values are 'native' and 'nsenter'. Defaults to // 'native'. @@ -369,6 +386,8 @@ type KubeletConfiguration struct { // registerSchedulable tells the kubelet to register the node as // schedulable. No-op if register-node is false. RegisterSchedulable *bool `json:"registerSchedulable"` + // contentType is contentType of requests sent to apiserver. + ContentType string `json:"contentType"` // kubeAPIQPS is the QPS to use while talking with kubernetes apiserver KubeAPIQPS float32 `json:"kubeAPIQPS"` // kubeAPIBurst is the burst to allow while talking with kubernetes @@ -382,7 +401,7 @@ type KubeletConfiguration struct { // experimentalFlannelOverlay enables experimental support for starting the // kubelet with the default overlay network (flannel). Assumes flanneld // is already running in client mode. - ExperimentalFlannelOverlay *bool `json:"experimentalFlannelOverlay"` + ExperimentalFlannelOverlay bool `json:"experimentalFlannelOverlay"` // outOfDiskTransitionFrequency is duration for which the kubelet has to // wait before transitioning out of out-of-disk node condition status. OutOfDiskTransitionFrequency unversioned.Duration `json:"outOfDiskTransitionFrequency"` @@ -395,4 +414,20 @@ type KubeletConfiguration struct { NonMasqueradeCIDR string `json:"nonMasqueradeCIDR"` // enable gathering custom metrics. EnableCustomMetrics bool `json:"enableCustomMetrics"` + // Comma-delimited list of hard eviction expressions. For example, 'memory.available<300Mi'. + EvictionHard string `json:"evictionHard"` + // Comma-delimited list of soft eviction expressions. For example, 'memory.available<300Mi'. + EvictionSoft string `json:"evictionSoft"` + // Comma-delimeted list of grace periods for each soft eviction signal. For example, 'memory.available=30s'. + EvictionSoftGracePeriod string `json:"evictionSoftGracePeriod"` + // Duration for which the kubelet has to wait before transitioning out of an eviction pressure condition. + EvictionPressureTransitionPeriod unversioned.Duration `json:"evictionPressureTransitionPeriod"` + // Maximum allowed grace period (in seconds) to use when terminating pods in response to a soft eviction threshold being met. + EvictionMaxPodGracePeriod int32 `json:"evictionMaxPodGracePeriod"` + // Maximum number of pods per core. Cannot exceed MaxPods + PodsPerCore int32 `json:"podsPerCore"` + // enableControllerAttachDetach enables the Attach/Detach controller to + // manage attachment/detachment of volumes scheduled to this node, and + // disables kubelet from executing any attach/detach operations + EnableControllerAttachDetach *bool `json:"enableControllerAttachDetach"` }