2014-10-27 17:04:39 +00:00
/ *
2015-05-01 16:19:44 +00:00
Copyright 2014 The Kubernetes Authors All rights reserved .
2014-10-27 17:04:39 +00:00
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 .
* /
2015-02-07 21:30:53 +00:00
// Package app makes it easy to create a kubelet server for various contexts.
package app
2014-10-27 17:04:39 +00:00
import (
2015-04-01 23:19:17 +00:00
"crypto/tls"
2014-10-27 17:04:39 +00:00
"fmt"
2015-02-02 21:30:31 +00:00
"math/rand"
2014-10-27 17:04:39 +00:00
"net"
2015-03-30 21:09:50 +00:00
"net/http"
2015-04-17 06:07:00 +00:00
_ "net/http/pprof"
2015-04-01 23:19:17 +00:00
"path"
2015-03-30 21:09:50 +00:00
"strconv"
2015-03-24 23:09:16 +00:00
"strings"
2014-10-27 17:04:39 +00:00
"time"
2015-02-02 21:30:31 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
2015-04-11 17:55:31 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/capabilities"
2014-10-27 17:04:39 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
2015-04-11 16:45:45 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/chaosclient"
2015-03-03 06:06:20 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/record"
2015-01-07 15:18:56 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
2015-01-27 20:16:47 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider"
2015-03-30 21:09:50 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/healthz"
2014-10-27 17:04:39 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet"
2015-03-06 07:56:30 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/cadvisor"
2014-10-27 17:04:39 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config"
2015-04-27 20:03:55 +00:00
kubecontainer "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/container"
2014-11-27 21:28:56 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools"
2015-03-19 23:14:13 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/network"
2015-02-02 21:30:31 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports"
2014-10-27 17:04:39 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
2015-05-04 14:43:10 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount"
2015-03-19 05:18:31 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/volume"
2014-10-27 17:04:39 +00:00
2015-03-23 22:31:13 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
2014-10-27 17:04:39 +00:00
"github.com/golang/glog"
2015-02-02 21:30:31 +00:00
"github.com/spf13/pflag"
2014-10-27 17:04:39 +00:00
)
2015-02-02 21:30:31 +00:00
const defaultRootDir = "/var/lib/kubelet"
// KubeletServer encapsulates all of the parameters necessary for starting up
// a kubelet. These can either be set via command line or directly.
type KubeletServer struct {
2015-01-08 20:41:38 +00:00
Config string
SyncFrequency time . Duration
FileCheckFrequency time . Duration
HTTPCheckFrequency time . Duration
ManifestURL string
EnableServer bool
Address util . IP
Port uint
2015-04-02 04:41:32 +00:00
ReadOnlyPort uint
2015-01-08 20:41:38 +00:00
HostnameOverride string
PodInfraContainerImage string
DockerEndpoint string
RootDirectory string
AllowPrivileged bool
2015-03-24 23:09:16 +00:00
HostNetworkSources string
2015-01-08 20:41:38 +00:00
RegistryPullQPS float64
RegistryBurst int
RunOnce bool
EnableDebuggingHandlers bool
MinimumGCAge time . Duration
2015-03-14 17:13:20 +00:00
MaxPerPodContainerCount int
2015-01-08 20:41:38 +00:00
MaxContainerCount int
AuthPath string
2015-03-10 05:39:00 +00:00
CadvisorPort uint
2015-03-30 21:09:50 +00:00
HealthzPort int
HealthzBindAddress util . IP
2015-01-08 20:41:38 +00:00
OOMScoreAdj int
APIServerList util . StringList
ClusterDomain string
MasterServiceNamespace string
ClusterDNS util . IP
StreamingConnectionIdleTimeout time . Duration
2015-03-16 04:00:46 +00:00
ImageGCHighThresholdPercent int
ImageGCLowThresholdPercent int
2015-05-12 08:24:08 +00:00
LowDiskSpaceThresholdMB int
2015-03-19 23:14:13 +00:00
NetworkPluginName string
2015-03-23 22:31:13 +00:00
CloudProvider string
CloudConfigFile string
2015-04-01 23:19:17 +00:00
TLSCertFile string
TLSPrivateKeyFile string
CertDirectory string
2015-03-31 11:17:12 +00:00
NodeStatusUpdateFrequency time . Duration
2015-04-14 00:30:57 +00:00
ResourceContainer string
2015-04-24 00:07:52 +00:00
CgroupRoot string
2015-05-01 21:24:07 +00:00
ContainerRuntime string
2015-05-12 16:59:02 +00:00
DockerDaemonContainer string
2015-04-11 16:45:45 +00:00
// Flags intended for testing
// Crash immediately, rather than eating panics.
ReallyCrashForTesting bool
// Insert a probability of random errors during calls to the master.
ChaosChance float64
2015-05-05 15:07:15 +00:00
// Is the kubelet containerized?
Containerized bool
2015-02-02 21:30:31 +00:00
}
2015-03-26 12:31:54 +00:00
// bootstrapping interface for kubelet, targets the initialization protocol
type KubeletBootstrap interface {
BirthCry ( )
StartGarbageCollection ( )
ListenAndServe ( net . IP , uint , * kubelet . TLSOptions , bool )
ListenAndServeReadOnly ( net . IP , uint )
Run ( <- chan kubelet . PodUpdate )
RunOnce ( <- chan kubelet . PodUpdate ) ( [ ] kubelet . RunPodResult , error )
}
// create and initialize a Kubelet instance
type KubeletBuilder func ( kc * KubeletConfig ) ( KubeletBootstrap , * config . PodConfig , error )
2015-02-02 21:30:31 +00:00
// NewKubeletServer will create a new KubeletServer with default values.
func NewKubeletServer ( ) * KubeletServer {
return & KubeletServer {
2015-04-02 04:41:32 +00:00
SyncFrequency : 10 * time . Second ,
FileCheckFrequency : 20 * time . Second ,
HTTPCheckFrequency : 20 * time . Second ,
EnableServer : true ,
Address : util . IP ( net . ParseIP ( "0.0.0.0" ) ) ,
Port : ports . KubeletPort ,
ReadOnlyPort : ports . KubeletReadOnlyPort ,
2015-04-09 01:56:58 +00:00
PodInfraContainerImage : dockertools . PodInfraContainerImage ,
2015-03-16 04:00:46 +00:00
RootDirectory : defaultRootDir ,
RegistryBurst : 10 ,
EnableDebuggingHandlers : true ,
MinimumGCAge : 1 * time . Minute ,
MaxPerPodContainerCount : 5 ,
MaxContainerCount : 100 ,
2015-04-01 17:00:42 +00:00
AuthPath : "/var/lib/kubelet/kubernetes_auth" ,
2015-03-16 04:00:46 +00:00
CadvisorPort : 4194 ,
2015-03-30 21:09:50 +00:00
HealthzPort : 10248 ,
HealthzBindAddress : util . IP ( net . ParseIP ( "127.0.0.1" ) ) ,
2015-03-16 04:00:46 +00:00
OOMScoreAdj : - 900 ,
MasterServiceNamespace : api . NamespaceDefault ,
ImageGCHighThresholdPercent : 90 ,
ImageGCLowThresholdPercent : 80 ,
2015-05-12 08:24:08 +00:00
LowDiskSpaceThresholdMB : 256 ,
2015-03-19 23:14:13 +00:00
NetworkPluginName : "" ,
2015-03-24 23:09:16 +00:00
HostNetworkSources : kubelet . FileSource ,
2015-04-01 23:19:17 +00:00
CertDirectory : "/var/run/kubernetes" ,
2015-04-07 19:36:09 +00:00
NodeStatusUpdateFrequency : 10 * time . Second ,
2015-04-14 00:30:57 +00:00
ResourceContainer : "/kubelet" ,
2015-05-09 00:51:24 +00:00
CgroupRoot : "/" ,
2015-05-01 21:24:07 +00:00
ContainerRuntime : "docker" ,
2015-05-12 16:59:02 +00:00
DockerDaemonContainer : "/docker-daemon" ,
2015-02-02 21:30:31 +00:00
}
}
// AddFlags adds flags for a specific KubeletServer to the specified FlagSet
func ( s * KubeletServer ) AddFlags ( fs * pflag . FlagSet ) {
fs . StringVar ( & s . Config , "config" , s . Config , "Path to the config file or directory of files" )
2015-04-24 06:10:33 +00:00
fs . DurationVar ( & s . SyncFrequency , "sync-frequency" , s . SyncFrequency , "Max period between synchronizing running containers and config" )
fs . DurationVar ( & s . FileCheckFrequency , "file-check-frequency" , s . FileCheckFrequency , "Duration between checking config files for new data" )
fs . DurationVar ( & s . HTTPCheckFrequency , "http-check-frequency" , s . HTTPCheckFrequency , "Duration between checking http for new data" )
fs . StringVar ( & s . ManifestURL , "manifest-url" , s . ManifestURL , "URL for accessing the container manifest" )
fs . BoolVar ( & s . EnableServer , "enable-server" , s . EnableServer , "Enable the info server" )
2015-02-02 21:30:31 +00:00
fs . Var ( & s . Address , "address" , "The IP address for the info server to serve on (set to 0.0.0.0 for all interfaces)" )
fs . UintVar ( & s . Port , "port" , s . Port , "The port for the info server to serve on" )
2015-04-24 06:10:33 +00:00
fs . UintVar ( & s . ReadOnlyPort , "read-only-port" , s . ReadOnlyPort , "The read-only port for the info server to serve on (set to 0 to disable)" )
fs . StringVar ( & s . TLSCertFile , "tls-cert-file" , s . TLSCertFile , "" +
2015-04-01 23:19:17 +00:00
"File containing x509 Certificate for HTTPS. (CA cert, if any, concatenated after server cert). " +
"If --tls_cert_file and --tls_private_key_file are not provided, a self-signed certificate and key " +
"are generated for the public address and saved to the directory passed to --cert_dir." )
2015-04-24 06:10:33 +00:00
fs . StringVar ( & s . TLSPrivateKeyFile , "tls-private-key-file" , s . TLSPrivateKeyFile , "File containing x509 private key matching --tls_cert_file." )
fs . StringVar ( & s . CertDirectory , "cert-dir" , s . CertDirectory , "The directory where the TLS certs are located (by default /var/run/kubernetes). " +
2015-04-19 15:35:56 +00:00
"If --tls_cert_file and --tls_private_key_file are provided, this flag will be ignored." )
2015-04-24 06:10:33 +00:00
fs . StringVar ( & s . HostnameOverride , "hostname-override" , s . HostnameOverride , "If non-empty, will use this string as identification instead of the actual hostname." )
fs . StringVar ( & s . PodInfraContainerImage , "pod-infra-container-image" , s . PodInfraContainerImage , "The image whose network/ipc namespaces containers in each pod will use." )
fs . StringVar ( & s . DockerEndpoint , "docker-endpoint" , s . DockerEndpoint , "If non-empty, use this for the docker endpoint to communicate with" )
fs . StringVar ( & s . RootDirectory , "root-dir" , s . RootDirectory , "Directory path for managing kubelet files (volume mounts,etc)." )
fs . BoolVar ( & s . AllowPrivileged , "allow-privileged" , s . AllowPrivileged , "If true, allow containers to request privileged mode. [default=false]" )
fs . StringVar ( & s . HostNetworkSources , "host-network-sources" , s . HostNetworkSources , "Comma-separated list of sources from which the Kubelet allows pods to use of host network. For all sources use \"*\" [default=\"file\"]" )
fs . Float64Var ( & s . RegistryPullQPS , "registry-qps" , s . RegistryPullQPS , "If > 0, limit registry pull QPS to this value. If 0, unlimited. [default=0.0]" )
fs . IntVar ( & s . RegistryBurst , "registry-burst" , s . RegistryBurst , "Maximum size of a bursty pulls, temporarily allows pulls to burst to this number, while still not exceeding registry_qps. Only used if --registry_qps > 0" )
2015-03-10 16:15:17 +00:00
fs . BoolVar ( & s . RunOnce , "runonce" , s . RunOnce , "If true, exit after spawning pods from local manifests or remote urls. Exclusive with --api_servers, and --enable-server" )
2015-04-24 06:10:33 +00:00
fs . BoolVar ( & s . EnableDebuggingHandlers , "enable-debugging-handlers" , s . EnableDebuggingHandlers , "Enables server endpoints for log collection and local running of containers and commands" )
fs . DurationVar ( & s . MinimumGCAge , "minimum-container-ttl-duration" , s . MinimumGCAge , "Minimum age for a finished container before it is garbage collected. Examples: '300ms', '10s' or '2h45m'" )
fs . IntVar ( & s . MaxPerPodContainerCount , "maximum-dead-containers-per-container" , s . MaxPerPodContainerCount , "Maximum number of old instances of a container to retain per container. Each container takes up some disk space. Default: 5." )
fs . IntVar ( & s . MaxContainerCount , "maximum-dead-containers" , s . MaxContainerCount , "Maximum number of old instances of a containers to retain globally. Each container takes up some disk space. Default: 100." )
fs . StringVar ( & s . AuthPath , "auth-path" , s . AuthPath , "Path to .kubernetes_auth file, specifying how to authenticate to API server." )
2015-05-08 20:26:27 +00:00
fs . MarkDeprecated ( "auth-path" , "will be removed in a future version" )
2015-04-24 06:10:33 +00:00
fs . UintVar ( & s . CadvisorPort , "cadvisor-port" , s . CadvisorPort , "The port of the localhost cAdvisor endpoint" )
fs . IntVar ( & s . HealthzPort , "healthz-port" , s . HealthzPort , "The port of the localhost healthz endpoint" )
fs . Var ( & s . HealthzBindAddress , "healthz-bind-address" , "The IP address for the healthz server to serve on, defaulting to 127.0.0.1 (set to 0.0.0.0 for all interfaces)" )
fs . IntVar ( & s . OOMScoreAdj , "oom-score-adj" , s . OOMScoreAdj , "The oom_score_adj value for kubelet process. Values must be within the range [-1000, 1000]" )
fs . Var ( & s . APIServerList , "api-servers" , "List of Kubernetes API servers for publishing events, and reading pods and services. (ip:port), comma separated." )
fs . StringVar ( & s . ClusterDomain , "cluster-domain" , s . ClusterDomain , "Domain for this cluster. If set, kubelet will configure all containers to search this domain in addition to the host's search domains" )
fs . StringVar ( & s . MasterServiceNamespace , "master-service-namespace" , s . MasterServiceNamespace , "The namespace from which the kubernetes master services should be injected into pods" )
fs . Var ( & s . ClusterDNS , "cluster-dns" , "IP address for a cluster DNS server. If set, kubelet will configure all containers to use this for DNS resolution in addition to the host's DNS servers" )
fs . DurationVar ( & s . StreamingConnectionIdleTimeout , "streaming-connection-idle-timeout" , 0 , "Maximum time a streaming connection can be idle before the connection is automatically closed. Example: '5m'" )
fs . DurationVar ( & s . NodeStatusUpdateFrequency , "node-status-update-frequency" , s . NodeStatusUpdateFrequency , "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" )
fs . IntVar ( & s . ImageGCHighThresholdPercent , "image-gc-high-threshold" , s . ImageGCHighThresholdPercent , "The percent of disk usage after which image garbage collection is always run. Default: 90%%" )
fs . IntVar ( & s . ImageGCLowThresholdPercent , "image-gc-low-threshold" , s . ImageGCLowThresholdPercent , "The percent of disk usage before which image garbage collection is never run. Lowest disk usage to garbage collect to. Default: 80%%" )
2015-05-12 08:24:08 +00:00
fs . IntVar ( & s . LowDiskSpaceThresholdMB , "low-diskspace-threshold-mb" , s . LowDiskSpaceThresholdMB , "The absolute free disk space, in MB, to maintain. When disk space falls below this threshold, new pods would be rejected. Default: 256" )
2015-04-24 06:10:33 +00:00
fs . StringVar ( & s . NetworkPluginName , "network-plugin" , s . NetworkPluginName , "<Warning: Alpha feature> The name of the network plugin to be invoked for various events in kubelet/pod lifecycle" )
fs . StringVar ( & s . CloudProvider , "cloud-provider" , s . CloudProvider , "The provider for cloud services. Empty string for no provider." )
fs . StringVar ( & s . CloudConfigFile , "cloud-config" , s . CloudConfigFile , "The path to the cloud provider configuration file. Empty string for no configuration file." )
fs . StringVar ( & s . ResourceContainer , "resource-container" , s . ResourceContainer , "Absolute name of the resource-only container to create and run the Kubelet in (Default: /kubelet)." )
2015-05-09 00:51:24 +00:00
fs . StringVar ( & s . CgroupRoot , "cgroup_root" , s . CgroupRoot , "Optional root cgroup to use for pods. This is handled by the container runtime on a best effort basis. Default: '/', which means top-level." )
2015-05-08 06:26:07 +00:00
fs . StringVar ( & s . ContainerRuntime , "container_runtime" , s . ContainerRuntime , "The container runtime to use. Possible values: 'docker', 'rkt'. Default: 'docker'." )
2015-05-12 16:59:02 +00:00
fs . StringVar ( & s . DockerDaemonContainer , "docker-daemon-container" , s . DockerDaemonContainer , "Optional resource-only container in which to place the Docker Daemon. Empty for no container (Default: /docker-daemon)." )
2015-04-11 16:45:45 +00:00
// Flags intended for testing, not recommended used in production environments.
2015-04-24 06:10:33 +00:00
fs . BoolVar ( & s . ReallyCrashForTesting , "really-crash-for-testing" , s . ReallyCrashForTesting , "If true, when panics occur crash. Intended for testing." )
fs . Float64Var ( & s . ChaosChance , "chaos-chance" , s . ChaosChance , "If > 0.0, introduce random client errors and latency. Intended for testing. [default=0.0]" )
2015-05-05 15:07:15 +00:00
fs . BoolVar ( & s . Containerized , "containerized" , s . Containerized , "Experimental support for running kubelet in a container. Intended for testing. [default=false]" )
2015-02-02 21:30:31 +00:00
}
// Run runs the specified KubeletServer. This should never exit.
func ( s * KubeletServer ) Run ( _ [ ] string ) error {
util . ReallyCrash = s . ReallyCrashForTesting
rand . Seed ( time . Now ( ) . UTC ( ) . UnixNano ( ) )
2015-04-14 00:30:57 +00:00
// TODO(vmarmol): Do this through container config.
2015-02-20 01:16:31 +00:00
if err := util . ApplyOomScoreAdj ( 0 , s . OOMScoreAdj ) ; err != nil {
2015-02-02 21:30:31 +00:00
glog . Info ( err )
}
client , err := s . createAPIServerClient ( )
if err != nil && len ( s . APIServerList ) > 0 {
glog . Warningf ( "No API client: %v" , err )
}
2015-02-18 01:26:41 +00:00
glog . Infof ( "Using root directory: %v" , s . RootDirectory )
2015-02-02 21:30:31 +00:00
credentialprovider . SetPreferredDockercfgPath ( s . RootDirectory )
2015-03-10 05:39:00 +00:00
cadvisorInterface , err := cadvisor . New ( s . CadvisorPort )
if err != nil {
return err
}
2015-03-16 04:00:46 +00:00
imageGCPolicy := kubelet . ImageGCPolicy {
HighThresholdPercent : s . ImageGCHighThresholdPercent ,
LowThresholdPercent : s . ImageGCLowThresholdPercent ,
}
2015-03-23 22:31:13 +00:00
2015-05-12 08:24:08 +00:00
diskSpacePolicy := kubelet . DiskSpacePolicy {
DockerFreeDiskMB : s . LowDiskSpaceThresholdMB ,
RootFreeDiskMB : s . LowDiskSpaceThresholdMB ,
}
2015-03-23 22:31:13 +00:00
cloud := cloudprovider . InitCloudProvider ( s . CloudProvider , s . CloudConfigFile )
glog . Infof ( "Successfully initialized cloud provider: %q from the config file: %q\n" , s . CloudProvider , s . CloudConfigFile )
2015-03-24 23:09:16 +00:00
hostNetworkSources , err := kubelet . GetValidatedSources ( strings . Split ( s . HostNetworkSources , "," ) )
if err != nil {
return err
}
2015-04-01 23:19:17 +00:00
if s . TLSCertFile == "" && s . TLSPrivateKeyFile == "" {
s . TLSCertFile = path . Join ( s . CertDirectory , "kubelet.crt" )
s . TLSPrivateKeyFile = path . Join ( s . CertDirectory , "kubelet.key" )
if err := util . GenerateSelfSignedCert ( util . GetHostname ( s . HostnameOverride ) , s . TLSCertFile , s . TLSPrivateKeyFile ) ; err != nil {
glog . Fatalf ( "Unable to generate self signed cert: %v" , err )
}
glog . Infof ( "Using self-signed cert (%s, %s)" , s . TLSCertFile , s . TLSPrivateKeyFile )
}
tlsOptions := & kubelet . TLSOptions {
Config : & tls . Config {
// Change default from SSLv3 to TLSv1.0 (because of POODLE vulnerability).
MinVersion : tls . VersionTLS10 ,
// Populate PeerCertificates in requests, but don't yet reject connections without certificates.
ClientAuth : tls . RequestClientCert ,
} ,
CertFile : s . TLSCertFile ,
KeyFile : s . TLSPrivateKeyFile ,
}
2015-05-05 15:07:15 +00:00
mounter := mount . New ( )
if s . Containerized {
glog . Info ( "Running kubelet in containerized mode (experimental)" )
mounter = & mount . NsenterMounter { }
}
2015-02-02 21:30:31 +00:00
kcfg := KubeletConfig {
2015-01-08 20:41:38 +00:00
Address : s . Address ,
AllowPrivileged : s . AllowPrivileged ,
2015-03-24 23:09:16 +00:00
HostNetworkSources : hostNetworkSources ,
2015-01-08 20:41:38 +00:00
HostnameOverride : s . HostnameOverride ,
RootDirectory : s . RootDirectory ,
ConfigFile : s . Config ,
ManifestURL : s . ManifestURL ,
FileCheckFrequency : s . FileCheckFrequency ,
HTTPCheckFrequency : s . HTTPCheckFrequency ,
PodInfraContainerImage : s . PodInfraContainerImage ,
SyncFrequency : s . SyncFrequency ,
RegistryPullQPS : s . RegistryPullQPS ,
RegistryBurst : s . RegistryBurst ,
MinimumGCAge : s . MinimumGCAge ,
2015-03-14 17:13:20 +00:00
MaxPerPodContainerCount : s . MaxPerPodContainerCount ,
2015-01-08 20:41:38 +00:00
MaxContainerCount : s . MaxContainerCount ,
ClusterDomain : s . ClusterDomain ,
ClusterDNS : s . ClusterDNS ,
Runonce : s . RunOnce ,
Port : s . Port ,
2015-04-02 04:41:32 +00:00
ReadOnlyPort : s . ReadOnlyPort ,
2015-03-10 05:39:00 +00:00
CadvisorInterface : cadvisorInterface ,
2015-01-08 20:41:38 +00:00
EnableServer : s . EnableServer ,
EnableDebuggingHandlers : s . EnableDebuggingHandlers ,
DockerClient : dockertools . ConnectToDockerOrDie ( s . DockerEndpoint ) ,
KubeClient : client ,
MasterServiceNamespace : s . MasterServiceNamespace ,
VolumePlugins : ProbeVolumePlugins ( ) ,
2015-03-19 23:14:13 +00:00
NetworkPlugins : ProbeNetworkPlugins ( ) ,
NetworkPluginName : s . NetworkPluginName ,
2015-01-08 20:41:38 +00:00
StreamingConnectionIdleTimeout : s . StreamingConnectionIdleTimeout ,
2015-04-01 23:19:17 +00:00
TLSOptions : tlsOptions ,
2015-03-16 04:00:46 +00:00
ImageGCPolicy : imageGCPolicy ,
2015-05-12 08:24:08 +00:00
DiskSpacePolicy : diskSpacePolicy ,
2015-03-23 22:31:13 +00:00
Cloud : cloud ,
2015-04-09 08:32:18 +00:00
NodeStatusUpdateFrequency : s . NodeStatusUpdateFrequency ,
2015-04-14 00:30:57 +00:00
ResourceContainer : s . ResourceContainer ,
2015-04-24 00:07:52 +00:00
CgroupRoot : s . CgroupRoot ,
2015-05-01 21:24:07 +00:00
ContainerRuntime : s . ContainerRuntime ,
2015-05-05 15:07:15 +00:00
Mounter : mounter ,
2015-05-12 16:59:02 +00:00
DockerDaemonContainer : s . DockerDaemonContainer ,
2015-02-02 21:30:31 +00:00
}
2015-03-26 12:31:54 +00:00
RunKubelet ( & kcfg , nil )
2015-02-02 21:30:31 +00:00
2015-03-30 21:09:50 +00:00
if s . HealthzPort > 0 {
healthz . DefaultHealthz ( )
go util . Forever ( func ( ) {
err := http . ListenAndServe ( net . JoinHostPort ( s . HealthzBindAddress . String ( ) , strconv . Itoa ( s . HealthzPort ) ) , nil )
if err != nil {
glog . Errorf ( "Starting health server failed: %v" , err )
}
} , 5 * time . Second )
}
2015-02-02 21:30:31 +00:00
// runs forever
select { }
}
2015-01-07 15:18:56 +00:00
// TODO: replace this with clientcmd
2015-02-02 21:30:31 +00:00
func ( s * KubeletServer ) createAPIServerClient ( ) ( * client . Client , error ) {
authInfo , err := clientauth . LoadFromFile ( s . AuthPath )
2015-01-07 15:18:56 +00:00
if err != nil {
2015-01-31 02:07:07 +00:00
glog . Warningf ( "Could not load kubernetes auth path: %v. Continuing with defaults." , err )
}
if authInfo == nil {
// authInfo didn't load correctly - continue with defaults.
authInfo = & clientauth . Info { }
2015-01-07 15:18:56 +00:00
}
clientConfig , err := authInfo . MergeWithConfig ( client . Config { } )
if err != nil {
return nil , err
}
2015-02-02 21:30:31 +00:00
if len ( s . APIServerList ) < 1 {
return nil , fmt . Errorf ( "no api servers specified" )
2015-01-07 15:18:56 +00:00
}
// TODO: adapt Kube client to support LB over several servers
2015-02-02 21:30:31 +00:00
if len ( s . APIServerList ) > 1 {
2015-01-18 07:32:34 +00:00
glog . Infof ( "Multiple api servers specified. Picking first one" )
2015-01-07 15:18:56 +00:00
}
2015-02-02 21:30:31 +00:00
clientConfig . Host = s . APIServerList [ 0 ]
2015-04-11 16:45:45 +00:00
s . addChaosToClientConfig ( & clientConfig )
2015-01-07 15:18:56 +00:00
c , err := client . New ( & clientConfig )
if err != nil {
return nil , err
}
return c , nil
}
2015-04-11 16:45:45 +00:00
// addChaosToClientConfig injects random errors into client connections if configured.
func ( s * KubeletServer ) addChaosToClientConfig ( config * client . Config ) {
if s . ChaosChance != 0.0 {
config . WrapTransport = func ( rt http . RoundTripper ) http . RoundTripper {
seed := chaosclient . NewSeed ( 1 )
// TODO: introduce a standard chaos package with more tunables - this is just a proof of concept
// TODO: introduce random latency and stalls
return chaosclient . NewChaosRoundTripper ( rt , chaosclient . LogChaos , seed . P ( s . ChaosChance , chaosclient . ErrSimulatedConnectionResetByPeer ) )
}
}
}
2015-03-11 23:40:20 +00:00
// SimpleRunKubelet is a simple way to start a Kubelet talking to dockerEndpoint, using an API Client.
2014-11-27 21:28:56 +00:00
// Under the hood it calls RunKubelet (below)
2015-03-23 03:02:18 +00:00
func SimpleKubelet ( client * client . Client ,
2015-01-08 15:25:14 +00:00
dockerClient dockertools . DockerInterface ,
hostname , rootDir , manifestURL , address string ,
port uint ,
2014-11-23 15:47:25 +00:00
masterServiceNamespace string ,
2015-03-19 05:18:31 +00:00
volumePlugins [ ] volume . VolumePlugin ,
2015-03-10 05:39:00 +00:00
tlsOptions * kubelet . TLSOptions ,
2015-03-09 22:46:47 +00:00
cadvisorInterface cadvisor . Interface ,
2015-03-23 22:31:13 +00:00
configFilePath string ,
2015-04-21 00:26:40 +00:00
cloud cloudprovider . Interface ,
2015-04-27 20:03:55 +00:00
osInterface kubecontainer . OSInterface ) * KubeletConfig {
2015-03-16 04:00:46 +00:00
imageGCPolicy := kubelet . ImageGCPolicy {
HighThresholdPercent : 90 ,
LowThresholdPercent : 80 ,
}
2015-05-12 08:24:08 +00:00
diskSpacePolicy := kubelet . DiskSpacePolicy {
DockerFreeDiskMB : 256 ,
RootFreeDiskMB : 256 ,
}
2014-11-27 21:28:56 +00:00
kcfg := KubeletConfig {
2015-01-21 00:59:26 +00:00
KubeClient : client ,
DockerClient : dockerClient ,
HostnameOverride : hostname ,
RootDirectory : rootDir ,
ManifestURL : manifestURL ,
2015-04-09 01:56:58 +00:00
PodInfraContainerImage : dockertools . PodInfraContainerImage ,
2015-03-20 16:37:08 +00:00
Port : port ,
Address : util . IP ( net . ParseIP ( address ) ) ,
EnableServer : true ,
EnableDebuggingHandlers : true ,
HTTPCheckFrequency : 1 * time . Second ,
FileCheckFrequency : 1 * time . Second ,
SyncFrequency : 3 * time . Second ,
MinimumGCAge : 10 * time . Second ,
MaxPerPodContainerCount : 5 ,
MaxContainerCount : 100 ,
MasterServiceNamespace : masterServiceNamespace ,
VolumePlugins : volumePlugins ,
TLSOptions : tlsOptions ,
CadvisorInterface : cadvisorInterface ,
ConfigFile : configFilePath ,
ImageGCPolicy : imageGCPolicy ,
2015-05-12 08:24:08 +00:00
DiskSpacePolicy : diskSpacePolicy ,
2015-03-23 22:31:13 +00:00
Cloud : cloud ,
2015-04-07 19:36:09 +00:00
NodeStatusUpdateFrequency : 10 * time . Second ,
2015-04-14 00:30:57 +00:00
ResourceContainer : "/kubelet" ,
2015-04-21 00:26:40 +00:00
OSInterface : osInterface ,
2015-05-09 00:51:24 +00:00
CgroupRoot : "/" ,
2015-05-01 21:24:07 +00:00
ContainerRuntime : "docker" ,
2015-05-04 14:43:10 +00:00
Mounter : mount . New ( ) ,
2015-05-12 16:59:02 +00:00
DockerDaemonContainer : "/docker-daemon" ,
2014-11-27 21:28:56 +00:00
}
2015-03-23 03:02:18 +00:00
return & kcfg
2014-11-27 21:28:56 +00:00
}
// RunKubelet is responsible for setting up and running a kubelet. It is used in three different applications:
// 1 Integration tests
// 2 Kubelet binary
// 3 Standalone 'kubernetes' binary
// Eventually, #2 will be replaced with instances of #3
2015-03-26 12:31:54 +00:00
func RunKubelet ( kcfg * KubeletConfig , builder KubeletBuilder ) {
2015-01-14 17:36:09 +00:00
kcfg . Hostname = util . GetHostname ( kcfg . HostnameOverride )
2015-03-17 04:03:07 +00:00
eventBroadcaster := record . NewBroadcaster ( )
kcfg . Recorder = eventBroadcaster . NewRecorder ( api . EventSource { Component : "kubelet" , Host : kcfg . Hostname } )
eventBroadcaster . StartLogging ( glog . Infof )
2015-01-07 15:18:56 +00:00
if kcfg . KubeClient != nil {
2015-03-17 04:03:07 +00:00
glog . Infof ( "Sending events to api server." )
eventBroadcaster . StartRecordingToSink ( kcfg . KubeClient . Events ( "" ) )
2015-01-07 15:18:56 +00:00
} else {
2015-03-17 04:03:07 +00:00
glog . Infof ( "No api server defined - no events will be sent to API server." )
2015-01-07 15:18:56 +00:00
}
2015-04-11 17:55:31 +00:00
capabilities . Setup ( kcfg . AllowPrivileged , kcfg . HostNetworkSources )
2014-11-27 21:28:56 +00:00
2015-01-27 20:16:47 +00:00
credentialprovider . SetPreferredDockercfgPath ( kcfg . RootDirectory )
2015-03-26 12:31:54 +00:00
if builder == nil {
builder = createAndInitKubelet
}
2015-04-21 00:26:40 +00:00
if kcfg . OSInterface == nil {
2015-04-27 20:03:55 +00:00
kcfg . OSInterface = kubecontainer . RealOS { }
2015-04-21 00:26:40 +00:00
}
2015-03-26 12:31:54 +00:00
k , podCfg , err := builder ( kcfg )
2015-01-07 02:31:40 +00:00
if err != nil {
glog . Errorf ( "Failed to create kubelet: %s" , err )
return
}
2014-11-27 21:28:56 +00:00
// process pods and exit.
if kcfg . Runonce {
2015-02-02 21:30:31 +00:00
if _ , err := k . RunOnce ( podCfg . Updates ( ) ) ; err != nil {
2014-11-27 21:28:56 +00:00
glog . Errorf ( "--runonce failed: %v" , err )
}
} else {
2015-02-02 21:30:31 +00:00
startKubelet ( k , podCfg , kcfg )
2014-11-27 21:28:56 +00:00
}
2015-04-08 20:57:19 +00:00
glog . Infof ( "Started kubelet" )
2014-11-27 21:28:56 +00:00
}
2015-03-26 12:31:54 +00:00
func startKubelet ( k KubeletBootstrap , podCfg * config . PodConfig , kc * KubeletConfig ) {
2014-11-27 21:28:56 +00:00
// start the kubelet
2015-02-02 21:30:31 +00:00
go util . Forever ( func ( ) { k . Run ( podCfg . Updates ( ) ) } , 0 )
2014-11-27 21:28:56 +00:00
// start the kubelet server
if kc . EnableServer {
go util . Forever ( func ( ) {
2015-03-26 12:31:54 +00:00
k . ListenAndServe ( net . IP ( kc . Address ) , kc . Port , kc . TLSOptions , kc . EnableDebuggingHandlers )
2014-11-27 21:28:56 +00:00
} , 0 )
}
2015-04-02 04:41:32 +00:00
if kc . ReadOnlyPort > 0 {
go util . Forever ( func ( ) {
2015-03-26 12:31:54 +00:00
k . ListenAndServeReadOnly ( net . IP ( kc . Address ) , kc . ReadOnlyPort )
2015-04-02 04:41:32 +00:00
} , 0 )
}
2014-11-27 21:28:56 +00:00
}
func makePodSourceConfig ( kc * KubeletConfig ) * config . PodConfig {
// source of all configuration
2015-03-03 06:06:20 +00:00
cfg := config . NewPodConfig ( config . PodConfigNotificationSnapshotAndUpdates , kc . Recorder )
2014-11-27 21:28:56 +00:00
// define file config source
if kc . ConfigFile != "" {
2014-12-17 05:11:27 +00:00
glog . Infof ( "Adding manifest file: %v" , kc . ConfigFile )
2015-03-23 03:06:12 +00:00
config . NewSourceFile ( kc . ConfigFile , kc . Hostname , kc . FileCheckFrequency , cfg . Channel ( kubelet . FileSource ) )
2014-11-27 21:28:56 +00:00
}
// define url config source
if kc . ManifestURL != "" {
2014-12-17 05:11:27 +00:00
glog . Infof ( "Adding manifest url: %v" , kc . ManifestURL )
2015-03-23 03:06:12 +00:00
config . NewSourceURL ( kc . ManifestURL , kc . Hostname , kc . HTTPCheckFrequency , cfg . Channel ( kubelet . HTTPSource ) )
2014-11-27 21:28:56 +00:00
}
2015-01-17 00:38:09 +00:00
if kc . KubeClient != nil {
2014-11-21 21:14:30 +00:00
glog . Infof ( "Watching apiserver" )
config . NewSourceApiserver ( kc . KubeClient , kc . Hostname , cfg . Channel ( kubelet . ApiserverSource ) )
}
2014-11-27 21:28:56 +00:00
return cfg
}
2015-02-02 21:30:31 +00:00
// KubeletConfig is all of the parameters necessary for running a kubelet.
// TODO: This should probably be merged with KubeletServer. The extra object is a consequence of refactoring.
2014-11-27 21:28:56 +00:00
type KubeletConfig struct {
2015-01-08 20:41:38 +00:00
KubeClient * client . Client
DockerClient dockertools . DockerInterface
2015-03-10 05:39:00 +00:00
CadvisorInterface cadvisor . Interface
2015-01-08 20:41:38 +00:00
Address util . IP
AllowPrivileged bool
2015-03-24 23:09:16 +00:00
HostNetworkSources [ ] string
2015-01-08 20:41:38 +00:00
HostnameOverride string
RootDirectory string
ConfigFile string
ManifestURL string
FileCheckFrequency time . Duration
HTTPCheckFrequency time . Duration
Hostname string
PodInfraContainerImage string
SyncFrequency time . Duration
RegistryPullQPS float64
RegistryBurst int
MinimumGCAge time . Duration
2015-03-14 17:13:20 +00:00
MaxPerPodContainerCount int
2015-01-08 20:41:38 +00:00
MaxContainerCount int
ClusterDomain string
ClusterDNS util . IP
EnableServer bool
EnableDebuggingHandlers bool
Port uint
2015-04-02 04:41:32 +00:00
ReadOnlyPort uint
2015-01-08 20:41:38 +00:00
Runonce bool
MasterServiceNamespace string
2015-03-19 05:18:31 +00:00
VolumePlugins [ ] volume . VolumePlugin
2015-03-19 23:14:13 +00:00
NetworkPlugins [ ] network . NetworkPlugin
NetworkPluginName string
2015-01-08 20:41:38 +00:00
StreamingConnectionIdleTimeout time . Duration
2015-03-03 06:06:20 +00:00
Recorder record . EventRecorder
2015-03-05 21:30:52 +00:00
TLSOptions * kubelet . TLSOptions
2015-03-16 04:00:46 +00:00
ImageGCPolicy kubelet . ImageGCPolicy
2015-05-12 08:24:08 +00:00
DiskSpacePolicy kubelet . DiskSpacePolicy
2015-03-23 22:31:13 +00:00
Cloud cloudprovider . Interface
2015-03-31 11:17:12 +00:00
NodeStatusUpdateFrequency time . Duration
2015-04-14 00:30:57 +00:00
ResourceContainer string
2015-04-27 20:03:55 +00:00
OSInterface kubecontainer . OSInterface
2015-04-24 00:07:52 +00:00
CgroupRoot string
2015-05-01 21:24:07 +00:00
ContainerRuntime string
2015-05-04 14:43:10 +00:00
Mounter mount . Interface
2015-05-12 16:59:02 +00:00
DockerDaemonContainer string
2014-11-27 21:28:56 +00:00
}
2015-03-26 12:31:54 +00:00
func createAndInitKubelet ( kc * KubeletConfig ) ( k KubeletBootstrap , pc * config . PodConfig , err error ) {
2014-11-27 21:28:56 +00:00
// TODO: block until all sources have delivered at least one update to the channel, or break the sync loop
// up into "per source" synchronizations
2015-02-27 18:44:44 +00:00
// TODO: KubeletConfig.KubeClient should be a client interface, but client interface misses certain methods
// used by kubelet. Since NewMainKubelet expects a client interface, we need to make sure we are not passing
// a nil pointer to it when what we really want is a nil interface.
var kubeClient client . Interface
2015-03-26 12:31:54 +00:00
if kc . KubeClient != nil {
2015-02-27 18:44:44 +00:00
kubeClient = kc . KubeClient
}
2015-03-06 07:56:30 +00:00
2015-03-14 17:13:20 +00:00
gcPolicy := kubelet . ContainerGCPolicy {
MinAge : kc . MinimumGCAge ,
MaxPerPodContainer : kc . MaxPerPodContainerCount ,
MaxContainers : kc . MaxContainerCount ,
}
2015-03-26 12:31:54 +00:00
pc = makePodSourceConfig ( kc )
k , err = kubelet . NewMainKubelet (
2014-11-27 21:28:56 +00:00
kc . Hostname ,
kc . DockerClient ,
2015-02-27 18:44:44 +00:00
kubeClient ,
2014-11-27 21:28:56 +00:00
kc . RootDirectory ,
2015-01-21 00:59:26 +00:00
kc . PodInfraContainerImage ,
2014-11-27 21:28:56 +00:00
kc . SyncFrequency ,
float32 ( kc . RegistryPullQPS ) ,
kc . RegistryBurst ,
2015-03-14 17:13:20 +00:00
gcPolicy ,
2015-03-05 18:49:36 +00:00
pc . SeenAllSources ,
2014-11-12 05:21:40 +00:00
kc . ClusterDomain ,
2015-01-08 15:25:14 +00:00
net . IP ( kc . ClusterDNS ) ,
2014-11-23 15:47:25 +00:00
kc . MasterServiceNamespace ,
2015-01-08 20:41:38 +00:00
kc . VolumePlugins ,
2015-03-19 23:14:13 +00:00
kc . NetworkPlugins ,
kc . NetworkPluginName ,
2015-03-03 06:06:20 +00:00
kc . StreamingConnectionIdleTimeout ,
2015-03-06 07:56:30 +00:00
kc . Recorder ,
2015-03-10 05:39:00 +00:00
kc . CadvisorInterface ,
2015-03-23 22:31:13 +00:00
kc . ImageGCPolicy ,
2015-05-12 08:24:08 +00:00
kc . DiskSpacePolicy ,
2015-03-31 11:17:12 +00:00
kc . Cloud ,
2015-04-14 00:30:57 +00:00
kc . NodeStatusUpdateFrequency ,
2015-04-21 00:26:40 +00:00
kc . ResourceContainer ,
2015-04-24 00:07:52 +00:00
kc . OSInterface ,
2015-05-01 21:24:07 +00:00
kc . CgroupRoot ,
2015-05-04 14:43:10 +00:00
kc . ContainerRuntime ,
2015-05-12 16:59:02 +00:00
kc . Mounter ,
kc . DockerDaemonContainer )
2014-11-27 21:28:56 +00:00
2015-01-07 02:31:40 +00:00
if err != nil {
2015-03-26 12:31:54 +00:00
return nil , nil , err
2015-01-07 02:31:40 +00:00
}
2014-11-27 21:28:56 +00:00
k . BirthCry ( )
2015-03-16 04:00:46 +00:00
k . StartGarbageCollection ( )
2014-10-27 17:04:39 +00:00
2015-03-26 12:31:54 +00:00
return k , pc , nil
2014-10-27 17:04:39 +00:00
}