From fb3c351fe1215cad2469d29f6e765166b79c8a8d Mon Sep 17 00:00:00 2001 From: Victor Marmol Date: Mon, 13 Apr 2015 17:30:57 -0700 Subject: [PATCH] Run Kubelet on "/kubelet" container. --- cmd/kubelet/app/server.go | 10 +++++++++- pkg/kubelet/kubelet.go | 18 +++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index 2a7d417ea96..1d5a03d7ebb 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -96,6 +96,7 @@ type KubeletServer struct { TLSPrivateKeyFile string CertDirectory string NodeStatusUpdateFrequency time.Duration + ResourceContainer string // Flags intended for testing @@ -147,6 +148,7 @@ func NewKubeletServer() *KubeletServer { HostNetworkSources: kubelet.FileSource, CertDirectory: "/var/run/kubernetes", NodeStatusUpdateFrequency: 10 * time.Second, + ResourceContainer: "/kubelet", } } @@ -196,6 +198,7 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&s.NetworkPluginName, "network_plugin", s.NetworkPluginName, " 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).") // Flags intended for testing, not recommended used in production environments. fs.BoolVar(&s.ReallyCrashForTesting, "really_crash_for_testing", s.ReallyCrashForTesting, "If true, when panics occur crash. Intended for testing.") @@ -207,6 +210,7 @@ func (s *KubeletServer) Run(_ []string) error { util.ReallyCrash = s.ReallyCrashForTesting rand.Seed(time.Now().UTC().UnixNano()) + // TODO(vmarmol): Do this through container config. if err := util.ApplyOomScoreAdj(0, s.OOMScoreAdj); err != nil { glog.Info(err) } @@ -293,6 +297,7 @@ func (s *KubeletServer) Run(_ []string) error { ImageGCPolicy: imageGCPolicy, Cloud: cloud, NodeStatusUpdateFrequency: s.NodeStatusUpdateFrequency, + ResourceContainer: s.ResourceContainer, } RunKubelet(&kcfg, nil) @@ -412,6 +417,7 @@ func SimpleKubelet(client *client.Client, ImageGCPolicy: imageGCPolicy, Cloud: cloud, NodeStatusUpdateFrequency: 10 * time.Second, + ResourceContainer: "/kubelet", } return &kcfg } @@ -534,6 +540,7 @@ type KubeletConfig struct { ImageGCPolicy kubelet.ImageGCPolicy Cloud cloudprovider.Interface NodeStatusUpdateFrequency time.Duration + ResourceContainer string } func createAndInitKubelet(kc *KubeletConfig) (k KubeletBootstrap, pc *config.PodConfig, err error) { @@ -576,7 +583,8 @@ func createAndInitKubelet(kc *KubeletConfig) (k KubeletBootstrap, pc *config.Pod kc.CadvisorInterface, kc.ImageGCPolicy, kc.Cloud, - kc.NodeStatusUpdateFrequency) + kc.NodeStatusUpdateFrequency, + kc.ResourceContainer) if err != nil { return nil, nil, err diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 9a0d6a7e1ca..f977d29dba5 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -122,7 +122,8 @@ func NewMainKubelet( cadvisorInterface cadvisor.Interface, imageGCPolicy ImageGCPolicy, cloud cloudprovider.Interface, - nodeStatusUpdateFrequency time.Duration) (*Kubelet, error) { + nodeStatusUpdateFrequency time.Duration, + resourceContainer string) (*Kubelet, error) { if rootDirectory == "" { return nil, fmt.Errorf("invalid root directory %q", rootDirectory) } @@ -228,6 +229,7 @@ func NewMainKubelet( nodeRef: nodeRef, containerManager: containerManager, nodeStatusUpdateFrequency: nodeStatusUpdateFrequency, + resourceContainer: resourceContainer, } klet.podManager = newBasicPodManager(klet.kubeClient) @@ -358,6 +360,10 @@ type Kubelet struct { // status. Kubelet may fail to update node status reliablly if the value is too small, // as it takes time to gather all necessary node information. nodeStatusUpdateFrequency time.Duration + + // The name of the resource-only container to run the Kubelet in (empty for no container). + // Name must be absolute. + resourceContainer string } // getRootDir returns the full path to the directory under which kubelet can @@ -536,6 +542,16 @@ func (kl *Kubelet) Run(updates <-chan PodUpdate) { if kl.kubeClient == nil { glog.Warning("No api server defined - no node status update will be sent.") } + + // Move Kubelet to a container. + if kl.resourceContainer != "" { + err := util.RunInResourceContainer(kl.resourceContainer) + if err != nil { + glog.Warningf("Failed to move Kubelet to container %q: %v", kl.resourceContainer, err) + } + glog.Infof("Running in container %q", kl.resourceContainer) + } + go kl.syncNodeStatus() kl.statusManager.Start() kl.syncLoop(updates, kl)