Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
77be271e
Commit
77be271e
authored
Sep 22, 2015
by
Vishnu kannan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Linux container manager initialization will now fail if cpu and memory cgroups are not mounted.
parent
a518a273
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
217 additions
and
35 deletions
+217
-35
container_manager_linux.go
pkg/kubelet/container_manager_linux.go
+86
-31
container_manager_linux_test.go
pkg/kubelet/container_manager_linux_test.go
+125
-0
container_manager_unsupported.go
pkg/kubelet/container_manager_unsupported.go
+2
-1
kubelet.go
pkg/kubelet/kubelet.go
+2
-1
kubelet_test.go
pkg/kubelet/kubelet_test.go
+1
-1
runonce_test.go
pkg/kubelet/runonce_test.go
+1
-1
No files found.
pkg/kubelet/container_manager_linux.go
View file @
77be271e
...
@@ -35,7 +35,9 @@ import (
...
@@ -35,7 +35,9 @@ import (
"k8s.io/kubernetes/pkg/kubelet/cadvisor"
"k8s.io/kubernetes/pkg/kubelet/cadvisor"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/util/oom"
"k8s.io/kubernetes/pkg/util/oom"
"k8s.io/kubernetes/pkg/util/sets"
)
)
const
(
const
(
...
@@ -70,23 +72,84 @@ func newSystemContainer(containerName string) *systemContainer {
...
@@ -70,23 +72,84 @@ func newSystemContainer(containerName string) *systemContainer {
}
}
}
}
type
nodeConfig
struct
{
dockerDaemonContainerName
string
systemContainerName
string
kubeletContainerName
string
}
type
containerManagerImpl
struct
{
type
containerManagerImpl
struct
{
cadvisorInterface
cadvisor
.
Interface
mountUtil
mount
.
Interface
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.
// As of now, only 'cpu' and 'memory' are required.
func
validateSystemRequirements
(
mountUtil
mount
.
Interface
)
error
{
const
(
cgroupMountType
=
"cgroup"
localErr
=
"system validation failed"
)
mountPoints
,
err
:=
mountUtil
.
List
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"%s - %v"
,
localErr
,
err
)
}
expectedCgroups
:=
sets
.
NewString
(
"cpu"
,
"cpuacct"
,
"cpuset"
,
"memory"
)
for
_
,
mountPoint
:=
range
mountPoints
{
if
mountPoint
.
Type
==
cgroupMountType
{
for
_
,
opt
:=
range
mountPoint
.
Opts
{
if
expectedCgroups
.
Has
(
opt
)
{
expectedCgroups
.
Delete
(
opt
)
}
}
}
}
if
expectedCgroups
.
Len
()
>
0
{
return
fmt
.
Errorf
(
"%s - Following Cgroup subsystem not mounted: %v"
,
localErr
,
expectedCgroups
.
List
())
}
return
nil
}
// 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
(
cadvisorInterface
cadvisor
.
Interface
,
dockerDaemonContainerName
,
systemContainerName
,
kubeletContainerName
string
)
(
containerManager
,
error
)
{
func
newContainerManager
(
mountUtil
mount
.
Interface
,
cadvisorInterface
cadvisor
.
Interface
,
dockerDaemonContainerName
,
systemContainerName
,
kubeletContainerName
string
)
(
containerManager
,
error
)
{
systemContainers
:=
[]
*
systemContainer
{}
return
&
containerManagerImpl
{
cadvisorInterface
:
cadvisorInterface
,
mountUtil
:
mountUtil
,
nodeConfig
:
nodeConfig
{
dockerDaemonContainerName
:
dockerDaemonContainerName
,
systemContainerName
:
systemContainerName
,
kubeletContainerName
:
kubeletContainerName
,
},
},
nil
}
if
dockerDaemonContainerName
!=
""
{
// Create a cgroup container manager.
cont
:=
newSystemContainer
(
dockerDaemonContainerName
)
func
createManager
(
containerName
string
)
*
fs
.
Manager
{
return
&
fs
.
Manager
{
Cgroups
:
&
configs
.
Cgroup
{
Name
:
containerName
,
AllowAllDevices
:
true
,
},
}
}
info
,
err
:=
cadvisorInterface
.
MachineInfo
()
func
(
cm
*
containerManagerImpl
)
setupNode
()
error
{
if
err
:=
validateSystemRequirements
(
cm
.
mountUtil
);
err
!=
nil
{
return
err
}
systemContainers
:=
[]
*
systemContainer
{}
if
cm
.
dockerDaemonContainerName
!=
""
{
cont
:=
newSystemContainer
(
cm
.
dockerDaemonContainerName
)
info
,
err
:=
cm
.
cadvisorInterface
.
MachineInfo
()
var
capacity
=
api
.
ResourceList
{}
var
capacity
=
api
.
ResourceList
{}
if
err
!=
nil
{
if
err
!=
nil
{
}
else
{
}
else
{
...
@@ -94,29 +157,29 @@ func newContainerManager(cadvisorInterface cadvisor.Interface, dockerDaemonConta
...
@@ -94,29 +157,29 @@ func newContainerManager(cadvisorInterface cadvisor.Interface, dockerDaemonConta
}
}
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
,
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"
,
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
:
dockerDaemonContainerName
,
Name
:
cm
.
dockerDaemonContainerName
,
Memory
:
memoryLimit
,
Memory
:
memoryLimit
,
MemorySwap
:
-
1
,
MemorySwap
:
-
1
,
AllowAllDevices
:
true
,
AllowAllDevices
:
true
,
},
},
}
}
cont
.
ensureStateFunc
=
func
(
manager
*
fs
.
Manager
)
error
{
cont
.
ensureStateFunc
=
func
(
manager
*
fs
.
Manager
)
error
{
return
ensureDockerInContainer
(
cadvisorInterface
,
-
900
,
dockerContainer
)
return
ensureDockerInContainer
(
c
m
.
c
advisorInterface
,
-
900
,
dockerContainer
)
}
}
systemContainers
=
append
(
systemContainers
,
cont
)
systemContainers
=
append
(
systemContainers
,
cont
)
}
}
if
systemContainerName
!=
""
{
if
cm
.
systemContainerName
!=
""
{
if
systemContainerName
==
"/"
{
if
cm
.
systemContainerName
==
"/"
{
return
nil
,
fmt
.
Errorf
(
"system container cannot be root (
\"
/
\"
)"
)
return
fmt
.
Errorf
(
"system container cannot be root (
\"
/
\"
)"
)
}
}
rootContainer
:=
&
fs
.
Manager
{
rootContainer
:=
&
fs
.
Manager
{
...
@@ -124,35 +187,27 @@ func newContainerManager(cadvisorInterface cadvisor.Interface, dockerDaemonConta
...
@@ -124,35 +187,27 @@ func newContainerManager(cadvisorInterface cadvisor.Interface, dockerDaemonConta
Name
:
"/"
,
Name
:
"/"
,
},
},
}
}
manager
:=
createManager
(
systemContainerName
)
manager
:=
createManager
(
cm
.
systemContainerName
)
err
:=
ensureSystemContainer
(
rootContainer
,
manager
)
err
:=
ensureSystemContainer
(
rootContainer
,
manager
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
err
}
}
systemContainers
=
append
(
systemContainers
,
newSystemContainer
(
systemContainerName
))
systemContainers
=
append
(
systemContainers
,
newSystemContainer
(
cm
.
systemContainerName
))
}
if
kubeletContainerName
!=
""
{
systemContainers
=
append
(
systemContainers
,
newSystemContainer
(
kubeletContainerName
))
}
}
return
&
containerManagerImpl
{
if
cm
.
kubeletContainerName
!=
""
{
systemContainers
:
systemContainers
,
systemContainers
=
append
(
systemContainers
,
newSystemContainer
(
cm
.
kubeletContainerName
))
},
nil
}
// Create a cgroup container manager.
func
createManager
(
containerName
string
)
*
fs
.
Manager
{
return
&
fs
.
Manager
{
Cgroups
:
&
configs
.
Cgroup
{
Name
:
containerName
,
AllowAllDevices
:
true
,
},
}
}
cm
.
systemContainers
=
systemContainers
return
nil
}
}
func
(
cm
*
containerManagerImpl
)
Start
()
error
{
func
(
cm
*
containerManagerImpl
)
Start
()
error
{
// Setup the node
if
err
:=
cm
.
setupNode
();
err
!=
nil
{
return
err
}
// Don't run a background thread if there are no ensureStateFuncs.
// Don't run a background thread if there are no ensureStateFuncs.
numEnsureStateFuncs
:=
0
numEnsureStateFuncs
:=
0
for
_
,
cont
:=
range
cm
.
systemContainers
{
for
_
,
cont
:=
range
cm
.
systemContainers
{
...
...
pkg/kubelet/container_manager_linux_test.go
0 → 100644
View file @
77be271e
// +build linux
/*
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
kubelet
import
(
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"k8s.io/kubernetes/pkg/util/mount"
)
type
fakeMountInterface
struct
{
mountPoints
[]
mount
.
MountPoint
}
func
(
mi
*
fakeMountInterface
)
Mount
(
source
string
,
target
string
,
fstype
string
,
options
[]
string
)
error
{
return
fmt
.
Errorf
(
"unsupported"
)
}
func
(
mi
*
fakeMountInterface
)
Unmount
(
target
string
)
error
{
return
fmt
.
Errorf
(
"unsupported"
)
}
func
(
mi
*
fakeMountInterface
)
List
()
([]
mount
.
MountPoint
,
error
)
{
return
mi
.
mountPoints
,
nil
}
func
(
mi
*
fakeMountInterface
)
IsLikelyNotMountPoint
(
file
string
)
(
bool
,
error
)
{
return
false
,
fmt
.
Errorf
(
"unsupported"
)
}
func
fakeContainerMgrMountInt
()
mount
.
Interface
{
return
&
fakeMountInterface
{
[]
mount
.
MountPoint
{
{
Device
:
"cgroup"
,
Type
:
"cgroup"
,
Opts
:
[]
string
{
"rw"
,
"relatime"
,
"cpuset"
},
},
{
Device
:
"cgroup"
,
Type
:
"cgroup"
,
Opts
:
[]
string
{
"rw"
,
"relatime"
,
"cpu"
},
},
{
Device
:
"cgroup"
,
Type
:
"cgroup"
,
Opts
:
[]
string
{
"rw"
,
"relatime"
,
"cpuacct"
},
},
{
Device
:
"cgroup"
,
Type
:
"cgroup"
,
Opts
:
[]
string
{
"rw"
,
"relatime"
,
"memory"
},
},
},
}
}
func
TestCgroupMountValidationSuccess
(
t
*
testing
.
T
)
{
assert
.
Nil
(
t
,
validateSystemRequirements
(
fakeContainerMgrMountInt
()))
}
func
TestCgroupMountValidationMemoryMissing
(
t
*
testing
.
T
)
{
mountInt
:=
&
fakeMountInterface
{
[]
mount
.
MountPoint
{
{
Device
:
"cgroup"
,
Type
:
"cgroup"
,
Opts
:
[]
string
{
"rw"
,
"relatime"
,
"cpuset"
},
},
{
Device
:
"cgroup"
,
Type
:
"cgroup"
,
Opts
:
[]
string
{
"rw"
,
"relatime"
,
"cpu"
},
},
{
Device
:
"cgroup"
,
Type
:
"cgroup"
,
Opts
:
[]
string
{
"rw"
,
"relatime"
,
"cpuacct"
},
},
},
}
assert
.
Error
(
t
,
validateSystemRequirements
(
mountInt
))
}
func
TestCgroupMountValidationMultipleSubsytem
(
t
*
testing
.
T
)
{
mountInt
:=
&
fakeMountInterface
{
[]
mount
.
MountPoint
{
{
Device
:
"cgroup"
,
Type
:
"cgroup"
,
Opts
:
[]
string
{
"rw"
,
"relatime"
,
"cpuset"
,
"memory"
},
},
{
Device
:
"cgroup"
,
Type
:
"cgroup"
,
Opts
:
[]
string
{
"rw"
,
"relatime"
,
"cpu"
},
},
{
Device
:
"cgroup"
,
Type
:
"cgroup"
,
Opts
:
[]
string
{
"rw"
,
"relatime"
,
"cpuacct"
},
},
},
}
assert
.
Nil
(
t
,
validateSystemRequirements
(
mountInt
))
}
pkg/kubelet/container_manager_unsupported.go
View file @
77be271e
...
@@ -23,6 +23,7 @@ import (
...
@@ -23,6 +23,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/kubelet/cadvisor"
"k8s.io/kubernetes/pkg/kubelet/cadvisor"
"k8s.io/kubernetes/pkg/util/mount"
)
)
type
unsupportedContainerManager
struct
{
type
unsupportedContainerManager
struct
{
...
@@ -38,6 +39,6 @@ func (unsupportedContainerManager) SystemContainersLimit() api.ResourceList {
...
@@ -38,6 +39,6 @@ func (unsupportedContainerManager) SystemContainersLimit() api.ResourceList {
return
api
.
ResourceList
{}
return
api
.
ResourceList
{}
}
}
func
newContainerManager
(
cadvisorInterface
cadvisor
.
Interface
,
dockerDaemonContainer
,
systemContainer
,
kubeletContainer
string
)
(
containerManager
,
error
)
{
func
newContainerManager
(
mounter
mount
.
Interface
,
cadvisorInterface
cadvisor
.
Interface
,
dockerDaemonContainer
,
systemContainer
,
kubeletContainer
string
)
(
containerManager
,
error
)
{
return
&
unsupportedContainerManager
{},
nil
return
&
unsupportedContainerManager
{},
nil
}
}
pkg/kubelet/kubelet.go
View file @
77be271e
...
@@ -362,7 +362,7 @@ func NewMainKubelet(
...
@@ -362,7 +362,7 @@ 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
(
cadvisorInterface
,
dockerDaemonContainer
,
systemContainer
,
resourceContainer
)
containerManager
,
err
:=
newContainerManager
(
mounter
,
cadvisorInterface
,
dockerDaemonContainer
,
systemContainer
,
resourceContainer
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to create the Container Manager: %v"
,
err
)
return
nil
,
fmt
.
Errorf
(
"failed to create the Container Manager: %v"
,
err
)
}
}
...
@@ -758,6 +758,7 @@ func (kl *Kubelet) Run(updates <-chan PodUpdate) {
...
@@ -758,6 +758,7 @@ func (kl *Kubelet) Run(updates <-chan PodUpdate) {
// Move Kubelet to a container.
// Move Kubelet to a container.
if
kl
.
resourceContainer
!=
""
{
if
kl
.
resourceContainer
!=
""
{
// Fixme: I need to reside inside ContainerManager interface.
err
:=
util
.
RunInResourceContainer
(
kl
.
resourceContainer
)
err
:=
util
.
RunInResourceContainer
(
kl
.
resourceContainer
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Warningf
(
"Failed to move Kubelet to container %q: %v"
,
kl
.
resourceContainer
,
err
)
glog
.
Warningf
(
"Failed to move Kubelet to container %q: %v"
,
kl
.
resourceContainer
,
err
)
...
...
pkg/kubelet/kubelet_test.go
View file @
77be271e
...
@@ -131,7 +131,7 @@ func newTestKubelet(t *testing.T) *TestKubelet {
...
@@ -131,7 +131,7 @@ func newTestKubelet(t *testing.T) *TestKubelet {
t
:
t
,
t
:
t
,
}
}
kubelet
.
volumeManager
=
newVolumeManager
()
kubelet
.
volumeManager
=
newVolumeManager
()
kubelet
.
containerManager
,
_
=
newContainerManager
(
mockCadvisor
,
""
,
""
,
""
)
kubelet
.
containerManager
,
_
=
newContainerManager
(
fakeContainerMgrMountInt
(),
mockCadvisor
,
""
,
""
,
""
)
kubelet
.
networkConfigured
=
true
kubelet
.
networkConfigured
=
true
fakeClock
:=
&
util
.
FakeClock
{
Time
:
time
.
Now
()}
fakeClock
:=
&
util
.
FakeClock
{
Time
:
time
.
Now
()}
kubelet
.
backOff
=
util
.
NewBackOff
(
time
.
Second
,
time
.
Minute
)
kubelet
.
backOff
=
util
.
NewBackOff
(
time
.
Second
,
time
.
Minute
)
...
...
pkg/kubelet/runonce_test.go
View file @
77be271e
...
@@ -51,7 +51,7 @@ func TestRunOnce(t *testing.T) {
...
@@ -51,7 +51,7 @@ func TestRunOnce(t *testing.T) {
diskSpaceManager
:
diskSpaceManager
,
diskSpaceManager
:
diskSpaceManager
,
containerRuntime
:
fakeRuntime
,
containerRuntime
:
fakeRuntime
,
}
}
kb
.
containerManager
,
_
=
newContainerManager
(
cadvisor
,
""
,
""
,
""
)
kb
.
containerManager
,
_
=
newContainerManager
(
fakeContainerMgrMountInt
(),
cadvisor
,
""
,
""
,
""
)
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
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment