From 76df5471b5330c96e46c55d126dc52c155211c99 Mon Sep 17 00:00:00 2001 From: Joe Beda Date: Mon, 2 Feb 2015 13:30:31 -0800 Subject: [PATCH] Covert the kubelet binary to hyperkube. This leaves `pkg/kubelet/server/server.go` looking a little ugly as there is an extra layer of "config" structs that isn't needed. This is left as a TODO for now. --- cmd/hyperkube/hyperkube.go | 2 + cmd/kubelet/kubelet.go | 135 +--------- cmd/kubernetes/kubernetes.go | 3 +- .../app => pkg/kubelet/server}/plugins.go | 3 +- pkg/kubelet/server/server.go | 230 ++++++++++++++++-- 5 files changed, 226 insertions(+), 147 deletions(-) rename {cmd/kubelet/app => pkg/kubelet/server}/plugins.go (94%) diff --git a/cmd/hyperkube/hyperkube.go b/cmd/hyperkube/hyperkube.go index dc88a14997b..7e7c64f8843 100644 --- a/cmd/hyperkube/hyperkube.go +++ b/cmd/hyperkube/hyperkube.go @@ -23,6 +23,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/controllermanager" "github.com/GoogleCloudPlatform/kubernetes/pkg/hyperkube" + kubelet "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/server" apiserver "github.com/GoogleCloudPlatform/kubernetes/pkg/master/server" sched "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/server" ) @@ -36,6 +37,7 @@ func main() { hk.AddServer(apiserver.NewHyperkubeServer()) hk.AddServer(controllermanager.NewHyperkubeServer()) hk.AddServer(sched.NewHyperkubeServer()) + hk.AddServer(kubelet.NewHyperkubeServer()) hk.RunToExit(os.Args) } diff --git a/cmd/kubelet/kubelet.go b/cmd/kubelet/kubelet.go index 3d637283dd7..a86bfa557e7 100644 --- a/cmd/kubelet/kubelet.go +++ b/cmd/kubelet/kubelet.go @@ -21,145 +21,22 @@ limitations under the License. package main import ( - "math/rand" - "net" - "time" - - "github.com/GoogleCloudPlatform/kubernetes/cmd/kubelet/app" - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider" - _ "github.com/GoogleCloudPlatform/kubernetes/pkg/healthz" - "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet" - kubeletServer "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/server" - "github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports" + "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/server" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/version/verflag" - "github.com/golang/glog" - flag "github.com/spf13/pflag" + "github.com/spf13/pflag" ) -const defaultRootDir = "/var/lib/kubelet" - -var ( - config = flag.String("config", "", "Path to the config file or directory of files") - syncFrequency = flag.Duration("sync_frequency", 10*time.Second, "Max period between synchronizing running containers and config") - fileCheckFrequency = flag.Duration("file_check_frequency", 20*time.Second, "Duration between checking config files for new data") - httpCheckFrequency = flag.Duration("http_check_frequency", 20*time.Second, "Duration between checking http for new data") - manifestURL = flag.String("manifest_url", "", "URL for accessing the container manifest") - enableServer = flag.Bool("enable_server", true, "Enable the info server") - address = util.IP(net.ParseIP("127.0.0.1")) - port = flag.Uint("port", ports.KubeletPort, "The port for the info server to serve on") - hostnameOverride = flag.String("hostname_override", "", "If non-empty, will use this string as identification instead of the actual hostname.") - podInfraContainerImage = flag.String("pod_infra_container_image", kubelet.PodInfraContainerImage, "The image whose network/ipc namespaces containers in each pod will use.") - dockerEndpoint = flag.String("docker_endpoint", "", "If non-empty, use this for the docker endpoint to communicate with") - etcdServerList util.StringList - etcdConfigFile = flag.String("etcd_config", "", "The config file for the etcd client. Mutually exclusive with -etcd_servers") - rootDirectory = flag.String("root_dir", defaultRootDir, "Directory path for managing kubelet files (volume mounts,etc).") - allowPrivileged = flag.Bool("allow_privileged", false, "If true, allow containers to request privileged mode. [default=false]") - registryPullQPS = flag.Float64("registry_qps", 0.0, "If > 0, limit registry pull QPS to this value. If 0, unlimited. [default=0.0]") - registryBurst = flag.Int("registry_burst", 10, "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") - runonce = flag.Bool("runonce", false, "If true, exit after spawning pods from local manifests or remote urls. Exclusive with --etcd_servers, --api_servers, and --enable-server") - enableDebuggingHandlers = flag.Bool("enable_debugging_handlers", true, "Enables server endpoints for log collection and local running of containers and commands") - minimumGCAge = flag.Duration("minimum_container_ttl_duration", 1*time.Minute, "Minimum age for a finished container before it is garbage collected. Examples: '300ms', '10s' or '2h45m'") - maxContainerCount = flag.Int("maximum_dead_containers_per_container", 5, "Maximum number of old instances of a container to retain per container. Each container takes up some disk space. Default: 5.") - authPath = flag.String("auth_path", "", "Path to .kubernetes_auth file, specifying how to authenticate to API server.") - cAdvisorPort = flag.Uint("cadvisor_port", 4194, "The port of the localhost cAdvisor endpoint") - oomScoreAdj = flag.Int("oom_score_adj", -900, "The oom_score_adj value for kubelet process. Values must be within the range [-1000, 1000]") - apiServerList util.StringList - clusterDomain = flag.String("cluster_domain", "", "Domain for this cluster. If set, kubelet will configure all containers to search this domain in addition to the host's search domains") - masterServiceNamespace = flag.String("master_service_namespace", api.NamespaceDefault, "The namespace from which the kubernetes master services should be injected into pods") - clusterDNS = util.IP(nil) - reallyCrashForTesting = flag.Bool("really_crash_for_testing", false, "If true, crash with panics more often.") -) - -func init() { - flag.Var(&etcdServerList, "etcd_servers", "List of etcd servers to watch (http://ip:port), comma separated. Mutually exclusive with -etcd_config") - flag.Var(&address, "address", "The IP address for the info server to serve on (set to 0.0.0.0 for all interfaces)") - flag.Var(&apiServerList, "api_servers", "List of Kubernetes API servers for publishing events, and reading pods and services. (ip:port), comma separated.") - flag.Var(&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") -} - -func setupRunOnce() { - if *runonce { - // Don't use remote (etcd or apiserver) sources - if len(etcdServerList) > 0 { - glog.Fatalf("invalid option: --runonce and --etcd_servers are mutually exclusive") - } - if len(apiServerList) > 0 { - glog.Fatalf("invalid option: --runonce and --api_servers are mutually exclusive") - } - if *enableServer { - glog.Infof("--runonce is set, disabling server") - *enableServer = false - } - } -} - func main() { + s := server.NewKubeletServer() + s.AddFlags(pflag.CommandLine) + util.InitFlags() util.InitLogs() - util.ReallyCrash = *reallyCrashForTesting defer util.FlushLogs() - rand.Seed(time.Now().UTC().UnixNano()) verflag.PrintAndExitIfRequested() - // Cluster creation scripts support both kubernetes versions that 1) support kublet watching - // apiserver for pods, and 2) ones that don't. So they ca set both --etcd_servers and - // --api_servers. The current code will ignore the --etcd_servers flag, while older kubelet - // code will use the --etd_servers flag for pods, and use --api_servers for event publising. - // - // TODO(erictune): convert all cloud provider scripts and Google Container Engine to - // use only --api_servers, then delete --etcd_servers flag and the resulting dead code. - if len(etcdServerList) > 0 && len(apiServerList) > 0 { - glog.Infof("Both --etcd_servers and --api_servers are set. Not using etcd source.") - etcdServerList = util.StringList{} - } - - setupRunOnce() - - if err := util.ApplyOomScoreAdj(*oomScoreAdj); err != nil { - glog.Info(err) - } - - client, err := kubeletServer.GetAPIServerClient(*authPath, apiServerList) - if err != nil && len(apiServerList) > 0 { - glog.Warningf("No API client: %v", err) - } - - credentialprovider.SetPreferredDockercfgPath(*rootDirectory) - - kcfg := kubeletServer.KubeletConfig{ - Address: address, - AllowPrivileged: *allowPrivileged, - HostnameOverride: *hostnameOverride, - RootDirectory: *rootDirectory, - ConfigFile: *config, - ManifestURL: *manifestURL, - FileCheckFrequency: *fileCheckFrequency, - HttpCheckFrequency: *httpCheckFrequency, - PodInfraContainerImage: *podInfraContainerImage, - SyncFrequency: *syncFrequency, - RegistryPullQPS: *registryPullQPS, - RegistryBurst: *registryBurst, - MinimumGCAge: *minimumGCAge, - MaxContainerCount: *maxContainerCount, - ClusterDomain: *clusterDomain, - ClusterDNS: clusterDNS, - Runonce: *runonce, - Port: *port, - CAdvisorPort: *cAdvisorPort, - EnableServer: *enableServer, - EnableDebuggingHandlers: *enableDebuggingHandlers, - DockerClient: util.ConnectToDockerOrDie(*dockerEndpoint), - KubeClient: client, - EtcdClient: kubelet.EtcdClientOrDie(etcdServerList, *etcdConfigFile), - MasterServiceNamespace: *masterServiceNamespace, - VolumePlugins: app.ProbeVolumePlugins(), - } - - kubeletServer.RunKubelet(&kcfg) - // runs forever - select {} + s.Run(pflag.CommandLine.Args()) } diff --git a/cmd/kubernetes/kubernetes.go b/cmd/kubernetes/kubernetes.go index fc592cd9a92..9eb08284f56 100644 --- a/cmd/kubernetes/kubernetes.go +++ b/cmd/kubernetes/kubernetes.go @@ -26,7 +26,6 @@ import ( "net/http" "time" - kubeletapp "github.com/GoogleCloudPlatform/kubernetes/cmd/kubelet/app" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" @@ -141,7 +140,7 @@ func startComponents(etcdClient tools.EtcdClient, cl *client.Client, addr net.IP runControllerManager(machineList, cl, *nodeMilliCPU, *nodeMemory) dockerClient := util.ConnectToDockerOrDie(*dockerEndpoint) - kubeletServer.SimpleRunKubelet(cl, nil, dockerClient, machineList[0], "/tmp/kubernetes", "", "127.0.0.1", 10250, *masterServiceNamespace, kubeletapp.ProbeVolumePlugins()) + kubeletServer.SimpleRunKubelet(cl, nil, dockerClient, machineList[0], "/tmp/kubernetes", "", "127.0.0.1", 10250, *masterServiceNamespace, kubeletServer.ProbeVolumePlugins()) } func newApiClient(addr net.IP, port int) *client.Client { diff --git a/cmd/kubelet/app/plugins.go b/pkg/kubelet/server/plugins.go similarity index 94% rename from cmd/kubelet/app/plugins.go rename to pkg/kubelet/server/plugins.go index a8fc7ed0e6e..7b79851de7b 100644 --- a/cmd/kubelet/app/plugins.go +++ b/pkg/kubelet/server/plugins.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package app +package server // This file exists to force the desired plugin implementations to be linked. import ( @@ -28,6 +28,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/host_path" ) +// ProbeVolumePlugins collects all volume plugins into an easy to use list. func ProbeVolumePlugins() []volume.Plugin { allPlugins := []volume.Plugin{} diff --git a/pkg/kubelet/server/server.go b/pkg/kubelet/server/server.go index a8105ec36df..943e6da99c0 100644 --- a/pkg/kubelet/server/server.go +++ b/pkg/kubelet/server/server.go @@ -14,30 +14,228 @@ See the License for the specific language governing permissions and limitations under the License. */ -// package server makes it easy to create a kubelet server for various contexts. +// Package server makes it easy to create a kubelet server for various contexts. package server import ( "fmt" + "math/rand" "net" "time" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth" "github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider" + _ "github.com/GoogleCloudPlatform/kubernetes/pkg/healthz" + "github.com/GoogleCloudPlatform/kubernetes/pkg/hyperkube" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume" + "github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/golang/glog" + "github.com/spf13/pflag" ) +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 { + Config string + SyncFrequency time.Duration + FileCheckFrequency time.Duration + HTTPCheckFrequency time.Duration + ManifestURL string + EnableServer bool + Address util.IP + Port uint + HostnameOverride string + PodInfraContainerImage string + DockerEndpoint string + EtcdServerList util.StringList + EtcdConfigFile string + RootDirectory string + AllowPrivileged bool + RegistryPullQPS float64 + RegistryBurst int + RunOnce bool + EnableDebuggingHandlers bool + MinimumGCAge time.Duration + MaxContainerCount int + AuthPath string + CAdvisorPort uint + OOMScoreAdj int + APIServerList util.StringList + ClusterDomain string + MasterServiceNamespace string + ClusterDNS util.IP + ReallyCrashForTesting bool +} + +// NewKubeletServer will create a new KubeletServer with default values. +func NewKubeletServer() *KubeletServer { + return &KubeletServer{ + SyncFrequency: 10 * time.Second, + FileCheckFrequency: 20 * time.Second, + HTTPCheckFrequency: 20 * time.Second, + EnableServer: true, + Address: util.IP(net.ParseIP("127.0.0.1")), + Port: ports.KubeletPort, + PodInfraContainerImage: kubelet.PodInfraContainerImage, + RootDirectory: defaultRootDir, + RegistryBurst: 10, + EnableDebuggingHandlers: true, + MinimumGCAge: 1 * time.Minute, + MaxContainerCount: 5, + CAdvisorPort: 4194, + OOMScoreAdj: -900, + MasterServiceNamespace: api.NamespaceDefault, + } +} + +// NewHyperkubeServer creates a new hyperkube Server object that includes the +// description and flags. +func NewHyperkubeServer() *hyperkube.Server { + s := NewKubeletServer() + hks := hyperkube.Server{ + SimpleUsage: "kubelet", + Long: `The kubelet binary is responsible for maintaining a set of containers on a +particular node. It syncs data from a variety of sources including a +Kubernetes API server, an etcd cluster, HTTP endpoint or local file. It then +queries Docker to see what is currently running. It synchronizes the +configuration data, with the running set of containers by starting or stopping +Docker containers.`, + Run: func(_ *hyperkube.Server, args []string) error { + return s.Run(args) + }, + } + s.AddFlags(hks.Flags()) + return &hks +} + +// 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") + 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") + 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") + 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.Var(&s.EtcdServerList, "etcd_servers", "List of etcd servers to watch (http://ip:port), comma separated. Mutually exclusive with -etcd_config") + fs.StringVar(&s.EtcdConfigFile, "etcd_config", s.EtcdConfigFile, "The config file for the etcd client. Mutually exclusive with -etcd_servers") + 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.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") + fs.BoolVar(&s.RunOnce, "runonce", s.RunOnce, "If true, exit after spawning pods from local manifests or remote urls. Exclusive with --etcd_servers, --api_servers, and --enable-server") + 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.MaxContainerCount, "maximum_dead_containers_per_container", s.MaxContainerCount, "Maximum number of old instances of a container to retain per container. Each container takes up some disk space. Default: 5.") + fs.StringVar(&s.AuthPath, "auth_path", s.AuthPath, "Path to .kubernetes_auth file, specifying how to authenticate to API server.") + fs.UintVar(&s.CAdvisorPort, "cadvisor_port", s.CAdvisorPort, "The port of the localhost cAdvisor endpoint") + 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.BoolVar(&s.ReallyCrashForTesting, "really_crash_for_testing", s.ReallyCrashForTesting, "If true, crash with panics more often.") +} + +// 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()) + + // Cluster creation scripts support both kubernetes versions that 1) + // support kublet watching apiserver for pods, and 2) ones that don't. So + // they can set both --etcd_servers and --api_servers. The current code + // will ignore the --etcd_servers flag, while older kubelet code will use + // the --etcd_servers flag for pods, and use --api_servers for event + // publising. + // + // TODO(erictune): convert all cloud provider scripts and Google Container Engine to + // use only --api_servers, then delete --etcd_servers flag and the resulting dead code. + if len(s.EtcdServerList) > 0 && len(s.APIServerList) > 0 { + glog.Infof("Both --etcd_servers and --api_servers are set. Not using etcd source.") + s.EtcdServerList = util.StringList{} + } + + if err := util.ApplyOomScoreAdj(s.OOMScoreAdj); err != nil { + glog.Info(err) + } + + client, err := s.createAPIServerClient() + if err != nil && len(s.APIServerList) > 0 { + glog.Warningf("No API client: %v", err) + } + + credentialprovider.SetPreferredDockercfgPath(s.RootDirectory) + + kcfg := KubeletConfig{ + Address: s.Address, + AllowPrivileged: s.AllowPrivileged, + 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, + MaxContainerCount: s.MaxContainerCount, + ClusterDomain: s.ClusterDomain, + ClusterDNS: s.ClusterDNS, + Runonce: s.RunOnce, + Port: s.Port, + CAdvisorPort: s.CAdvisorPort, + EnableServer: s.EnableServer, + EnableDebuggingHandlers: s.EnableDebuggingHandlers, + DockerClient: util.ConnectToDockerOrDie(s.DockerEndpoint), + KubeClient: client, + EtcdClient: kubelet.EtcdClientOrDie(s.EtcdServerList, s.EtcdConfigFile), + MasterServiceNamespace: s.MasterServiceNamespace, + VolumePlugins: ProbeVolumePlugins(), + } + + RunKubelet(&kcfg) + + // runs forever + select {} + +} + +func (s *KubeletServer) setupRunOnce() { + if s.RunOnce { + // Don't use remote (etcd or apiserver) sources + if len(s.EtcdServerList) > 0 { + glog.Fatalf("invalid option: --runonce and --etcd_servers are mutually exclusive") + } + if len(s.APIServerList) > 0 { + glog.Fatalf("invalid option: --runonce and --api_servers are mutually exclusive") + } + if s.EnableServer { + glog.Infof("--runonce is set, disabling server") + s.EnableServer = false + } + } +} + // TODO: replace this with clientcmd -func GetAPIServerClient(authPath string, apiServerList util.StringList) (*client.Client, error) { - authInfo, err := clientauth.LoadFromFile(authPath) +func (s *KubeletServer) createAPIServerClient() (*client.Client, error) { + authInfo, err := clientauth.LoadFromFile(s.AuthPath) if err != nil { glog.Warningf("Could not load kubernetes auth path: %v. Continuing with defaults.", err) } @@ -49,14 +247,14 @@ func GetAPIServerClient(authPath string, apiServerList util.StringList) (*client if err != nil { return nil, err } - if len(apiServerList) < 1 { - return nil, fmt.Errorf("no api servers specified.") + if len(s.APIServerList) < 1 { + return nil, fmt.Errorf("no api servers specified") } // TODO: adapt Kube client to support LB over several servers - if len(apiServerList) > 1 { + if len(s.APIServerList) > 1 { glog.Infof("Multiple api servers specified. Picking first one") } - clientConfig.Host = apiServerList[0] + clientConfig.Host = s.APIServerList[0] c, err := client.New(&clientConfig) if err != nil { return nil, err @@ -111,25 +309,25 @@ func RunKubelet(kcfg *KubeletConfig) { credentialprovider.SetPreferredDockercfgPath(kcfg.RootDirectory) - cfg := makePodSourceConfig(kcfg) - k, err := createAndInitKubelet(kcfg, cfg) + podCfg := makePodSourceConfig(kcfg) + k, err := createAndInitKubelet(kcfg, podCfg) if err != nil { glog.Errorf("Failed to create kubelet: %s", err) return } // process pods and exit. if kcfg.Runonce { - if _, err := k.RunOnce(cfg.Updates()); err != nil { + if _, err := k.RunOnce(podCfg.Updates()); err != nil { glog.Errorf("--runonce failed: %v", err) } } else { - startKubelet(k, cfg, kcfg) + startKubelet(k, podCfg, kcfg) } } -func startKubelet(k *kubelet.Kubelet, cfg *config.PodConfig, kc *KubeletConfig) { +func startKubelet(k *kubelet.Kubelet, podCfg *config.PodConfig, kc *KubeletConfig) { // start the kubelet - go util.Forever(func() { k.Run(cfg.Updates()) }, 0) + go util.Forever(func() { k.Run(podCfg.Updates()) }, 0) // start the kubelet server if kc.EnableServer { @@ -152,7 +350,7 @@ func makePodSourceConfig(kc *KubeletConfig) *config.PodConfig { // define url config source if kc.ManifestURL != "" { glog.Infof("Adding manifest url: %v", kc.ManifestURL) - config.NewSourceURL(kc.ManifestURL, kc.HttpCheckFrequency, cfg.Channel(kubelet.HTTPSource)) + config.NewSourceURL(kc.ManifestURL, kc.HTTPCheckFrequency, cfg.Channel(kubelet.HTTPSource)) } if kc.EtcdClient != nil { glog.Infof("Watching for etcd configs at %v", kc.EtcdClient.GetCluster()) @@ -165,6 +363,8 @@ func makePodSourceConfig(kc *KubeletConfig) *config.PodConfig { return cfg } +// 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. type KubeletConfig struct { EtcdClient tools.EtcdClient KubeClient *client.Client @@ -177,7 +377,7 @@ type KubeletConfig struct { ConfigFile string ManifestURL string FileCheckFrequency time.Duration - HttpCheckFrequency time.Duration + HTTPCheckFrequency time.Duration Hostname string PodInfraContainerImage string SyncFrequency time.Duration