Move container manager into a separate package.

Inject container manager into Kubelet. This lets us stub out container
manager during integration testing.
This commit is contained in:
Vishnu kannan 2015-10-09 17:09:53 -07:00
parent 129dbc734c
commit 4ad3d6f5fe
16 changed files with 159 additions and 69 deletions

View File

@ -49,6 +49,7 @@ import (
replicationcontroller "k8s.io/kubernetes/pkg/controller/replication" replicationcontroller "k8s.io/kubernetes/pkg/controller/replication"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/kubelet/cadvisor"
"k8s.io/kubernetes/pkg/kubelet/cm"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/dockertools"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
@ -216,7 +217,7 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string
configFilePath := integration.MakeTempDirOrDie("config", testRootDir) configFilePath := integration.MakeTempDirOrDie("config", testRootDir)
glog.Infof("Using %s as root dir for kubelet #1", testRootDir) glog.Infof("Using %s as root dir for kubelet #1", testRootDir)
fakeDocker1.VersionInfo = docker.Env{"ApiVersion=1.20"} fakeDocker1.VersionInfo = docker.Env{"ApiVersion=1.20"}
cm := cm.NewStubContainerManager()
kcfg := kubeletapp.SimpleKubelet( kcfg := kubeletapp.SimpleKubelet(
cl, cl,
&fakeDocker1, &fakeDocker1,
@ -238,7 +239,8 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string
10*time.Second, /* MinimumGCAge */ 10*time.Second, /* MinimumGCAge */
3*time.Second, /* NodeStatusUpdateFrequency */ 3*time.Second, /* NodeStatusUpdateFrequency */
10*time.Second, /* SyncFrequency */ 10*time.Second, /* SyncFrequency */
40 /* MaxPods */) 40, /* MaxPods */
cm)
kubeletapp.RunKubelet(kcfg) kubeletapp.RunKubelet(kcfg)
// Kubelet (machine) // Kubelet (machine)
@ -270,7 +272,8 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string
3*time.Second, /* NodeStatusUpdateFrequency */ 3*time.Second, /* NodeStatusUpdateFrequency */
10*time.Second, /* SyncFrequency */ 10*time.Second, /* SyncFrequency */
40 /* MaxPods */) 40, /* MaxPods */
cm)
kubeletapp.RunKubelet(kcfg) kubeletapp.RunKubelet(kcfg)
return apiServer.URL, configFilePath return apiServer.URL, configFilePath

View File

@ -44,6 +44,7 @@ import (
"k8s.io/kubernetes/pkg/healthz" "k8s.io/kubernetes/pkg/healthz"
"k8s.io/kubernetes/pkg/kubelet" "k8s.io/kubernetes/pkg/kubelet"
"k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/kubelet/cadvisor"
"k8s.io/kubernetes/pkg/kubelet/cm"
"k8s.io/kubernetes/pkg/kubelet/config" "k8s.io/kubernetes/pkg/kubelet/config"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/dockertools"
@ -409,6 +410,7 @@ func (s *KubeletServer) UnsecuredKubeletConfig() (*KubeletConfig, error) {
ClusterDomain: s.ClusterDomain, ClusterDomain: s.ClusterDomain,
ConfigFile: s.Config, ConfigFile: s.Config,
ConfigureCBR0: s.ConfigureCBR0, ConfigureCBR0: s.ConfigureCBR0,
ContainerManager: nil,
ContainerRuntime: s.ContainerRuntime, ContainerRuntime: s.ContainerRuntime,
CPUCFSQuota: s.CPUCFSQuota, CPUCFSQuota: s.CPUCFSQuota,
DiskSpacePolicy: diskSpacePolicy, DiskSpacePolicy: diskSpacePolicy,
@ -474,6 +476,7 @@ func (s *KubeletServer) UnsecuredKubeletConfig() (*KubeletConfig, error) {
// Otherwise, the caller is assumed to have set up the KubeletConfig object and all defaults // Otherwise, the caller is assumed to have set up the KubeletConfig object and all defaults
// will be ignored. // will be ignored.
func (s *KubeletServer) Run(kcfg *KubeletConfig) error { func (s *KubeletServer) Run(kcfg *KubeletConfig) error {
var err error
if kcfg == nil { if kcfg == nil {
cfg, err := s.UnsecuredKubeletConfig() cfg, err := s.UnsecuredKubeletConfig()
if err != nil { if err != nil {
@ -498,11 +501,17 @@ func (s *KubeletServer) Run(kcfg *KubeletConfig) error {
} }
if kcfg.CAdvisorInterface == nil { if kcfg.CAdvisorInterface == nil {
ca, err := cadvisor.New(s.CAdvisorPort) kcfg.CAdvisorInterface, err = cadvisor.New(s.CAdvisorPort)
if err != nil {
return err
}
}
if kcfg.ContainerManager == nil {
kcfg.ContainerManager, err = cm.NewContainerManager(kcfg.Mounter, kcfg.CAdvisorInterface)
if err != nil { if err != nil {
return err return err
} }
kcfg.CAdvisorInterface = ca
} }
util.ReallyCrash = s.ReallyCrashForTesting util.ReallyCrash = s.ReallyCrashForTesting
@ -670,7 +679,7 @@ func SimpleKubelet(client *client.Client,
osInterface kubecontainer.OSInterface, osInterface kubecontainer.OSInterface,
fileCheckFrequency, httpCheckFrequency, minimumGCAge, nodeStatusUpdateFrequency, syncFrequency time.Duration, fileCheckFrequency, httpCheckFrequency, minimumGCAge, nodeStatusUpdateFrequency, syncFrequency time.Duration,
maxPods int, maxPods int,
) *KubeletConfig { containerManager cm.ContainerManager) *KubeletConfig {
imageGCPolicy := kubelet.ImageGCPolicy{ imageGCPolicy := kubelet.ImageGCPolicy{
HighThresholdPercent: 90, HighThresholdPercent: 90,
LowThresholdPercent: 80, LowThresholdPercent: 80,
@ -686,6 +695,7 @@ func SimpleKubelet(client *client.Client,
CgroupRoot: "", CgroupRoot: "",
Cloud: cloud, Cloud: cloud,
ConfigFile: configFilePath, ConfigFile: configFilePath,
ContainerManager: containerManager,
ContainerRuntime: "docker", ContainerRuntime: "docker",
CPUCFSQuota: false, CPUCFSQuota: false,
DiskSpacePolicy: diskSpacePolicy, DiskSpacePolicy: diskSpacePolicy,
@ -724,8 +734,8 @@ func SimpleKubelet(client *client.Client,
SyncFrequency: syncFrequency, SyncFrequency: syncFrequency,
SystemContainer: "", SystemContainer: "",
TLSOptions: tlsOptions, TLSOptions: tlsOptions,
Writer: &io.StdWriter{},
VolumePlugins: volumePlugins, VolumePlugins: volumePlugins,
Writer: &io.StdWriter{},
} }
return &kcfg return &kcfg
} }
@ -864,6 +874,7 @@ type KubeletConfig struct {
ClusterDomain string ClusterDomain string
ConfigFile string ConfigFile string
ConfigureCBR0 bool ConfigureCBR0 bool
ContainerManager cm.ContainerManager
ContainerRuntime string ContainerRuntime string
CPUCFSQuota bool CPUCFSQuota bool
DiskSpacePolicy kubelet.DiskSpacePolicy DiskSpacePolicy kubelet.DiskSpacePolicy
@ -1004,6 +1015,7 @@ func CreateAndInitKubelet(kc *KubeletConfig) (k KubeletBootstrap, pc *config.Pod
daemonEndpoints, daemonEndpoints,
kc.OOMAdjuster, kc.OOMAdjuster,
kc.SerializeImagePulls, kc.SerializeImagePulls,
kc.ContainerManager,
) )
if err != nil { if err != nil {

View File

@ -27,6 +27,7 @@ import (
client "k8s.io/kubernetes/pkg/client/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
"k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/kubelet/cadvisor"
"k8s.io/kubernetes/pkg/kubelet/cm"
"k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/dockertools"
"k8s.io/kubernetes/pkg/kubemark" "k8s.io/kubernetes/pkg/kubemark"
proxyconfig "k8s.io/kubernetes/pkg/proxy/config" proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
@ -93,6 +94,7 @@ func main() {
if config.Morph == "kubelet" { if config.Morph == "kubelet" {
cadvisorInterface := new(cadvisor.Fake) cadvisorInterface := new(cadvisor.Fake)
containerManager := cm.NewStubContainerManager()
fakeDockerClient := &dockertools.FakeDockerClient{} fakeDockerClient := &dockertools.FakeDockerClient{}
fakeDockerClient.VersionInfo = docker.Env{"ApiVersion=1.18"} fakeDockerClient.VersionInfo = docker.Env{"ApiVersion=1.18"}
@ -106,6 +108,7 @@ func main() {
fakeDockerClient, fakeDockerClient,
config.KubeletPort, config.KubeletPort,
config.KubeletReadOnlyPort, config.KubeletReadOnlyPort,
containerManager,
) )
hollowKubelet.Run() hollowKubelet.Run()
} }

View File

@ -36,6 +36,7 @@ import (
client "k8s.io/kubernetes/pkg/client/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/kubelet" "k8s.io/kubernetes/pkg/kubelet"
"k8s.io/kubernetes/pkg/kubelet/cm"
kconfig "k8s.io/kubernetes/pkg/kubelet/config" kconfig "k8s.io/kubernetes/pkg/kubelet/config"
"k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/dockertools"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
@ -151,7 +152,6 @@ func (s *KubeletExecutorServer) runKubelet(execUpdates <-chan kubetypes.PodUpdat
if err != nil { if err != nil {
return k, pc, err return k, pc, err
} }
klet := k.(*kubelet.Kubelet) klet := k.(*kubelet.Kubelet)
s.kletLock.Lock() s.kletLock.Lock()
@ -187,6 +187,11 @@ func (s *KubeletExecutorServer) runKubelet(execUpdates <-chan kubetypes.PodUpdat
return err return err
} }
kcfg.CAdvisorInterface = cAdvisorInterface kcfg.CAdvisorInterface = cAdvisorInterface
kcfg.ContainerManager, err = cm.NewContainerManager(kcfg.Mounter, cAdvisorInterface)
if err != nil {
return err
}
go func() { go func() {
for ni := range nodeInfos { for ni := range nodeInfos {
// TODO(sttts): implement with MachineAllocable mechanism when https://github.com/kubernetes/kubernetes/issues/13984 is finished // TODO(sttts): implement with MachineAllocable mechanism when https://github.com/kubernetes/kubernetes/issues/13984 is finished

View File

@ -0,0 +1,35 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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 cadvisor
import (
cadvisorApi "github.com/google/cadvisor/info/v1"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource"
)
func CapacityFromMachineInfo(info *cadvisorApi.MachineInfo) api.ResourceList {
c := api.ResourceList{
api.ResourceCPU: *resource.NewMilliQuantity(
int64(info.NumCores*1000),
resource.DecimalSI),
api.ResourceMemory: *resource.NewQuantity(
info.MemoryCapacity,
resource.BinarySI),
}
return c
}

View File

@ -14,20 +14,26 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubelet package cm
import ( import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
) )
// Manages the containers running on a machine. // Manages the containers running on a machine.
type containerManager interface { type ContainerManager interface {
// Runs the container manager's housekeeping. // Runs the container manager's housekeeping.
// - Ensures that the Docker daemon is in a container. // - Ensures that the Docker daemon is in a container.
// - Creates the system container where all non-containerized processes run. // - Creates the system container where all non-containerized processes run.
Start() error Start(NodeConfig) error
// Returns resources allocated to system containers in the machine. // Returns resources allocated to system containers in the machine.
// These containers include the system and Kubernetes services. // These containers include the system and Kubernetes services.
SystemContainersLimit() api.ResourceList SystemContainersLimit() api.ResourceList
} }
type NodeConfig struct {
DockerDaemonContainerName string
SystemContainerName string
KubeletContainerName string
}

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubelet package cm
import ( import (
"fmt" "fmt"
@ -73,21 +73,15 @@ func newSystemContainer(containerName string) *systemContainer {
} }
} }
type nodeConfig struct {
dockerDaemonContainerName string
systemContainerName string
kubeletContainerName string
}
type containerManagerImpl struct { type containerManagerImpl struct {
cadvisorInterface cadvisor.Interface cadvisorInterface cadvisor.Interface
mountUtil mount.Interface mountUtil mount.Interface
nodeConfig NodeConfig
// External containers being managed. // External containers being managed.
systemContainers []*systemContainer systemContainers []*systemContainer
} }
var _ containerManager = &containerManagerImpl{} var _ ContainerManager = &containerManagerImpl{}
// checks if the required cgroups subsystems are mounted. // checks if the required cgroups subsystems are mounted.
// As of now, only 'cpu' and 'memory' are required. // As of now, only 'cpu' and 'memory' are required.
@ -120,15 +114,11 @@ func validateSystemRequirements(mountUtil mount.Interface) error {
// TODO(vmarmol): Add limits to the system containers. // TODO(vmarmol): Add limits to the system containers.
// Takes the absolute name of the specified containers. // Takes the absolute name of the specified containers.
// Empty container name disables use of the specified container. // Empty container name disables use of the specified container.
func newContainerManager(mountUtil mount.Interface, cadvisorInterface cadvisor.Interface, dockerDaemonContainerName, systemContainerName, kubeletContainerName string) (containerManager, error) { func NewContainerManager(mountUtil mount.Interface, cadvisorInterface cadvisor.Interface) (ContainerManager, error) {
return &containerManagerImpl{ return &containerManagerImpl{
cadvisorInterface: cadvisorInterface, cadvisorInterface: cadvisorInterface,
mountUtil: mountUtil, mountUtil: mountUtil,
nodeConfig: nodeConfig{ NodeConfig: NodeConfig{},
dockerDaemonContainerName: dockerDaemonContainerName,
systemContainerName: systemContainerName,
kubeletContainerName: kubeletContainerName,
},
}, nil }, nil
} }
@ -197,26 +187,26 @@ func (cm *containerManagerImpl) setupNode() error {
} }
systemContainers := []*systemContainer{} systemContainers := []*systemContainer{}
if cm.dockerDaemonContainerName != "" { if cm.DockerDaemonContainerName != "" {
cont := newSystemContainer(cm.dockerDaemonContainerName) cont := newSystemContainer(cm.DockerDaemonContainerName)
info, err := cm.cadvisorInterface.MachineInfo() info, err := cm.cadvisorInterface.MachineInfo()
var capacity = api.ResourceList{} var capacity = api.ResourceList{}
if err != nil { if err != nil {
} else { } else {
capacity = CapacityFromMachineInfo(info) capacity = cadvisor.CapacityFromMachineInfo(info)
} }
memoryLimit := (int64(capacity.Memory().Value() * DockerMemoryLimitThresholdPercent / 100)) memoryLimit := (int64(capacity.Memory().Value() * DockerMemoryLimitThresholdPercent / 100))
if memoryLimit < MinDockerMemoryLimit { if memoryLimit < MinDockerMemoryLimit {
glog.Warningf("Memory limit %d for container %s is too small, reset it to %d", memoryLimit, cm.dockerDaemonContainerName, MinDockerMemoryLimit) glog.Warningf("Memory limit %d for container %s is too small, reset it to %d", memoryLimit, cm.DockerDaemonContainerName, MinDockerMemoryLimit)
memoryLimit = MinDockerMemoryLimit memoryLimit = MinDockerMemoryLimit
} }
glog.V(2).Infof("Configure resource-only container %s with memory limit: %d", cm.dockerDaemonContainerName, memoryLimit) glog.V(2).Infof("Configure resource-only container %s with memory limit: %d", cm.DockerDaemonContainerName, memoryLimit)
dockerContainer := &fs.Manager{ dockerContainer := &fs.Manager{
Cgroups: &configs.Cgroup{ Cgroups: &configs.Cgroup{
Name: cm.dockerDaemonContainerName, Name: cm.DockerDaemonContainerName,
Memory: memoryLimit, Memory: memoryLimit,
MemorySwap: -1, MemorySwap: -1,
AllowAllDevices: true, AllowAllDevices: true,
@ -228,8 +218,8 @@ func (cm *containerManagerImpl) setupNode() error {
systemContainers = append(systemContainers, cont) systemContainers = append(systemContainers, cont)
} }
if cm.systemContainerName != "" { if cm.SystemContainerName != "" {
if cm.systemContainerName == "/" { if cm.SystemContainerName == "/" {
return fmt.Errorf("system container cannot be root (\"/\")") return fmt.Errorf("system container cannot be root (\"/\")")
} }
@ -238,23 +228,25 @@ func (cm *containerManagerImpl) setupNode() error {
Name: "/", Name: "/",
}, },
} }
manager := createManager(cm.systemContainerName) manager := createManager(cm.SystemContainerName)
err := ensureSystemContainer(rootContainer, manager) err := ensureSystemContainer(rootContainer, manager)
if err != nil { if err != nil {
return err return err
} }
systemContainers = append(systemContainers, newSystemContainer(cm.systemContainerName)) systemContainers = append(systemContainers, newSystemContainer(cm.SystemContainerName))
} }
if cm.kubeletContainerName != "" { if cm.KubeletContainerName != "" {
systemContainers = append(systemContainers, newSystemContainer(cm.kubeletContainerName)) systemContainers = append(systemContainers, newSystemContainer(cm.KubeletContainerName))
} }
cm.systemContainers = systemContainers cm.systemContainers = systemContainers
return nil return nil
} }
func (cm *containerManagerImpl) Start() error { func (cm *containerManagerImpl) Start(nodeConfig NodeConfig) error {
cm.NodeConfig = nodeConfig
// Setup the node // Setup the node
if err := cm.setupNode(); err != nil { if err := cm.setupNode(); err != nil {
return err return err

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubelet package cm
import ( import (
"fmt" "fmt"

View File

@ -0,0 +1,39 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
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 cm
import (
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
)
type containerManagerStub struct{}
var _ ContainerManager = &containerManagerStub{}
func (cm *containerManagerStub) Start(_ NodeConfig) error {
glog.V(2).Infof("Starting stub container manager")
return nil
}
func (cm *containerManagerStub) SystemContainersLimit() api.ResourceList {
return api.ResourceList{}
}
func NewStubContainerManager() ContainerManager {
return &containerManagerStub{}
}

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubelet package cm
import ( import (
"fmt" "fmt"
@ -29,9 +29,9 @@ import (
type unsupportedContainerManager struct { type unsupportedContainerManager struct {
} }
var _ containerManager = &unsupportedContainerManager{} var _ ContainerManager = &unsupportedContainerManager{}
func (unsupportedContainerManager) Start() error { func (unsupportedContainerManager) Start(_ NodeConfig) error {
return fmt.Errorf("Container Manager is unsupported in this build") return fmt.Errorf("Container Manager is unsupported in this build")
} }
@ -39,6 +39,6 @@ func (unsupportedContainerManager) SystemContainersLimit() api.ResourceList {
return api.ResourceList{} return api.ResourceList{}
} }
func newContainerManager(mounter mount.Interface, cadvisorInterface cadvisor.Interface, dockerDaemonContainer, systemContainer, kubeletContainer string) (containerManager, error) { func NewContainerManager(mounter mount.Interface, cadvisorInterface cadvisor.Interface) (ContainerManager, error) {
return &unsupportedContainerManager{}, nil return &unsupportedContainerManager{}, nil
} }

View File

@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubelet package cm
import ( import (
"fmt" "fmt"

View File

@ -48,6 +48,7 @@ import (
"k8s.io/kubernetes/pkg/fieldpath" "k8s.io/kubernetes/pkg/fieldpath"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/kubelet/cadvisor"
"k8s.io/kubernetes/pkg/kubelet/cm"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/dockertools"
"k8s.io/kubernetes/pkg/kubelet/envvars" "k8s.io/kubernetes/pkg/kubelet/envvars"
@ -195,7 +196,9 @@ func NewMainKubelet(
daemonEndpoints *api.NodeDaemonEndpoints, daemonEndpoints *api.NodeDaemonEndpoints,
oomAdjuster *oom.OOMAdjuster, oomAdjuster *oom.OOMAdjuster,
serializeImagePulls bool, serializeImagePulls bool,
containerManager cm.ContainerManager,
) (*Kubelet, error) { ) (*Kubelet, error) {
if rootDirectory == "" { if rootDirectory == "" {
return nil, fmt.Errorf("invalid root directory %q", rootDirectory) return nil, fmt.Errorf("invalid root directory %q", rootDirectory)
} }
@ -302,6 +305,7 @@ func NewMainKubelet(
resolverConfig: resolverConfig, resolverConfig: resolverConfig,
cpuCFSQuota: cpuCFSQuota, cpuCFSQuota: cpuCFSQuota,
daemonEndpoints: daemonEndpoints, daemonEndpoints: daemonEndpoints,
containerManager: containerManager,
} }
if plug, err := network.InitNetworkPlugin(networkPlugins, networkPluginName, &networkHost{klet}); err != nil { if plug, err := network.InitNetworkPlugin(networkPlugins, networkPluginName, &networkHost{klet}); err != nil {
@ -390,12 +394,11 @@ func NewMainKubelet(
// Setup container manager, can fail if the devices hierarchy is not mounted // Setup container manager, can fail if the devices hierarchy is not mounted
// (it is required by Docker however). // (it is required by Docker however).
containerManager, err := newContainerManager(mounter, cadvisorInterface, dockerDaemonContainer, systemContainer, resourceContainer) klet.nodeConfig = cm.NodeConfig{
if err != nil { DockerDaemonContainerName: dockerDaemonContainer,
return nil, fmt.Errorf("failed to create the Container Manager: %v", err) SystemContainerName: systemContainer,
KubeletContainerName: resourceContainer,
} }
klet.containerManager = containerManager
klet.runtimeState.setRuntimeSync(time.Now()) klet.runtimeState.setRuntimeSync(time.Now())
klet.runner = klet.containerRuntime klet.runner = klet.containerRuntime
@ -575,7 +578,8 @@ type Kubelet struct {
writer kubeio.Writer writer kubeio.Writer
// Manager of non-Runtime containers. // Manager of non-Runtime containers.
containerManager containerManager containerManager cm.ContainerManager
nodeConfig cm.NodeConfig
// Whether or not kubelet should take responsibility for keeping cbr0 in // Whether or not kubelet should take responsibility for keeping cbr0 in
// the correct state. // the correct state.
@ -813,7 +817,7 @@ func (kl *Kubelet) preRun() error {
return fmt.Errorf("Failed to start CAdvisor %v", err) return fmt.Errorf("Failed to start CAdvisor %v", err)
} }
if err := kl.containerManager.Start(); err != nil { if err := kl.containerManager.Start(kl.nodeConfig); err != nil {
return fmt.Errorf("Failed to start ContainerManager %v", err) return fmt.Errorf("Failed to start ContainerManager %v", err)
} }
@ -1971,7 +1975,7 @@ func (kl *Kubelet) hasInsufficientfFreeResources(pods []*api.Pod) (bool, bool) {
// TODO: Should we admit the pod when machine info is unavailable? // TODO: Should we admit the pod when machine info is unavailable?
return false, false return false, false
} }
capacity := CapacityFromMachineInfo(info) capacity := cadvisor.CapacityFromMachineInfo(info)
_, notFittingCPU, notFittingMemory := predicates.CheckPodsExceedingFreeResources(pods, capacity) _, notFittingCPU, notFittingMemory := predicates.CheckPodsExceedingFreeResources(pods, capacity)
return len(notFittingCPU) > 0, len(notFittingMemory) > 0 return len(notFittingCPU) > 0, len(notFittingMemory) > 0
} }
@ -2506,7 +2510,7 @@ func (kl *Kubelet) setNodeStatus(node *api.Node) error {
} else { } else {
node.Status.NodeInfo.MachineID = info.MachineID node.Status.NodeInfo.MachineID = info.MachineID
node.Status.NodeInfo.SystemUUID = info.SystemUUID node.Status.NodeInfo.SystemUUID = info.SystemUUID
node.Status.Capacity = CapacityFromMachineInfo(info) node.Status.Capacity = cadvisor.CapacityFromMachineInfo(info)
node.Status.Capacity[api.ResourcePods] = *resource.NewQuantity( node.Status.Capacity[api.ResourcePods] = *resource.NewQuantity(
int64(kl.pods), resource.DecimalSI) int64(kl.pods), resource.DecimalSI)
if node.Status.NodeInfo.BootID != "" && if node.Status.NodeInfo.BootID != "" &&

View File

@ -42,6 +42,7 @@ import (
"k8s.io/kubernetes/pkg/client/record" "k8s.io/kubernetes/pkg/client/record"
"k8s.io/kubernetes/pkg/client/unversioned/testclient" "k8s.io/kubernetes/pkg/client/unversioned/testclient"
"k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/kubelet/cadvisor"
"k8s.io/kubernetes/pkg/kubelet/cm"
"k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/container"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/network" "k8s.io/kubernetes/pkg/kubelet/network"

View File

@ -26,6 +26,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/record" "k8s.io/kubernetes/pkg/client/record"
"k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/kubelet/cadvisor"
"k8s.io/kubernetes/pkg/kubelet/cm"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/network" "k8s.io/kubernetes/pkg/kubelet/network"
kubepod "k8s.io/kubernetes/pkg/kubelet/pod" kubepod "k8s.io/kubernetes/pkg/kubelet/pod"
@ -56,7 +57,7 @@ func TestRunOnce(t *testing.T) {
diskSpaceManager: diskSpaceManager, diskSpaceManager: diskSpaceManager,
containerRuntime: fakeRuntime, containerRuntime: fakeRuntime,
} }
kb.containerManager, _ = newContainerManager(fakeContainerMgrMountInt(), cadvisor, "", "", "") kb.containerManager = cm.NewStubContainerManager()
kb.networkPlugin, _ = network.InitNetworkPlugin([]network.NetworkPlugin{}, "", network.NewFakeHost(nil)) kb.networkPlugin, _ = network.InitNetworkPlugin([]network.NetworkPlugin{}, "", network.NewFakeHost(nil))
if err := kb.setupDataDirs(); err != nil { if err := kb.setupDataDirs(); err != nil {

View File

@ -19,26 +19,12 @@ package kubelet
import ( import (
"fmt" "fmt"
cadvisorapi "github.com/google/cadvisor/info/v1"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/capabilities" "k8s.io/kubernetes/pkg/capabilities"
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/kubernetes/pkg/securitycontext" "k8s.io/kubernetes/pkg/securitycontext"
) )
func CapacityFromMachineInfo(info *cadvisorapi.MachineInfo) api.ResourceList {
c := api.ResourceList{
api.ResourceCPU: *resource.NewMilliQuantity(
int64(info.NumCores*1000),
resource.DecimalSI),
api.ResourceMemory: *resource.NewQuantity(
info.MemoryCapacity,
resource.BinarySI),
}
return c
}
// Check whether we have the capabilities to run the specified pod. // Check whether we have the capabilities to run the specified pod.
func canRunPod(pod *api.Pod) error { func canRunPod(pod *api.Pod) error {
if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork { if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork {

View File

@ -23,6 +23,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
client "k8s.io/kubernetes/pkg/client/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/kubelet/cadvisor" "k8s.io/kubernetes/pkg/kubelet/cadvisor"
"k8s.io/kubernetes/pkg/kubelet/cm"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/dockertools"
"k8s.io/kubernetes/pkg/volume/empty_dir" "k8s.io/kubernetes/pkg/volume/empty_dir"
@ -41,6 +42,7 @@ func NewHollowKubelet(
cadvisorInterface cadvisor.Interface, cadvisorInterface cadvisor.Interface,
dockerClient dockertools.DockerInterface, dockerClient dockertools.DockerInterface,
kubeletPort, kubeletReadOnlyPort int, kubeletPort, kubeletReadOnlyPort int,
containerManager cm.ContainerManager,
) *HollowKubelet { ) *HollowKubelet {
testRootDir := integration.MakeTempDirOrDie("hollow-kubelet.", "") testRootDir := integration.MakeTempDirOrDie("hollow-kubelet.", "")
manifestFilePath := integration.MakeTempDirOrDie("manifest", testRootDir) manifestFilePath := integration.MakeTempDirOrDie("manifest", testRootDir)
@ -69,6 +71,7 @@ func NewHollowKubelet(
10*time.Second, /* NodeStatusUpdateFrequency */ 10*time.Second, /* NodeStatusUpdateFrequency */
10*time.Second, /* SyncFrequency */ 10*time.Second, /* SyncFrequency */
40, /* MaxPods */ 40, /* MaxPods */
containerManager,
), ),
} }
} }