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
960856f4
Commit
960856f4
authored
Feb 16, 2018
by
David Ashpole
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
collect metrics on the /kubepods cgroup on-demand
parent
1a6a01ee
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
141 additions
and
79 deletions
+141
-79
types.go
pkg/kubelet/apis/stats/v1alpha1/types.go
+2
-0
container_manager.go
pkg/kubelet/cm/container_manager.go
+3
-0
container_manager_linux.go
pkg/kubelet/cm/container_manager_linux.go
+5
-0
container_manager_stub.go
pkg/kubelet/cm/container_manager_stub.go
+4
-0
eviction_manager.go
pkg/kubelet/eviction/eviction_manager.go
+9
-9
eviction_manager_test.go
pkg/kubelet/eviction/eviction_manager_test.go
+0
-0
helpers.go
pkg/kubelet/eviction/helpers.go
+41
-44
helpers_test.go
pkg/kubelet/eviction/helpers_test.go
+14
-6
types.go
pkg/kubelet/eviction/types.go
+1
-9
kubelet.go
pkg/kubelet/kubelet.go
+1
-1
kubelet_getters.go
pkg/kubelet/kubelet_getters.go
+5
-0
server_test.go
pkg/kubelet/server/server_test.go
+1
-0
handler.go
pkg/kubelet/server/stats/handler.go
+3
-0
summary.go
pkg/kubelet/server/stats/summary.go
+12
-8
summary_test.go
pkg/kubelet/server/stats/summary_test.go
+14
-2
mock_stats_provider.go
pkg/kubelet/server/stats/testing/mock_stats_provider.go
+14
-0
summary_test.go
test/e2e_node/summary_test.go
+12
-0
No files found.
pkg/kubelet/apis/stats/v1alpha1/types.go
View file @
960856f4
...
@@ -87,6 +87,8 @@ const (
...
@@ -87,6 +87,8 @@ const (
SystemContainerRuntime
=
"runtime"
SystemContainerRuntime
=
"runtime"
// SystemContainerMisc is the container name for the system container tracking non-kubernetes processes.
// SystemContainerMisc is the container name for the system container tracking non-kubernetes processes.
SystemContainerMisc
=
"misc"
SystemContainerMisc
=
"misc"
// SystemContainerPods is the container name for the system container tracking user pods.
SystemContainerPods
=
"pods"
)
)
// PodStats holds pod-level unprocessed sample stats.
// PodStats holds pod-level unprocessed sample stats.
...
...
pkg/kubelet/cm/container_manager.go
View file @
960856f4
...
@@ -91,6 +91,9 @@ type ContainerManager interface {
...
@@ -91,6 +91,9 @@ type ContainerManager interface {
UpdatePluginResources
(
*
schedulercache
.
NodeInfo
,
*
lifecycle
.
PodAdmitAttributes
)
error
UpdatePluginResources
(
*
schedulercache
.
NodeInfo
,
*
lifecycle
.
PodAdmitAttributes
)
error
InternalContainerLifecycle
()
InternalContainerLifecycle
InternalContainerLifecycle
()
InternalContainerLifecycle
// GetPodCgroupRoot returns the cgroup which contains all pods.
GetPodCgroupRoot
()
string
}
}
type
NodeConfig
struct
{
type
NodeConfig
struct
{
...
...
pkg/kubelet/cm/container_manager_linux.go
View file @
960856f4
...
@@ -500,6 +500,11 @@ func (cm *containerManagerImpl) GetNodeConfig() NodeConfig {
...
@@ -500,6 +500,11 @@ func (cm *containerManagerImpl) GetNodeConfig() NodeConfig {
return
cm
.
NodeConfig
return
cm
.
NodeConfig
}
}
// GetPodCgroupRoot returns the literal cgroupfs value for the cgroup containing all pods.
func
(
cm
*
containerManagerImpl
)
GetPodCgroupRoot
()
string
{
return
cm
.
cgroupManager
.
Name
(
CgroupName
(
cm
.
cgroupRoot
))
}
func
(
cm
*
containerManagerImpl
)
GetMountedSubsystems
()
*
CgroupSubsystems
{
func
(
cm
*
containerManagerImpl
)
GetMountedSubsystems
()
*
CgroupSubsystems
{
return
cm
.
subsystems
return
cm
.
subsystems
}
}
...
...
pkg/kubelet/cm/container_manager_stub.go
View file @
960856f4
...
@@ -90,6 +90,10 @@ func (cm *containerManagerStub) InternalContainerLifecycle() InternalContainerLi
...
@@ -90,6 +90,10 @@ func (cm *containerManagerStub) InternalContainerLifecycle() InternalContainerLi
return
&
internalContainerLifecycleImpl
{
cpumanager
.
NewFakeManager
()}
return
&
internalContainerLifecycleImpl
{
cpumanager
.
NewFakeManager
()}
}
}
func
(
cm
*
containerManagerStub
)
GetPodCgroupRoot
()
string
{
return
""
}
func
NewStubContainerManager
()
ContainerManager
{
func
NewStubContainerManager
()
ContainerManager
{
return
&
containerManagerStub
{}
return
&
containerManagerStub
{}
}
}
pkg/kubelet/eviction/eviction_manager.go
View file @
960856f4
...
@@ -149,11 +149,11 @@ func (m *managerImpl) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAd
...
@@ -149,11 +149,11 @@ func (m *managerImpl) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAd
}
}
// Start starts the control loop to observe and response to low compute resources.
// Start starts the control loop to observe and response to low compute resources.
func
(
m
*
managerImpl
)
Start
(
diskInfoProvider
DiskInfoProvider
,
podFunc
ActivePodsFunc
,
podCleanedUpFunc
PodCleanedUpFunc
,
capacityProvider
CapacityProvider
,
monitoringInterval
time
.
Duration
)
{
func
(
m
*
managerImpl
)
Start
(
diskInfoProvider
DiskInfoProvider
,
podFunc
ActivePodsFunc
,
podCleanedUpFunc
PodCleanedUpFunc
,
monitoringInterval
time
.
Duration
)
{
// start the eviction manager monitoring
// start the eviction manager monitoring
go
func
()
{
go
func
()
{
for
{
for
{
if
evictedPods
:=
m
.
synchronize
(
diskInfoProvider
,
podFunc
,
capacityProvider
);
evictedPods
!=
nil
{
if
evictedPods
:=
m
.
synchronize
(
diskInfoProvider
,
podFunc
);
evictedPods
!=
nil
{
glog
.
Infof
(
"eviction manager: pods %s evicted, waiting for pod to be cleaned up"
,
format
.
Pods
(
evictedPods
))
glog
.
Infof
(
"eviction manager: pods %s evicted, waiting for pod to be cleaned up"
,
format
.
Pods
(
evictedPods
))
m
.
waitForPodsCleanup
(
podCleanedUpFunc
,
evictedPods
)
m
.
waitForPodsCleanup
(
podCleanedUpFunc
,
evictedPods
)
}
else
{
}
else
{
...
@@ -219,7 +219,7 @@ func startMemoryThresholdNotifier(thresholds []evictionapi.Threshold, observatio
...
@@ -219,7 +219,7 @@ func startMemoryThresholdNotifier(thresholds []evictionapi.Threshold, observatio
// synchronize is the main control loop that enforces eviction thresholds.
// synchronize is the main control loop that enforces eviction thresholds.
// Returns the pod that was killed, or nil if no pod was killed.
// Returns the pod that was killed, or nil if no pod was killed.
func
(
m
*
managerImpl
)
synchronize
(
diskInfoProvider
DiskInfoProvider
,
podFunc
ActivePodsFunc
,
capacityProvider
CapacityProvider
)
[]
*
v1
.
Pod
{
func
(
m
*
managerImpl
)
synchronize
(
diskInfoProvider
DiskInfoProvider
,
podFunc
ActivePodsFunc
)
[]
*
v1
.
Pod
{
// if we have nothing to do, just return
// if we have nothing to do, just return
thresholds
:=
m
.
config
.
Thresholds
thresholds
:=
m
.
config
.
Thresholds
if
len
(
thresholds
)
==
0
{
if
len
(
thresholds
)
==
0
{
...
@@ -248,7 +248,7 @@ func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc Act
...
@@ -248,7 +248,7 @@ func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc Act
}
}
// make observations and get a function to derive pod usage stats relative to those observations.
// make observations and get a function to derive pod usage stats relative to those observations.
observations
,
statsFunc
:=
makeSignalObservations
(
summary
,
capacityProvider
,
activePods
)
observations
,
statsFunc
:=
makeSignalObservations
(
summary
)
debugLogObservations
(
"observations"
,
observations
)
debugLogObservations
(
"observations"
,
observations
)
// attempt to create a threshold notifier to improve eviction response time
// attempt to create a threshold notifier to improve eviction response time
...
@@ -259,7 +259,7 @@ func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc Act
...
@@ -259,7 +259,7 @@ func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc Act
err
=
startMemoryThresholdNotifier
(
m
.
config
.
Thresholds
,
observations
,
false
,
func
(
desc
string
)
{
err
=
startMemoryThresholdNotifier
(
m
.
config
.
Thresholds
,
observations
,
false
,
func
(
desc
string
)
{
glog
.
Infof
(
"soft memory eviction threshold crossed at %s"
,
desc
)
glog
.
Infof
(
"soft memory eviction threshold crossed at %s"
,
desc
)
// TODO wait grace period for soft memory limit
// TODO wait grace period for soft memory limit
m
.
synchronize
(
diskInfoProvider
,
podFunc
,
capacityProvider
)
m
.
synchronize
(
diskInfoProvider
,
podFunc
)
})
})
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Warningf
(
"eviction manager: failed to create soft memory threshold notifier: %v"
,
err
)
glog
.
Warningf
(
"eviction manager: failed to create soft memory threshold notifier: %v"
,
err
)
...
@@ -267,7 +267,7 @@ func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc Act
...
@@ -267,7 +267,7 @@ func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc Act
// start hard memory notification
// start hard memory notification
err
=
startMemoryThresholdNotifier
(
m
.
config
.
Thresholds
,
observations
,
true
,
func
(
desc
string
)
{
err
=
startMemoryThresholdNotifier
(
m
.
config
.
Thresholds
,
observations
,
true
,
func
(
desc
string
)
{
glog
.
Infof
(
"hard memory eviction threshold crossed at %s"
,
desc
)
glog
.
Infof
(
"hard memory eviction threshold crossed at %s"
,
desc
)
m
.
synchronize
(
diskInfoProvider
,
podFunc
,
capacityProvider
)
m
.
synchronize
(
diskInfoProvider
,
podFunc
)
})
})
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Warningf
(
"eviction manager: failed to create hard memory threshold notifier: %v"
,
err
)
glog
.
Warningf
(
"eviction manager: failed to create hard memory threshold notifier: %v"
,
err
)
...
@@ -349,7 +349,7 @@ func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc Act
...
@@ -349,7 +349,7 @@ func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc Act
m
.
recorder
.
Eventf
(
m
.
nodeRef
,
v1
.
EventTypeWarning
,
"EvictionThresholdMet"
,
"Attempting to reclaim %s"
,
resourceToReclaim
)
m
.
recorder
.
Eventf
(
m
.
nodeRef
,
v1
.
EventTypeWarning
,
"EvictionThresholdMet"
,
"Attempting to reclaim %s"
,
resourceToReclaim
)
// check if there are node-level resources we can reclaim to reduce pressure before evicting end-user pods.
// check if there are node-level resources we can reclaim to reduce pressure before evicting end-user pods.
if
m
.
reclaimNodeLevelResources
(
resourceToReclaim
,
capacityProvider
,
activePods
)
{
if
m
.
reclaimNodeLevelResources
(
resourceToReclaim
)
{
glog
.
Infof
(
"eviction manager: able to reduce %v pressure without evicting pods."
,
resourceToReclaim
)
glog
.
Infof
(
"eviction manager: able to reduce %v pressure without evicting pods."
,
resourceToReclaim
)
return
nil
return
nil
}
}
...
@@ -437,7 +437,7 @@ func (m *managerImpl) waitForPodsCleanup(podCleanedUpFunc PodCleanedUpFunc, pods
...
@@ -437,7 +437,7 @@ func (m *managerImpl) waitForPodsCleanup(podCleanedUpFunc PodCleanedUpFunc, pods
}
}
// reclaimNodeLevelResources attempts to reclaim node level resources. returns true if thresholds were satisfied and no pod eviction is required.
// reclaimNodeLevelResources attempts to reclaim node level resources. returns true if thresholds were satisfied and no pod eviction is required.
func
(
m
*
managerImpl
)
reclaimNodeLevelResources
(
resourceToReclaim
v1
.
ResourceName
,
capacityProvider
CapacityProvider
,
pods
[]
*
v1
.
Pod
)
bool
{
func
(
m
*
managerImpl
)
reclaimNodeLevelResources
(
resourceToReclaim
v1
.
ResourceName
)
bool
{
nodeReclaimFuncs
:=
m
.
resourceToNodeReclaimFuncs
[
resourceToReclaim
]
nodeReclaimFuncs
:=
m
.
resourceToNodeReclaimFuncs
[
resourceToReclaim
]
for
_
,
nodeReclaimFunc
:=
range
nodeReclaimFuncs
{
for
_
,
nodeReclaimFunc
:=
range
nodeReclaimFuncs
{
// attempt to reclaim the pressured resource.
// attempt to reclaim the pressured resource.
...
@@ -454,7 +454,7 @@ func (m *managerImpl) reclaimNodeLevelResources(resourceToReclaim v1.ResourceNam
...
@@ -454,7 +454,7 @@ func (m *managerImpl) reclaimNodeLevelResources(resourceToReclaim v1.ResourceNam
}
}
// make observations and get a function to derive pod usage stats relative to those observations.
// make observations and get a function to derive pod usage stats relative to those observations.
observations
,
_
:=
makeSignalObservations
(
summary
,
capacityProvider
,
pods
)
observations
,
_
:=
makeSignalObservations
(
summary
)
debugLogObservations
(
"observations after resource reclaim"
,
observations
)
debugLogObservations
(
"observations after resource reclaim"
,
observations
)
// determine the set of thresholds met independent of grace period
// determine the set of thresholds met independent of grace period
...
...
pkg/kubelet/eviction/eviction_manager_test.go
View file @
960856f4
This diff is collapsed.
Click to expand it.
pkg/kubelet/eviction/helpers.go
View file @
960856f4
...
@@ -100,9 +100,6 @@ func validSignal(signal evictionapi.Signal) bool {
...
@@ -100,9 +100,6 @@ func validSignal(signal evictionapi.Signal) bool {
// ParseThresholdConfig parses the flags for thresholds.
// ParseThresholdConfig parses the flags for thresholds.
func
ParseThresholdConfig
(
allocatableConfig
[]
string
,
evictionHard
,
evictionSoft
,
evictionSoftGracePeriod
,
evictionMinimumReclaim
map
[
string
]
string
)
([]
evictionapi
.
Threshold
,
error
)
{
func
ParseThresholdConfig
(
allocatableConfig
[]
string
,
evictionHard
,
evictionSoft
,
evictionSoftGracePeriod
,
evictionMinimumReclaim
map
[
string
]
string
)
([]
evictionapi
.
Threshold
,
error
)
{
results
:=
[]
evictionapi
.
Threshold
{}
results
:=
[]
evictionapi
.
Threshold
{}
allocatableThresholds
:=
getAllocatableThreshold
(
allocatableConfig
)
results
=
append
(
results
,
allocatableThresholds
...
)
hardThresholds
,
err
:=
parseThresholdStatements
(
evictionHard
)
hardThresholds
,
err
:=
parseThresholdStatements
(
evictionHard
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -137,9 +134,31 @@ func ParseThresholdConfig(allocatableConfig []string, evictionHard, evictionSoft
...
@@ -137,9 +134,31 @@ func ParseThresholdConfig(allocatableConfig []string, evictionHard, evictionSoft
}
}
}
}
}
}
for
_
,
key
:=
range
allocatableConfig
{
if
key
==
kubetypes
.
NodeAllocatableEnforcementKey
{
results
=
addAllocatableThresholds
(
results
)
break
}
}
return
results
,
nil
return
results
,
nil
}
}
func
addAllocatableThresholds
(
thresholds
[]
evictionapi
.
Threshold
)
[]
evictionapi
.
Threshold
{
additionalThresholds
:=
[]
evictionapi
.
Threshold
{}
for
_
,
threshold
:=
range
thresholds
{
if
threshold
.
Signal
==
evictionapi
.
SignalMemoryAvailable
&&
isHardEvictionThreshold
(
threshold
)
{
// Copy the SignalMemoryAvailable to SignalAllocatableMemoryAvailable
additionalThresholds
=
append
(
additionalThresholds
,
evictionapi
.
Threshold
{
Signal
:
evictionapi
.
SignalAllocatableMemoryAvailable
,
Operator
:
threshold
.
Operator
,
Value
:
threshold
.
Value
,
MinReclaim
:
threshold
.
MinReclaim
,
})
}
}
return
append
(
thresholds
,
additionalThresholds
...
)
}
// parseThresholdStatements parses the input statements into a list of Threshold objects.
// parseThresholdStatements parses the input statements into a list of Threshold objects.
func
parseThresholdStatements
(
statements
map
[
string
]
string
)
([]
evictionapi
.
Threshold
,
error
)
{
func
parseThresholdStatements
(
statements
map
[
string
]
string
)
([]
evictionapi
.
Threshold
,
error
)
{
if
len
(
statements
)
==
0
{
if
len
(
statements
)
==
0
{
...
@@ -204,27 +223,6 @@ func parseThresholdStatement(signal evictionapi.Signal, val string) (*evictionap
...
@@ -204,27 +223,6 @@ func parseThresholdStatement(signal evictionapi.Signal, val string) (*evictionap
},
nil
},
nil
}
}
// getAllocatableThreshold returns the thresholds applicable for the allocatable configuration
func
getAllocatableThreshold
(
allocatableConfig
[]
string
)
[]
evictionapi
.
Threshold
{
for
_
,
key
:=
range
allocatableConfig
{
if
key
==
kubetypes
.
NodeAllocatableEnforcementKey
{
return
[]
evictionapi
.
Threshold
{
{
Signal
:
evictionapi
.
SignalAllocatableMemoryAvailable
,
Operator
:
evictionapi
.
OpLessThan
,
Value
:
evictionapi
.
ThresholdValue
{
Quantity
:
resource
.
NewQuantity
(
int64
(
0
),
resource
.
BinarySI
),
},
MinReclaim
:
&
evictionapi
.
ThresholdValue
{
Quantity
:
resource
.
NewQuantity
(
int64
(
0
),
resource
.
BinarySI
),
},
},
}
}
}
return
[]
evictionapi
.
Threshold
{}
}
// parsePercentage parses a string representing a percentage value
// parsePercentage parses a string representing a percentage value
func
parsePercentage
(
input
string
)
(
float32
,
error
)
{
func
parsePercentage
(
input
string
)
(
float32
,
error
)
{
value
,
err
:=
strconv
.
ParseFloat
(
strings
.
TrimRight
(
input
,
"%"
),
32
)
value
,
err
:=
strconv
.
ParseFloat
(
strings
.
TrimRight
(
input
,
"%"
),
32
)
...
@@ -724,7 +722,7 @@ func (a byEvictionPriority) Less(i, j int) bool {
...
@@ -724,7 +722,7 @@ func (a byEvictionPriority) Less(i, j int) bool {
}
}
// makeSignalObservations derives observations using the specified summary provider.
// makeSignalObservations derives observations using the specified summary provider.
func
makeSignalObservations
(
summary
*
statsapi
.
Summary
,
capacityProvider
CapacityProvider
,
pods
[]
*
v1
.
Pod
)
(
signalObservations
,
statsFunc
)
{
func
makeSignalObservations
(
summary
*
statsapi
.
Summary
)
(
signalObservations
,
statsFunc
)
{
// build the function to work against for pod stats
// build the function to work against for pod stats
statsFunc
:=
cachedStatsFunc
(
summary
.
Pods
)
statsFunc
:=
cachedStatsFunc
(
summary
.
Pods
)
// build an evaluation context for current eviction signals
// build an evaluation context for current eviction signals
...
@@ -737,6 +735,17 @@ func makeSignalObservations(summary *statsapi.Summary, capacityProvider Capacity
...
@@ -737,6 +735,17 @@ func makeSignalObservations(summary *statsapi.Summary, capacityProvider Capacity
time
:
memory
.
Time
,
time
:
memory
.
Time
,
}
}
}
}
if
allocatableContainer
,
err
:=
getSysContainer
(
summary
.
Node
.
SystemContainers
,
statsapi
.
SystemContainerPods
);
err
!=
nil
{
glog
.
Errorf
(
"eviction manager: failed to construct signal: %q error: %v"
,
evictionapi
.
SignalAllocatableMemoryAvailable
,
err
)
}
else
{
if
memory
:=
allocatableContainer
.
Memory
;
memory
!=
nil
&&
memory
.
AvailableBytes
!=
nil
&&
memory
.
WorkingSetBytes
!=
nil
{
result
[
evictionapi
.
SignalAllocatableMemoryAvailable
]
=
signalObservation
{
available
:
resource
.
NewQuantity
(
int64
(
*
memory
.
AvailableBytes
),
resource
.
BinarySI
),
capacity
:
resource
.
NewQuantity
(
int64
(
*
memory
.
AvailableBytes
+*
memory
.
WorkingSetBytes
),
resource
.
BinarySI
),
time
:
memory
.
Time
,
}
}
}
if
nodeFs
:=
summary
.
Node
.
Fs
;
nodeFs
!=
nil
{
if
nodeFs
:=
summary
.
Node
.
Fs
;
nodeFs
!=
nil
{
if
nodeFs
.
AvailableBytes
!=
nil
&&
nodeFs
.
CapacityBytes
!=
nil
{
if
nodeFs
.
AvailableBytes
!=
nil
&&
nodeFs
.
CapacityBytes
!=
nil
{
result
[
evictionapi
.
SignalNodeFsAvailable
]
=
signalObservation
{
result
[
evictionapi
.
SignalNodeFsAvailable
]
=
signalObservation
{
...
@@ -771,7 +780,6 @@ func makeSignalObservations(summary *statsapi.Summary, capacityProvider Capacity
...
@@ -771,7 +780,6 @@ func makeSignalObservations(summary *statsapi.Summary, capacityProvider Capacity
}
}
}
}
}
}
if
rlimit
:=
summary
.
Node
.
Rlimit
;
rlimit
!=
nil
{
if
rlimit
:=
summary
.
Node
.
Rlimit
;
rlimit
!=
nil
{
if
rlimit
.
NumOfRunningProcesses
!=
nil
&&
rlimit
.
MaxPID
!=
nil
{
if
rlimit
.
NumOfRunningProcesses
!=
nil
&&
rlimit
.
MaxPID
!=
nil
{
available
:=
int64
(
*
rlimit
.
MaxPID
)
-
int64
(
*
rlimit
.
NumOfRunningProcesses
)
available
:=
int64
(
*
rlimit
.
MaxPID
)
-
int64
(
*
rlimit
.
NumOfRunningProcesses
)
...
@@ -782,27 +790,16 @@ func makeSignalObservations(summary *statsapi.Summary, capacityProvider Capacity
...
@@ -782,27 +790,16 @@ func makeSignalObservations(summary *statsapi.Summary, capacityProvider Capacity
}
}
}
}
}
}
return
result
,
statsFunc
}
if
memoryAllocatableCapacity
,
ok
:=
capacityProvider
.
GetCapacity
()[
v1
.
ResourceMemory
];
ok
{
func
getSysContainer
(
sysContainers
[]
statsapi
.
ContainerStats
,
name
string
)
(
*
statsapi
.
ContainerStats
,
error
)
{
memoryAllocatableAvailable
:=
memoryAllocatableCapacity
.
Copy
()
for
_
,
cont
:=
range
sysContainers
{
if
reserved
,
exists
:=
capacityProvider
.
GetNodeAllocatableReservation
()[
v1
.
ResourceMemory
];
exists
{
if
cont
.
Name
==
name
{
memoryAllocatableAvailable
.
Sub
(
reserved
)
return
&
cont
,
nil
}
for
_
,
pod
:=
range
summary
.
Pods
{
mu
,
err
:=
podMemoryUsage
(
pod
)
if
err
==
nil
{
memoryAllocatableAvailable
.
Sub
(
mu
[
v1
.
ResourceMemory
])
}
}
result
[
evictionapi
.
SignalAllocatableMemoryAvailable
]
=
signalObservation
{
available
:
memoryAllocatableAvailable
,
capacity
:
&
memoryAllocatableCapacity
,
}
}
}
else
{
glog
.
Errorf
(
"Could not find capacity information for resource %v"
,
v1
.
ResourceMemory
)
}
}
return
nil
,
fmt
.
Errorf
(
"system container %q not found in metrics"
,
name
)
return
result
,
statsFunc
}
}
// thresholdsMet returns the set of thresholds that were met independent of grace period
// thresholdsMet returns the set of thresholds that were met independent of grace period
...
...
pkg/kubelet/eviction/helpers_test.go
View file @
960856f4
...
@@ -72,7 +72,7 @@ func TestParseThresholdConfig(t *testing.T) {
...
@@ -72,7 +72,7 @@ func TestParseThresholdConfig(t *testing.T) {
Signal
:
evictionapi
.
SignalAllocatableMemoryAvailable
,
Signal
:
evictionapi
.
SignalAllocatableMemoryAvailable
,
Operator
:
evictionapi
.
OpLessThan
,
Operator
:
evictionapi
.
OpLessThan
,
Value
:
evictionapi
.
ThresholdValue
{
Value
:
evictionapi
.
ThresholdValue
{
Quantity
:
quantityMustParse
(
"
0
"
),
Quantity
:
quantityMustParse
(
"
150Mi
"
),
},
},
MinReclaim
:
&
evictionapi
.
ThresholdValue
{
MinReclaim
:
&
evictionapi
.
ThresholdValue
{
Quantity
:
quantityMustParse
(
"0"
),
Quantity
:
quantityMustParse
(
"0"
),
...
@@ -1004,6 +1004,15 @@ func TestMakeSignalObservations(t *testing.T) {
...
@@ -1004,6 +1004,15 @@ func TestMakeSignalObservations(t *testing.T) {
InodesFree
:
&
nodeFsInodesFree
,
InodesFree
:
&
nodeFsInodesFree
,
Inodes
:
&
nodeFsInodes
,
Inodes
:
&
nodeFsInodes
,
},
},
SystemContainers
:
[]
statsapi
.
ContainerStats
{
{
Name
:
statsapi
.
SystemContainerPods
,
Memory
:
&
statsapi
.
MemoryStats
{
AvailableBytes
:
&
nodeAvailableBytes
,
WorkingSetBytes
:
&
nodeWorkingSetBytes
,
},
},
},
},
},
Pods
:
[]
statsapi
.
PodStats
{},
Pods
:
[]
statsapi
.
PodStats
{},
}
}
...
@@ -1017,20 +1026,19 @@ func TestMakeSignalObservations(t *testing.T) {
...
@@ -1017,20 +1026,19 @@ func TestMakeSignalObservations(t *testing.T) {
fakeStats
.
Pods
=
append
(
fakeStats
.
Pods
,
newPodStats
(
pod
,
containerWorkingSetBytes
))
fakeStats
.
Pods
=
append
(
fakeStats
.
Pods
,
newPodStats
(
pod
,
containerWorkingSetBytes
))
}
}
res
:=
quantityMustParse
(
"5Gi"
)
res
:=
quantityMustParse
(
"5Gi"
)
capacityProvider
:=
newMockCapacityProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"5Gi"
)},
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"0Gi"
)})
// Allocatable thresholds are always 100%. Verify that Threshold == Capacity.
// Allocatable thresholds are always 100%. Verify that Threshold == Capacity.
if
res
.
CmpInt64
(
int64
(
allocatableMemoryCapacity
))
!=
0
{
if
res
.
CmpInt64
(
int64
(
allocatableMemoryCapacity
))
!=
0
{
t
.
Errorf
(
"Expected Threshold %v to be equal to value %v"
,
res
.
Value
(),
allocatableMemoryCapacity
)
t
.
Errorf
(
"Expected Threshold %v to be equal to value %v"
,
res
.
Value
(),
allocatableMemoryCapacity
)
}
}
actualObservations
,
statsFunc
:=
makeSignalObservations
(
fakeStats
,
capacityProvider
,
pods
)
actualObservations
,
statsFunc
:=
makeSignalObservations
(
fakeStats
)
allocatableMemQuantity
,
found
:=
actualObservations
[
evictionapi
.
SignalAllocatableMemoryAvailable
]
allocatableMemQuantity
,
found
:=
actualObservations
[
evictionapi
.
SignalAllocatableMemoryAvailable
]
if
!
found
{
if
!
found
{
t
.
Errorf
(
"Expected allocatable memory observation, but didnt find one"
)
t
.
Errorf
(
"Expected allocatable memory observation, but didnt find one"
)
}
}
if
allocatableMemQuantity
.
available
.
Value
()
!=
2
*
containerWorkingSet
Bytes
{
if
expectedBytes
:=
int64
(
nodeAvailableBytes
);
allocatableMemQuantity
.
available
.
Value
()
!=
expected
Bytes
{
t
.
Errorf
(
"Expected %v, actual: %v"
,
containerWorkingSet
Bytes
,
allocatableMemQuantity
.
available
.
Value
())
t
.
Errorf
(
"Expected %v, actual: %v"
,
expected
Bytes
,
allocatableMemQuantity
.
available
.
Value
())
}
}
if
expectedBytes
:=
int64
(
allocatableMemoryCapacity
);
allocatableMemQuantity
.
capacity
.
Value
()
!=
expectedBytes
{
if
expectedBytes
:=
int64
(
nodeWorkingSetBytes
+
nodeAvailableBytes
);
allocatableMemQuantity
.
capacity
.
Value
()
!=
expectedBytes
{
t
.
Errorf
(
"Expected %v, actual: %v"
,
expectedBytes
,
allocatableMemQuantity
.
capacity
.
Value
())
t
.
Errorf
(
"Expected %v, actual: %v"
,
expectedBytes
,
allocatableMemQuantity
.
capacity
.
Value
())
}
}
memQuantity
,
found
:=
actualObservations
[
evictionapi
.
SignalMemoryAvailable
]
memQuantity
,
found
:=
actualObservations
[
evictionapi
.
SignalMemoryAvailable
]
...
...
pkg/kubelet/eviction/types.go
View file @
960856f4
...
@@ -53,7 +53,7 @@ type Config struct {
...
@@ -53,7 +53,7 @@ type Config struct {
// Manager evaluates when an eviction threshold for node stability has been met on the node.
// Manager evaluates when an eviction threshold for node stability has been met on the node.
type
Manager
interface
{
type
Manager
interface
{
// Start starts the control loop to monitor eviction thresholds at specified interval.
// Start starts the control loop to monitor eviction thresholds at specified interval.
Start
(
diskInfoProvider
DiskInfoProvider
,
podFunc
ActivePodsFunc
,
podCleanedUpFunc
PodCleanedUpFunc
,
capacityProvider
CapacityProvider
,
monitoringInterval
time
.
Duration
)
Start
(
diskInfoProvider
DiskInfoProvider
,
podFunc
ActivePodsFunc
,
podCleanedUpFunc
PodCleanedUpFunc
,
monitoringInterval
time
.
Duration
)
// IsUnderMemoryPressure returns true if the node is under memory pressure.
// IsUnderMemoryPressure returns true if the node is under memory pressure.
IsUnderMemoryPressure
()
bool
IsUnderMemoryPressure
()
bool
...
@@ -71,14 +71,6 @@ type DiskInfoProvider interface {
...
@@ -71,14 +71,6 @@ type DiskInfoProvider interface {
HasDedicatedImageFs
()
(
bool
,
error
)
HasDedicatedImageFs
()
(
bool
,
error
)
}
}
// CapacityProvider is responsible for providing the resource capacity and reservation information
type
CapacityProvider
interface
{
// GetCapacity returns the amount of compute resources tracked by container manager available on the node.
GetCapacity
()
v1
.
ResourceList
// GetNodeAllocatableReservation returns the amount of compute resources that have to be reserved from scheduling.
GetNodeAllocatableReservation
()
v1
.
ResourceList
}
// ImageGC is responsible for performing garbage collection of unused images.
// ImageGC is responsible for performing garbage collection of unused images.
type
ImageGC
interface
{
type
ImageGC
interface
{
// DeleteUnusedImages deletes unused images.
// DeleteUnusedImages deletes unused images.
...
...
pkg/kubelet/kubelet.go
View file @
960856f4
...
@@ -1318,7 +1318,7 @@ func (kl *Kubelet) initializeRuntimeDependentModules() {
...
@@ -1318,7 +1318,7 @@ func (kl *Kubelet) initializeRuntimeDependentModules() {
glog
.
Fatalf
(
"Failed to start cAdvisor %v"
,
err
)
glog
.
Fatalf
(
"Failed to start cAdvisor %v"
,
err
)
}
}
// eviction manager must start after cadvisor because it needs to know if the container runtime has a dedicated imagefs
// eviction manager must start after cadvisor because it needs to know if the container runtime has a dedicated imagefs
kl
.
evictionManager
.
Start
(
kl
.
StatsProvider
,
kl
.
GetActivePods
,
kl
.
podResourcesAreReclaimed
,
kl
.
containerManager
,
evictionMonitoringPeriod
)
kl
.
evictionManager
.
Start
(
kl
.
StatsProvider
,
kl
.
GetActivePods
,
kl
.
podResourcesAreReclaimed
,
evictionMonitoringPeriod
)
// trigger on-demand stats collection once so that we have capacity information for ephemeral storage.
// trigger on-demand stats collection once so that we have capacity information for ephemeral storage.
// ignore any errors, since if stats collection is not successful, the container manager will fail to start below.
// ignore any errors, since if stats collection is not successful, the container manager will fail to start below.
...
...
pkg/kubelet/kubelet_getters.go
View file @
960856f4
...
@@ -211,6 +211,11 @@ func (kl *Kubelet) GetNodeConfig() cm.NodeConfig {
...
@@ -211,6 +211,11 @@ func (kl *Kubelet) GetNodeConfig() cm.NodeConfig {
return
kl
.
containerManager
.
GetNodeConfig
()
return
kl
.
containerManager
.
GetNodeConfig
()
}
}
// GetPodCgroupRoot returns the listeral cgroupfs value for the cgroup containing all pods
func
(
kl
*
Kubelet
)
GetPodCgroupRoot
()
string
{
return
kl
.
containerManager
.
GetPodCgroupRoot
()
}
// GetHostIP returns host IP or nil in case of error.
// GetHostIP returns host IP or nil in case of error.
func
(
kl
*
Kubelet
)
GetHostIP
()
(
net
.
IP
,
error
)
{
func
(
kl
*
Kubelet
)
GetHostIP
()
(
net
.
IP
,
error
)
{
node
,
err
:=
kl
.
GetNode
()
node
,
err
:=
kl
.
GetNode
()
...
...
pkg/kubelet/server/server_test.go
View file @
960856f4
...
@@ -168,6 +168,7 @@ func (fk *fakeKubelet) StreamingConnectionIdleTimeout() time.Duration {
...
@@ -168,6 +168,7 @@ func (fk *fakeKubelet) StreamingConnectionIdleTimeout() time.Duration {
// Unused functions
// Unused functions
func
(
_
*
fakeKubelet
)
GetNode
()
(
*
v1
.
Node
,
error
)
{
return
nil
,
nil
}
func
(
_
*
fakeKubelet
)
GetNode
()
(
*
v1
.
Node
,
error
)
{
return
nil
,
nil
}
func
(
_
*
fakeKubelet
)
GetNodeConfig
()
cm
.
NodeConfig
{
return
cm
.
NodeConfig
{}
}
func
(
_
*
fakeKubelet
)
GetNodeConfig
()
cm
.
NodeConfig
{
return
cm
.
NodeConfig
{}
}
func
(
_
*
fakeKubelet
)
GetPodCgroupRoot
()
string
{
return
""
}
func
(
fk
*
fakeKubelet
)
ListVolumesForPod
(
podUID
types
.
UID
)
(
map
[
string
]
volume
.
Volume
,
bool
)
{
func
(
fk
*
fakeKubelet
)
ListVolumesForPod
(
podUID
types
.
UID
)
(
map
[
string
]
volume
.
Volume
,
bool
)
{
return
map
[
string
]
volume
.
Volume
{},
true
return
map
[
string
]
volume
.
Volume
{},
true
...
...
pkg/kubelet/server/stats/handler.go
View file @
960856f4
...
@@ -81,6 +81,9 @@ type StatsProvider interface {
...
@@ -81,6 +81,9 @@ type StatsProvider interface {
// RlimitStats returns the rlimit stats of system.
// RlimitStats returns the rlimit stats of system.
RlimitStats
()
(
*
statsapi
.
RlimitStats
,
error
)
RlimitStats
()
(
*
statsapi
.
RlimitStats
,
error
)
// GetPodCgroupRoot returns the literal cgroupfs value for the cgroup containing all pods
GetPodCgroupRoot
()
string
}
}
type
handler
struct
{
type
handler
struct
{
...
...
pkg/kubelet/server/stats/summary.go
View file @
960856f4
...
@@ -83,19 +83,23 @@ func (sp *summaryProviderImpl) Get(updateStats bool) (*statsapi.Summary, error)
...
@@ -83,19 +83,23 @@ func (sp *summaryProviderImpl) Get(updateStats bool) (*statsapi.Summary, error)
Rlimit
:
rlimit
,
Rlimit
:
rlimit
,
}
}
systemContainers
:=
map
[
string
]
string
{
systemContainers
:=
map
[
string
]
struct
{
statsapi
.
SystemContainerKubelet
:
nodeConfig
.
KubeletCgroupsName
,
name
string
statsapi
.
SystemContainerRuntime
:
nodeConfig
.
RuntimeCgroupsName
,
forceStatsUpdate
bool
statsapi
.
SystemContainerMisc
:
nodeConfig
.
SystemCgroupsName
,
}{
statsapi
.
SystemContainerKubelet
:
{
nodeConfig
.
KubeletCgroupsName
,
false
},
statsapi
.
SystemContainerRuntime
:
{
nodeConfig
.
RuntimeCgroupsName
,
false
},
statsapi
.
SystemContainerMisc
:
{
nodeConfig
.
SystemCgroupsName
,
false
},
statsapi
.
SystemContainerPods
:
{
sp
.
provider
.
GetPodCgroupRoot
(),
updateStats
},
}
}
for
sys
,
name
:=
range
systemContainers
{
for
sys
,
cont
:=
range
systemContainers
{
// skip if cgroup name is undefined (not all system containers are required)
// skip if cgroup name is undefined (not all system containers are required)
if
name
==
""
{
if
cont
.
name
==
""
{
continue
continue
}
}
s
,
_
,
err
:=
sp
.
provider
.
GetCgroupStats
(
name
,
fals
e
)
s
,
_
,
err
:=
sp
.
provider
.
GetCgroupStats
(
cont
.
name
,
cont
.
forceStatsUpdat
e
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Errorf
(
"Failed to get system container stats for %q: %v"
,
name
,
err
)
glog
.
Errorf
(
"Failed to get system container stats for %q: %v"
,
cont
.
name
,
err
)
continue
continue
}
}
// System containers don't have a filesystem associated with them.
// System containers don't have a filesystem associated with them.
...
...
pkg/kubelet/server/stats/summary_test.go
View file @
960856f4
...
@@ -49,6 +49,7 @@ func TestSummaryProvider(t *testing.T) {
...
@@ -49,6 +49,7 @@ func TestSummaryProvider(t *testing.T) {
SystemCgroupsName
:
"/misc"
,
SystemCgroupsName
:
"/misc"
,
KubeletCgroupsName
:
"/kubelet"
,
KubeletCgroupsName
:
"/kubelet"
,
}
}
cgroupRoot
=
"/kubepods"
cgroupStatsMap
=
map
[
string
]
struct
{
cgroupStatsMap
=
map
[
string
]
struct
{
cs
*
statsapi
.
ContainerStats
cs
*
statsapi
.
ContainerStats
ns
*
statsapi
.
NetworkStats
ns
*
statsapi
.
NetworkStats
...
@@ -57,6 +58,7 @@ func TestSummaryProvider(t *testing.T) {
...
@@ -57,6 +58,7 @@ func TestSummaryProvider(t *testing.T) {
"/runtime"
:
{
cs
:
getContainerStats
(),
ns
:
getNetworkStats
()},
"/runtime"
:
{
cs
:
getContainerStats
(),
ns
:
getNetworkStats
()},
"/misc"
:
{
cs
:
getContainerStats
(),
ns
:
getNetworkStats
()},
"/misc"
:
{
cs
:
getContainerStats
(),
ns
:
getNetworkStats
()},
"/kubelet"
:
{
cs
:
getContainerStats
(),
ns
:
getNetworkStats
()},
"/kubelet"
:
{
cs
:
getContainerStats
(),
ns
:
getNetworkStats
()},
"/pods"
:
{
cs
:
getContainerStats
(),
ns
:
getNetworkStats
()},
}
}
rlimitStats
=
getRlimitStats
()
rlimitStats
=
getRlimitStats
()
)
)
...
@@ -67,6 +69,7 @@ func TestSummaryProvider(t *testing.T) {
...
@@ -67,6 +69,7 @@ func TestSummaryProvider(t *testing.T) {
mockStatsProvider
.
mockStatsProvider
.
On
(
"GetNode"
)
.
Return
(
node
,
nil
)
.
On
(
"GetNode"
)
.
Return
(
node
,
nil
)
.
On
(
"GetNodeConfig"
)
.
Return
(
nodeConfig
)
.
On
(
"GetNodeConfig"
)
.
Return
(
nodeConfig
)
.
On
(
"GetPodCgroupRoot"
)
.
Return
(
cgroupRoot
)
.
On
(
"ListPodStats"
)
.
Return
(
podStats
,
nil
)
.
On
(
"ListPodStats"
)
.
Return
(
podStats
,
nil
)
.
On
(
"ImageFsStats"
)
.
Return
(
imageFsStats
,
nil
)
.
On
(
"ImageFsStats"
)
.
Return
(
imageFsStats
,
nil
)
.
On
(
"RootFsStats"
)
.
Return
(
rootFsStats
,
nil
)
.
On
(
"RootFsStats"
)
.
Return
(
rootFsStats
,
nil
)
.
...
@@ -74,7 +77,8 @@ func TestSummaryProvider(t *testing.T) {
...
@@ -74,7 +77,8 @@ func TestSummaryProvider(t *testing.T) {
On
(
"GetCgroupStats"
,
"/"
,
true
)
.
Return
(
cgroupStatsMap
[
"/"
]
.
cs
,
cgroupStatsMap
[
"/"
]
.
ns
,
nil
)
.
On
(
"GetCgroupStats"
,
"/"
,
true
)
.
Return
(
cgroupStatsMap
[
"/"
]
.
cs
,
cgroupStatsMap
[
"/"
]
.
ns
,
nil
)
.
On
(
"GetCgroupStats"
,
"/runtime"
,
false
)
.
Return
(
cgroupStatsMap
[
"/runtime"
]
.
cs
,
cgroupStatsMap
[
"/runtime"
]
.
ns
,
nil
)
.
On
(
"GetCgroupStats"
,
"/runtime"
,
false
)
.
Return
(
cgroupStatsMap
[
"/runtime"
]
.
cs
,
cgroupStatsMap
[
"/runtime"
]
.
ns
,
nil
)
.
On
(
"GetCgroupStats"
,
"/misc"
,
false
)
.
Return
(
cgroupStatsMap
[
"/misc"
]
.
cs
,
cgroupStatsMap
[
"/misc"
]
.
ns
,
nil
)
.
On
(
"GetCgroupStats"
,
"/misc"
,
false
)
.
Return
(
cgroupStatsMap
[
"/misc"
]
.
cs
,
cgroupStatsMap
[
"/misc"
]
.
ns
,
nil
)
.
On
(
"GetCgroupStats"
,
"/kubelet"
,
false
)
.
Return
(
cgroupStatsMap
[
"/kubelet"
]
.
cs
,
cgroupStatsMap
[
"/kubelet"
]
.
ns
,
nil
)
On
(
"GetCgroupStats"
,
"/kubelet"
,
false
)
.
Return
(
cgroupStatsMap
[
"/kubelet"
]
.
cs
,
cgroupStatsMap
[
"/kubelet"
]
.
ns
,
nil
)
.
On
(
"GetCgroupStats"
,
"/kubepods"
,
true
)
.
Return
(
cgroupStatsMap
[
"/pods"
]
.
cs
,
cgroupStatsMap
[
"/pods"
]
.
ns
,
nil
)
provider
:=
NewSummaryProvider
(
mockStatsProvider
)
provider
:=
NewSummaryProvider
(
mockStatsProvider
)
summary
,
err
:=
provider
.
Get
(
true
)
summary
,
err
:=
provider
.
Get
(
true
)
...
@@ -88,7 +92,7 @@ func TestSummaryProvider(t *testing.T) {
...
@@ -88,7 +92,7 @@ func TestSummaryProvider(t *testing.T) {
assert
.
Equal
(
summary
.
Node
.
Fs
,
rootFsStats
)
assert
.
Equal
(
summary
.
Node
.
Fs
,
rootFsStats
)
assert
.
Equal
(
summary
.
Node
.
Runtime
,
&
statsapi
.
RuntimeStats
{
ImageFs
:
imageFsStats
})
assert
.
Equal
(
summary
.
Node
.
Runtime
,
&
statsapi
.
RuntimeStats
{
ImageFs
:
imageFsStats
})
assert
.
Equal
(
len
(
summary
.
Node
.
SystemContainers
),
3
)
assert
.
Equal
(
len
(
summary
.
Node
.
SystemContainers
),
4
)
assert
.
Contains
(
summary
.
Node
.
SystemContainers
,
statsapi
.
ContainerStats
{
assert
.
Contains
(
summary
.
Node
.
SystemContainers
,
statsapi
.
ContainerStats
{
Name
:
"kubelet"
,
Name
:
"kubelet"
,
StartTime
:
cgroupStatsMap
[
"/kubelet"
]
.
cs
.
StartTime
,
StartTime
:
cgroupStatsMap
[
"/kubelet"
]
.
cs
.
StartTime
,
...
@@ -113,6 +117,14 @@ func TestSummaryProvider(t *testing.T) {
...
@@ -113,6 +117,14 @@ func TestSummaryProvider(t *testing.T) {
Accelerators
:
cgroupStatsMap
[
"/runtime"
]
.
cs
.
Accelerators
,
Accelerators
:
cgroupStatsMap
[
"/runtime"
]
.
cs
.
Accelerators
,
UserDefinedMetrics
:
cgroupStatsMap
[
"/runtime"
]
.
cs
.
UserDefinedMetrics
,
UserDefinedMetrics
:
cgroupStatsMap
[
"/runtime"
]
.
cs
.
UserDefinedMetrics
,
})
})
assert
.
Contains
(
summary
.
Node
.
SystemContainers
,
statsapi
.
ContainerStats
{
Name
:
"pods"
,
StartTime
:
cgroupStatsMap
[
"/pods"
]
.
cs
.
StartTime
,
CPU
:
cgroupStatsMap
[
"/pods"
]
.
cs
.
CPU
,
Memory
:
cgroupStatsMap
[
"/pods"
]
.
cs
.
Memory
,
Accelerators
:
cgroupStatsMap
[
"/pods"
]
.
cs
.
Accelerators
,
UserDefinedMetrics
:
cgroupStatsMap
[
"/pods"
]
.
cs
.
UserDefinedMetrics
,
})
assert
.
Equal
(
summary
.
Pods
,
podStats
)
assert
.
Equal
(
summary
.
Pods
,
podStats
)
}
}
...
...
pkg/kubelet/server/stats/testing/mock_stats_provider.go
View file @
960856f4
...
@@ -125,6 +125,20 @@ func (_m *StatsProvider) GetNodeConfig() cm.NodeConfig {
...
@@ -125,6 +125,20 @@ func (_m *StatsProvider) GetNodeConfig() cm.NodeConfig {
return
r0
return
r0
}
}
// GetPodCgroupRoot provides a mock function with given fields:
func
(
_m
*
StatsProvider
)
GetPodCgroupRoot
()
string
{
ret
:=
_m
.
Called
()
var
r0
string
if
rf
,
ok
:=
ret
.
Get
(
0
)
.
(
func
()
string
);
ok
{
r0
=
rf
()
}
else
{
r0
=
ret
.
Get
(
0
)
.
(
string
)
}
return
r0
}
// GetPodByName provides a mock function with given fields: namespace, name
// GetPodByName provides a mock function with given fields: namespace, name
func
(
_m
*
StatsProvider
)
GetPodByName
(
namespace
string
,
name
string
)
(
*
corev1
.
Pod
,
bool
)
{
func
(
_m
*
StatsProvider
)
GetPodByName
(
namespace
string
,
name
string
)
(
*
corev1
.
Pod
,
bool
)
{
ret
:=
_m
.
Called
(
namespace
,
name
)
ret
:=
_m
.
Called
(
namespace
,
name
)
...
...
test/e2e_node/summary_test.go
View file @
960856f4
...
@@ -107,9 +107,21 @@ var _ = framework.KubeDescribe("Summary API", func() {
...
@@ -107,9 +107,21 @@ var _ = framework.KubeDescribe("Summary API", func() {
"UserDefinedMetrics"
:
BeEmpty
(),
"UserDefinedMetrics"
:
BeEmpty
(),
})
})
}
}
podsContExpectations
:=
sysContExpectations
()
.
(
*
gstruct
.
FieldsMatcher
)
podsContExpectations
.
Fields
[
"Memory"
]
=
ptrMatchAllFields
(
gstruct
.
Fields
{
"Time"
:
recent
(
maxStatsAge
),
// Pods are limited by Node Allocatable
"AvailableBytes"
:
bounded
(
1
*
framework
.
Kb
,
memoryLimit
),
"UsageBytes"
:
bounded
(
10
*
framework
.
Kb
,
20
*
framework
.
Mb
),
"WorkingSetBytes"
:
bounded
(
10
*
framework
.
Kb
,
20
*
framework
.
Mb
),
"RSSBytes"
:
bounded
(
1
*
framework
.
Kb
,
20
*
framework
.
Mb
),
"PageFaults"
:
bounded
(
0
,
1000000
),
"MajorPageFaults"
:
bounded
(
0
,
10
),
})
systemContainers
:=
gstruct
.
Elements
{
systemContainers
:=
gstruct
.
Elements
{
"kubelet"
:
sysContExpectations
(),
"kubelet"
:
sysContExpectations
(),
"runtime"
:
sysContExpectations
(),
"runtime"
:
sysContExpectations
(),
"pods"
:
podsContExpectations
,
}
}
// The Kubelet only manages the 'misc' system container if the host is not running systemd.
// The Kubelet only manages the 'misc' system container if the host is not running systemd.
if
!
systemdutil
.
IsRunningSystemd
()
{
if
!
systemdutil
.
IsRunningSystemd
()
{
...
...
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