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
889afa5e
Commit
889afa5e
authored
May 22, 2017
by
David Ashpole
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
trigger aggressive container garbage collection when under disk pressure
parent
07f85565
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
193 additions
and
105 deletions
+193
-105
container_gc.go
pkg/kubelet/container/container_gc.go
+22
-6
runtime.go
pkg/kubelet/container/runtime.go
+3
-1
fake_runtime.go
pkg/kubelet/container/testing/fake_runtime.go
+1
-1
runtime_mock.go
pkg/kubelet/container/testing/runtime_mock.go
+2
-2
eviction_manager.go
pkg/kubelet/eviction/eviction_manager.go
+5
-2
eviction_manager_test.go
pkg/kubelet/eviction/eviction_manager_test.go
+47
-31
helpers.go
pkg/kubelet/eviction/helpers.go
+15
-13
types.go
pkg/kubelet/eviction/types.go
+7
-0
kubelet.go
pkg/kubelet/kubelet.go
+3
-3
kubelet_test.go
pkg/kubelet/kubelet_test.go
+1
-1
kuberuntime_gc.go
pkg/kubelet/kuberuntime/kuberuntime_gc.go
+7
-7
kuberuntime_gc_test.go
pkg/kubelet/kuberuntime/kuberuntime_gc_test.go
+74
-33
kuberuntime_manager.go
pkg/kubelet/kuberuntime/kuberuntime_manager.go
+2
-2
rkt.go
pkg/kubelet/rkt/rkt.go
+1
-1
rkt_test.go
pkg/kubelet/rkt/rkt_test.go
+2
-1
runonce_test.go
pkg/kubelet/runonce_test.go
+1
-1
No files found.
pkg/kubelet/container/container_gc.go
View file @
889afa5e
...
@@ -39,7 +39,15 @@ type ContainerGCPolicy struct {
...
@@ -39,7 +39,15 @@ type ContainerGCPolicy struct {
// Implementation is thread-compatible.
// Implementation is thread-compatible.
type
ContainerGC
interface
{
type
ContainerGC
interface
{
// Garbage collect containers.
// Garbage collect containers.
GarbageCollect
(
allSourcesReady
bool
)
error
GarbageCollect
()
error
// Deletes all unused containers, including containers belonging to pods that are terminated but not deleted
DeleteAllUnusedContainers
()
error
}
// SourcesReadyProvider knows how to determine if configuration sources are ready
type
SourcesReadyProvider
interface
{
// AllReady returns true if the currently configured sources have all been seen.
AllReady
()
bool
}
}
// TODO(vmarmol): Preferentially remove pod infra containers.
// TODO(vmarmol): Preferentially remove pod infra containers.
...
@@ -49,20 +57,28 @@ type realContainerGC struct {
...
@@ -49,20 +57,28 @@ type realContainerGC struct {
// Policy for garbage collection.
// Policy for garbage collection.
policy
ContainerGCPolicy
policy
ContainerGCPolicy
// sourcesReadyProvider provides the readyness of kubelet configuration sources.
sourcesReadyProvider
SourcesReadyProvider
}
}
// New ContainerGC instance with the specified policy.
// New ContainerGC instance with the specified policy.
func
NewContainerGC
(
runtime
Runtime
,
policy
ContainerGCPolicy
)
(
ContainerGC
,
error
)
{
func
NewContainerGC
(
runtime
Runtime
,
policy
ContainerGCPolicy
,
sourcesReadyProvider
SourcesReadyProvider
)
(
ContainerGC
,
error
)
{
if
policy
.
MinAge
<
0
{
if
policy
.
MinAge
<
0
{
return
nil
,
fmt
.
Errorf
(
"invalid minimum garbage collection age: %v"
,
policy
.
MinAge
)
return
nil
,
fmt
.
Errorf
(
"invalid minimum garbage collection age: %v"
,
policy
.
MinAge
)
}
}
return
&
realContainerGC
{
return
&
realContainerGC
{
runtime
:
runtime
,
runtime
:
runtime
,
policy
:
policy
,
policy
:
policy
,
sourcesReadyProvider
:
sourcesReadyProvider
,
},
nil
},
nil
}
}
func
(
cgc
*
realContainerGC
)
GarbageCollect
(
allSourcesReady
bool
)
error
{
func
(
cgc
*
realContainerGC
)
GarbageCollect
()
error
{
return
cgc
.
runtime
.
GarbageCollect
(
cgc
.
policy
,
allSourcesReady
)
return
cgc
.
runtime
.
GarbageCollect
(
cgc
.
policy
,
cgc
.
sourcesReadyProvider
.
AllReady
(),
false
)
}
func
(
cgc
*
realContainerGC
)
DeleteAllUnusedContainers
()
error
{
return
cgc
.
runtime
.
GarbageCollect
(
cgc
.
policy
,
cgc
.
sourcesReadyProvider
.
AllReady
(),
true
)
}
}
pkg/kubelet/container/runtime.go
View file @
889afa5e
...
@@ -82,8 +82,10 @@ type Runtime interface {
...
@@ -82,8 +82,10 @@ type Runtime interface {
// complete list of pods from all avialble sources (e.g., apiserver, http,
// complete list of pods from all avialble sources (e.g., apiserver, http,
// file). In this case, garbage collector should refrain itself from aggressive
// file). In this case, garbage collector should refrain itself from aggressive
// behavior such as removing all containers of unrecognized pods (yet).
// behavior such as removing all containers of unrecognized pods (yet).
// If evictNonDeletedPods is set to true, containers and sandboxes belonging to pods
// that are terminated, but not deleted will be evicted. Otherwise, only deleted pods will be GC'd.
// TODO: Revisit this method and make it cleaner.
// TODO: Revisit this method and make it cleaner.
GarbageCollect
(
gcPolicy
ContainerGCPolicy
,
allSourcesReady
bool
)
error
GarbageCollect
(
gcPolicy
ContainerGCPolicy
,
allSourcesReady
bool
,
evictNonDeletedPods
bool
)
error
// Syncs the running pod into the desired pod.
// Syncs the running pod into the desired pod.
SyncPod
(
pod
*
v1
.
Pod
,
apiPodStatus
v1
.
PodStatus
,
podStatus
*
PodStatus
,
pullSecrets
[]
v1
.
Secret
,
backOff
*
flowcontrol
.
Backoff
)
PodSyncResult
SyncPod
(
pod
*
v1
.
Pod
,
apiPodStatus
v1
.
PodStatus
,
podStatus
*
PodStatus
,
pullSecrets
[]
v1
.
Secret
,
backOff
*
flowcontrol
.
Backoff
)
PodSyncResult
// KillPod kills all the containers of a pod. Pod may be nil, running pod must not be.
// KillPod kills all the containers of a pod. Pod may be nil, running pod must not be.
...
...
pkg/kubelet/container/testing/fake_runtime.go
View file @
889afa5e
...
@@ -431,7 +431,7 @@ func (f *FakeRuntime) GetPodContainerID(pod *Pod) (ContainerID, error) {
...
@@ -431,7 +431,7 @@ func (f *FakeRuntime) GetPodContainerID(pod *Pod) (ContainerID, error) {
return
ContainerID
{},
f
.
Err
return
ContainerID
{},
f
.
Err
}
}
func
(
f
*
FakeRuntime
)
GarbageCollect
(
gcPolicy
ContainerGCPolicy
,
ready
bool
)
error
{
func
(
f
*
FakeRuntime
)
GarbageCollect
(
gcPolicy
ContainerGCPolicy
,
ready
bool
,
evictNonDeletedPods
bool
)
error
{
f
.
Lock
()
f
.
Lock
()
defer
f
.
Unlock
()
defer
f
.
Unlock
()
...
...
pkg/kubelet/container/testing/runtime_mock.go
View file @
889afa5e
...
@@ -140,8 +140,8 @@ func (r *Mock) GetPodContainerID(pod *Pod) (ContainerID, error) {
...
@@ -140,8 +140,8 @@ func (r *Mock) GetPodContainerID(pod *Pod) (ContainerID, error) {
return
ContainerID
{},
args
.
Error
(
0
)
return
ContainerID
{},
args
.
Error
(
0
)
}
}
func
(
r
*
Mock
)
GarbageCollect
(
gcPolicy
ContainerGCPolicy
,
ready
bool
)
error
{
func
(
r
*
Mock
)
GarbageCollect
(
gcPolicy
ContainerGCPolicy
,
ready
bool
,
evictNonDeletedPods
bool
)
error
{
args
:=
r
.
Called
(
gcPolicy
,
ready
)
args
:=
r
.
Called
(
gcPolicy
,
ready
,
evictNonDeletedPods
)
return
args
.
Error
(
0
)
return
args
.
Error
(
0
)
}
}
...
...
pkg/kubelet/eviction/eviction_manager.go
View file @
889afa5e
...
@@ -58,6 +58,8 @@ type managerImpl struct {
...
@@ -58,6 +58,8 @@ type managerImpl struct {
killPodFunc
KillPodFunc
killPodFunc
KillPodFunc
// the interface that knows how to do image gc
// the interface that knows how to do image gc
imageGC
ImageGC
imageGC
ImageGC
// the interface that knows how to do image gc
containerGC
ContainerGC
// protects access to internal state
// protects access to internal state
sync
.
RWMutex
sync
.
RWMutex
// node conditions are the set of conditions present
// node conditions are the set of conditions present
...
@@ -95,6 +97,7 @@ func NewManager(
...
@@ -95,6 +97,7 @@ func NewManager(
config
Config
,
config
Config
,
killPodFunc
KillPodFunc
,
killPodFunc
KillPodFunc
,
imageGC
ImageGC
,
imageGC
ImageGC
,
containerGC
ContainerGC
,
recorder
record
.
EventRecorder
,
recorder
record
.
EventRecorder
,
nodeRef
*
clientv1
.
ObjectReference
,
nodeRef
*
clientv1
.
ObjectReference
,
clock
clock
.
Clock
)
(
Manager
,
lifecycle
.
PodAdmitHandler
)
{
clock
clock
.
Clock
)
(
Manager
,
lifecycle
.
PodAdmitHandler
)
{
...
@@ -102,6 +105,7 @@ func NewManager(
...
@@ -102,6 +105,7 @@ func NewManager(
clock
:
clock
,
clock
:
clock
,
killPodFunc
:
killPodFunc
,
killPodFunc
:
killPodFunc
,
imageGC
:
imageGC
,
imageGC
:
imageGC
,
containerGC
:
containerGC
,
config
:
config
,
config
:
config
,
recorder
:
recorder
,
recorder
:
recorder
,
summaryProvider
:
summaryProvider
,
summaryProvider
:
summaryProvider
,
...
@@ -223,8 +227,7 @@ func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc Act
...
@@ -223,8 +227,7 @@ func (m *managerImpl) synchronize(diskInfoProvider DiskInfoProvider, podFunc Act
}
}
m
.
dedicatedImageFs
=
&
hasImageFs
m
.
dedicatedImageFs
=
&
hasImageFs
m
.
resourceToRankFunc
=
buildResourceToRankFunc
(
hasImageFs
)
m
.
resourceToRankFunc
=
buildResourceToRankFunc
(
hasImageFs
)
m
.
resourceToNodeReclaimFuncs
=
buildResourceToNodeReclaimFuncs
(
m
.
imageGC
,
hasImageFs
)
m
.
resourceToNodeReclaimFuncs
=
buildResourceToNodeReclaimFuncs
(
m
.
imageGC
,
m
.
containerGC
,
hasImageFs
)
}
}
activePods
:=
podFunc
()
activePods
:=
podFunc
()
...
...
pkg/kubelet/eviction/eviction_manager_test.go
View file @
889afa5e
...
@@ -77,17 +77,24 @@ func (m *mockNodeProvider) GetNode() (*v1.Node, error) {
...
@@ -77,17 +77,24 @@ func (m *mockNodeProvider) GetNode() (*v1.Node, error) {
return
&
m
.
node
,
nil
return
&
m
.
node
,
nil
}
}
// mockImageGC is used to simulate invoking image garbage collection.
// mockDiskGC is used to simulate invoking image and container garbage collection.
type
mockImageGC
struct
{
type
mockDiskGC
struct
{
err
error
err
error
freed
int64
imageBytesFreed
int64
invoked
bool
imageGCInvoked
bool
containerGCInvoked
bool
}
}
// DeleteUnusedImages returns the mocked values.
// DeleteUnusedImages returns the mocked values.
func
(
m
*
mockImageGC
)
DeleteUnusedImages
()
(
int64
,
error
)
{
func
(
m
*
mockDiskGC
)
DeleteUnusedImages
()
(
int64
,
error
)
{
m
.
invoked
=
true
m
.
imageGCInvoked
=
true
return
m
.
freed
,
m
.
err
return
m
.
imageBytesFreed
,
m
.
err
}
// DeleteAllUnusedContainers returns the mocked value
func
(
m
*
mockDiskGC
)
DeleteAllUnusedContainers
()
error
{
m
.
containerGCInvoked
=
true
return
m
.
err
}
}
func
makePodWithMemoryStats
(
name
string
,
requests
v1
.
ResourceList
,
limits
v1
.
ResourceList
,
memoryWorkingSet
string
)
(
*
v1
.
Pod
,
statsapi
.
PodStats
)
{
func
makePodWithMemoryStats
(
name
string
,
requests
v1
.
ResourceList
,
limits
v1
.
ResourceList
,
memoryWorkingSet
string
)
(
*
v1
.
Pod
,
statsapi
.
PodStats
)
{
...
@@ -194,7 +201,7 @@ func TestMemoryPressure(t *testing.T) {
...
@@ -194,7 +201,7 @@ func TestMemoryPressure(t *testing.T) {
podKiller
:=
&
mockPodKiller
{}
podKiller
:=
&
mockPodKiller
{}
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
imageGC
:=
&
mock
ImageGC
{
f
reed
:
int64
(
0
),
err
:
nil
}
imageGC
:=
&
mock
DiskGC
{
imageBytesF
reed
:
int64
(
0
),
err
:
nil
}
nodeRef
:=
&
clientv1
.
ObjectReference
{
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
}
nodeRef
:=
&
clientv1
.
ObjectReference
{
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
}
config
:=
Config
{
config
:=
Config
{
...
@@ -412,7 +419,7 @@ func TestDiskPressureNodeFs(t *testing.T) {
...
@@ -412,7 +419,7 @@ func TestDiskPressureNodeFs(t *testing.T) {
podKiller
:=
&
mockPodKiller
{}
podKiller
:=
&
mockPodKiller
{}
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
imageGC
:=
&
mockImageGC
{
f
reed
:
int64
(
0
),
err
:
nil
}
diskGC
:=
&
mockDiskGC
{
imageBytesF
reed
:
int64
(
0
),
err
:
nil
}
nodeRef
:=
&
clientv1
.
ObjectReference
{
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
}
nodeRef
:=
&
clientv1
.
ObjectReference
{
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
}
config
:=
Config
{
config
:=
Config
{
...
@@ -440,7 +447,8 @@ func TestDiskPressureNodeFs(t *testing.T) {
...
@@ -440,7 +447,8 @@ func TestDiskPressureNodeFs(t *testing.T) {
manager
:=
&
managerImpl
{
manager
:=
&
managerImpl
{
clock
:
fakeClock
,
clock
:
fakeClock
,
killPodFunc
:
podKiller
.
killPodNow
,
killPodFunc
:
podKiller
.
killPodNow
,
imageGC
:
imageGC
,
imageGC
:
diskGC
,
containerGC
:
diskGC
,
config
:
config
,
config
:
config
,
recorder
:
&
record
.
FakeRecorder
{},
recorder
:
&
record
.
FakeRecorder
{},
summaryProvider
:
summaryProvider
,
summaryProvider
:
summaryProvider
,
...
@@ -610,7 +618,7 @@ func TestMinReclaim(t *testing.T) {
...
@@ -610,7 +618,7 @@ func TestMinReclaim(t *testing.T) {
podKiller
:=
&
mockPodKiller
{}
podKiller
:=
&
mockPodKiller
{}
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
imageGC
:=
&
mockImageGC
{
f
reed
:
int64
(
0
),
err
:
nil
}
diskGC
:=
&
mockDiskGC
{
imageBytesF
reed
:
int64
(
0
),
err
:
nil
}
nodeRef
:=
&
clientv1
.
ObjectReference
{
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
}
nodeRef
:=
&
clientv1
.
ObjectReference
{
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
}
config
:=
Config
{
config
:=
Config
{
...
@@ -633,7 +641,8 @@ func TestMinReclaim(t *testing.T) {
...
@@ -633,7 +641,8 @@ func TestMinReclaim(t *testing.T) {
manager
:=
&
managerImpl
{
manager
:=
&
managerImpl
{
clock
:
fakeClock
,
clock
:
fakeClock
,
killPodFunc
:
podKiller
.
killPodNow
,
killPodFunc
:
podKiller
.
killPodNow
,
imageGC
:
imageGC
,
imageGC
:
diskGC
,
containerGC
:
diskGC
,
config
:
config
,
config
:
config
,
recorder
:
&
record
.
FakeRecorder
{},
recorder
:
&
record
.
FakeRecorder
{},
summaryProvider
:
summaryProvider
,
summaryProvider
:
summaryProvider
,
...
@@ -750,7 +759,7 @@ func TestNodeReclaimFuncs(t *testing.T) {
...
@@ -750,7 +759,7 @@ func TestNodeReclaimFuncs(t *testing.T) {
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
imageGcFree
:=
resource
.
MustParse
(
"700Mi"
)
imageGcFree
:=
resource
.
MustParse
(
"700Mi"
)
imageGC
:=
&
mockImageGC
{
f
reed
:
imageGcFree
.
Value
(),
err
:
nil
}
diskGC
:=
&
mockDiskGC
{
imageBytesF
reed
:
imageGcFree
.
Value
(),
err
:
nil
}
nodeRef
:=
&
clientv1
.
ObjectReference
{
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
}
nodeRef
:=
&
clientv1
.
ObjectReference
{
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
}
config
:=
Config
{
config
:=
Config
{
...
@@ -773,7 +782,8 @@ func TestNodeReclaimFuncs(t *testing.T) {
...
@@ -773,7 +782,8 @@ func TestNodeReclaimFuncs(t *testing.T) {
manager
:=
&
managerImpl
{
manager
:=
&
managerImpl
{
clock
:
fakeClock
,
clock
:
fakeClock
,
killPodFunc
:
podKiller
.
killPodNow
,
killPodFunc
:
podKiller
.
killPodNow
,
imageGC
:
imageGC
,
imageGC
:
diskGC
,
containerGC
:
diskGC
,
config
:
config
,
config
:
config
,
recorder
:
&
record
.
FakeRecorder
{},
recorder
:
&
record
.
FakeRecorder
{},
summaryProvider
:
summaryProvider
,
summaryProvider
:
summaryProvider
,
...
@@ -801,7 +811,7 @@ func TestNodeReclaimFuncs(t *testing.T) {
...
@@ -801,7 +811,7 @@ func TestNodeReclaimFuncs(t *testing.T) {
}
}
// verify image gc was invoked
// verify image gc was invoked
if
!
imageGC
.
i
nvoked
{
if
!
diskGC
.
imageGCInvoked
||
!
diskGC
.
containerGCI
nvoked
{
t
.
Errorf
(
"Manager should have invoked image gc"
)
t
.
Errorf
(
"Manager should have invoked image gc"
)
}
}
...
@@ -811,7 +821,8 @@ func TestNodeReclaimFuncs(t *testing.T) {
...
@@ -811,7 +821,8 @@ func TestNodeReclaimFuncs(t *testing.T) {
}
}
// reset state
// reset state
imageGC
.
invoked
=
false
diskGC
.
imageGCInvoked
=
false
diskGC
.
containerGCInvoked
=
false
// remove disk pressure
// remove disk pressure
fakeClock
.
Step
(
20
*
time
.
Minute
)
fakeClock
.
Step
(
20
*
time
.
Minute
)
...
@@ -833,8 +844,8 @@ func TestNodeReclaimFuncs(t *testing.T) {
...
@@ -833,8 +844,8 @@ func TestNodeReclaimFuncs(t *testing.T) {
t
.
Errorf
(
"Manager should report disk pressure"
)
t
.
Errorf
(
"Manager should report disk pressure"
)
}
}
// ensure
image
gc was invoked
// ensure
disk
gc was invoked
if
!
imageGC
.
i
nvoked
{
if
!
diskGC
.
imageGCInvoked
||
!
diskGC
.
containerGCI
nvoked
{
t
.
Errorf
(
"Manager should have invoked image gc"
)
t
.
Errorf
(
"Manager should have invoked image gc"
)
}
}
...
@@ -850,8 +861,9 @@ func TestNodeReclaimFuncs(t *testing.T) {
...
@@ -850,8 +861,9 @@ func TestNodeReclaimFuncs(t *testing.T) {
// reduce disk pressure
// reduce disk pressure
fakeClock
.
Step
(
1
*
time
.
Minute
)
fakeClock
.
Step
(
1
*
time
.
Minute
)
summaryProvider
.
result
=
summaryStatsMaker
(
"16Gi"
,
"200Gi"
,
podStats
)
summaryProvider
.
result
=
summaryStatsMaker
(
"16Gi"
,
"200Gi"
,
podStats
)
imageGC
.
invoked
=
false
// reset state
diskGC
.
imageGCInvoked
=
false
// reset state
podKiller
.
pod
=
nil
// reset state
diskGC
.
containerGCInvoked
=
false
// reset state
podKiller
.
pod
=
nil
// reset state
manager
.
synchronize
(
diskInfoProvider
,
activePodsFunc
,
nodeProvider
)
manager
.
synchronize
(
diskInfoProvider
,
activePodsFunc
,
nodeProvider
)
// we should have disk pressure (because transition period not yet met)
// we should have disk pressure (because transition period not yet met)
...
@@ -860,7 +872,7 @@ func TestNodeReclaimFuncs(t *testing.T) {
...
@@ -860,7 +872,7 @@ func TestNodeReclaimFuncs(t *testing.T) {
}
}
// no image gc should have occurred
// no image gc should have occurred
if
imageGC
.
i
nvoked
{
if
diskGC
.
imageGCInvoked
||
diskGC
.
containerGCI
nvoked
{
t
.
Errorf
(
"Manager chose to perform image gc when it was not neeed"
)
t
.
Errorf
(
"Manager chose to perform image gc when it was not neeed"
)
}
}
...
@@ -872,8 +884,9 @@ func TestNodeReclaimFuncs(t *testing.T) {
...
@@ -872,8 +884,9 @@ func TestNodeReclaimFuncs(t *testing.T) {
// move the clock past transition period to ensure that we stop reporting pressure
// move the clock past transition period to ensure that we stop reporting pressure
fakeClock
.
Step
(
5
*
time
.
Minute
)
fakeClock
.
Step
(
5
*
time
.
Minute
)
summaryProvider
.
result
=
summaryStatsMaker
(
"16Gi"
,
"200Gi"
,
podStats
)
summaryProvider
.
result
=
summaryStatsMaker
(
"16Gi"
,
"200Gi"
,
podStats
)
imageGC
.
invoked
=
false
// reset state
diskGC
.
imageGCInvoked
=
false
// reset state
podKiller
.
pod
=
nil
// reset state
diskGC
.
containerGCInvoked
=
false
// reset state
podKiller
.
pod
=
nil
// reset state
manager
.
synchronize
(
diskInfoProvider
,
activePodsFunc
,
nodeProvider
)
manager
.
synchronize
(
diskInfoProvider
,
activePodsFunc
,
nodeProvider
)
// we should not have disk pressure (because transition period met)
// we should not have disk pressure (because transition period met)
...
@@ -882,7 +895,7 @@ func TestNodeReclaimFuncs(t *testing.T) {
...
@@ -882,7 +895,7 @@ func TestNodeReclaimFuncs(t *testing.T) {
}
}
// no image gc should have occurred
// no image gc should have occurred
if
imageGC
.
i
nvoked
{
if
diskGC
.
imageGCInvoked
||
diskGC
.
containerGCI
nvoked
{
t
.
Errorf
(
"Manager chose to perform image gc when it was not neeed"
)
t
.
Errorf
(
"Manager chose to perform image gc when it was not neeed"
)
}
}
...
@@ -943,7 +956,7 @@ func TestInodePressureNodeFsInodes(t *testing.T) {
...
@@ -943,7 +956,7 @@ func TestInodePressureNodeFsInodes(t *testing.T) {
podKiller
:=
&
mockPodKiller
{}
podKiller
:=
&
mockPodKiller
{}
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
imageGC
:=
&
mockImageGC
{
f
reed
:
int64
(
0
),
err
:
nil
}
diskGC
:=
&
mockDiskGC
{
imageBytesF
reed
:
int64
(
0
),
err
:
nil
}
nodeRef
:=
&
clientv1
.
ObjectReference
{
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
}
nodeRef
:=
&
clientv1
.
ObjectReference
{
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
}
config
:=
Config
{
config
:=
Config
{
...
@@ -971,7 +984,8 @@ func TestInodePressureNodeFsInodes(t *testing.T) {
...
@@ -971,7 +984,8 @@ func TestInodePressureNodeFsInodes(t *testing.T) {
manager
:=
&
managerImpl
{
manager
:=
&
managerImpl
{
clock
:
fakeClock
,
clock
:
fakeClock
,
killPodFunc
:
podKiller
.
killPodNow
,
killPodFunc
:
podKiller
.
killPodNow
,
imageGC
:
imageGC
,
imageGC
:
diskGC
,
containerGC
:
diskGC
,
config
:
config
,
config
:
config
,
recorder
:
&
record
.
FakeRecorder
{},
recorder
:
&
record
.
FakeRecorder
{},
summaryProvider
:
summaryProvider
,
summaryProvider
:
summaryProvider
,
...
@@ -1144,7 +1158,7 @@ func TestCriticalPodsAreNotEvicted(t *testing.T) {
...
@@ -1144,7 +1158,7 @@ func TestCriticalPodsAreNotEvicted(t *testing.T) {
podKiller
:=
&
mockPodKiller
{}
podKiller
:=
&
mockPodKiller
{}
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
imageGC
:=
&
mockImageGC
{
f
reed
:
int64
(
0
),
err
:
nil
}
diskGC
:=
&
mockDiskGC
{
imageBytesF
reed
:
int64
(
0
),
err
:
nil
}
nodeRef
:=
&
clientv1
.
ObjectReference
{
nodeRef
:=
&
clientv1
.
ObjectReference
{
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
,
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
,
}
}
...
@@ -1174,7 +1188,8 @@ func TestCriticalPodsAreNotEvicted(t *testing.T) {
...
@@ -1174,7 +1188,8 @@ func TestCriticalPodsAreNotEvicted(t *testing.T) {
manager
:=
&
managerImpl
{
manager
:=
&
managerImpl
{
clock
:
fakeClock
,
clock
:
fakeClock
,
killPodFunc
:
podKiller
.
killPodNow
,
killPodFunc
:
podKiller
.
killPodNow
,
imageGC
:
imageGC
,
imageGC
:
diskGC
,
containerGC
:
diskGC
,
config
:
config
,
config
:
config
,
recorder
:
&
record
.
FakeRecorder
{},
recorder
:
&
record
.
FakeRecorder
{},
summaryProvider
:
summaryProvider
,
summaryProvider
:
summaryProvider
,
...
@@ -1276,7 +1291,7 @@ func TestAllocatableMemoryPressure(t *testing.T) {
...
@@ -1276,7 +1291,7 @@ func TestAllocatableMemoryPressure(t *testing.T) {
podKiller
:=
&
mockPodKiller
{}
podKiller
:=
&
mockPodKiller
{}
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
diskInfoProvider
:=
&
mockDiskInfoProvider
{
dedicatedImageFs
:
false
}
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
nodeProvider
:=
newMockNodeProvider
(
v1
.
ResourceList
{
v1
.
ResourceMemory
:
*
quantityMustParse
(
"2Gi"
)})
imageGC
:=
&
mockImageGC
{
f
reed
:
int64
(
0
),
err
:
nil
}
diskGC
:=
&
mockDiskGC
{
imageBytesF
reed
:
int64
(
0
),
err
:
nil
}
nodeRef
:=
&
clientv1
.
ObjectReference
{
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
}
nodeRef
:=
&
clientv1
.
ObjectReference
{
Kind
:
"Node"
,
Name
:
"test"
,
UID
:
types
.
UID
(
"test"
),
Namespace
:
""
}
config
:=
Config
{
config
:=
Config
{
...
@@ -1296,7 +1311,8 @@ func TestAllocatableMemoryPressure(t *testing.T) {
...
@@ -1296,7 +1311,8 @@ func TestAllocatableMemoryPressure(t *testing.T) {
manager
:=
&
managerImpl
{
manager
:=
&
managerImpl
{
clock
:
fakeClock
,
clock
:
fakeClock
,
killPodFunc
:
podKiller
.
killPodNow
,
killPodFunc
:
podKiller
.
killPodNow
,
imageGC
:
imageGC
,
imageGC
:
diskGC
,
containerGC
:
diskGC
,
config
:
config
,
config
:
config
,
recorder
:
&
record
.
FakeRecorder
{},
recorder
:
&
record
.
FakeRecorder
{},
summaryProvider
:
summaryProvider
,
summaryProvider
:
summaryProvider
,
...
...
pkg/kubelet/eviction/helpers.go
View file @
889afa5e
...
@@ -1019,32 +1019,34 @@ func PodIsEvicted(podStatus v1.PodStatus) bool {
...
@@ -1019,32 +1019,34 @@ func PodIsEvicted(podStatus v1.PodStatus) bool {
}
}
// buildResourceToNodeReclaimFuncs returns reclaim functions associated with resources.
// buildResourceToNodeReclaimFuncs returns reclaim functions associated with resources.
func
buildResourceToNodeReclaimFuncs
(
imageGC
ImageGC
,
withImageFs
bool
)
map
[
v1
.
ResourceName
]
nodeReclaimFuncs
{
func
buildResourceToNodeReclaimFuncs
(
imageGC
ImageGC
,
containerGC
ContainerGC
,
withImageFs
bool
)
map
[
v1
.
ResourceName
]
nodeReclaimFuncs
{
resourceToReclaimFunc
:=
map
[
v1
.
ResourceName
]
nodeReclaimFuncs
{}
resourceToReclaimFunc
:=
map
[
v1
.
ResourceName
]
nodeReclaimFuncs
{}
// usage of an imagefs is optional
// usage of an imagefs is optional
if
withImageFs
{
if
withImageFs
{
// with an imagefs, nodefs pressure should just delete logs
// with an imagefs, nodefs pressure should just delete logs
resourceToReclaimFunc
[
resourceNodeFs
]
=
nodeReclaimFuncs
{
deleteLogs
()
}
resourceToReclaimFunc
[
resourceNodeFs
]
=
nodeReclaimFuncs
{}
resourceToReclaimFunc
[
resourceNodeFsInodes
]
=
nodeReclaimFuncs
{
deleteLogs
()
}
resourceToReclaimFunc
[
resourceNodeFsInodes
]
=
nodeReclaimFuncs
{}
// with an imagefs, imagefs pressure should delete unused images
// with an imagefs, imagefs pressure should delete unused images
resourceToReclaimFunc
[
resourceImageFs
]
=
nodeReclaimFuncs
{
deleteImages
(
imageGC
,
true
)}
resourceToReclaimFunc
[
resourceImageFs
]
=
nodeReclaimFuncs
{
delete
TerminatedContainers
(
containerGC
),
delete
Images
(
imageGC
,
true
)}
resourceToReclaimFunc
[
resourceImageFsInodes
]
=
nodeReclaimFuncs
{
deleteImages
(
imageGC
,
false
)}
resourceToReclaimFunc
[
resourceImageFsInodes
]
=
nodeReclaimFuncs
{
delete
TerminatedContainers
(
containerGC
),
delete
Images
(
imageGC
,
false
)}
}
else
{
}
else
{
// without an imagefs, nodefs pressure should delete logs, and unused images
// without an imagefs, nodefs pressure should delete logs, and unused images
// since imagefs and nodefs share a common device, they share common reclaim functions
// since imagefs and nodefs share a common device, they share common reclaim functions
resourceToReclaimFunc
[
resourceNodeFs
]
=
nodeReclaimFuncs
{
delete
Logs
(
),
deleteImages
(
imageGC
,
true
)}
resourceToReclaimFunc
[
resourceNodeFs
]
=
nodeReclaimFuncs
{
delete
TerminatedContainers
(
containerGC
),
deleteImages
(
imageGC
,
true
)}
resourceToReclaimFunc
[
resourceNodeFsInodes
]
=
nodeReclaimFuncs
{
delete
Logs
(
),
deleteImages
(
imageGC
,
false
)}
resourceToReclaimFunc
[
resourceNodeFsInodes
]
=
nodeReclaimFuncs
{
delete
TerminatedContainers
(
containerGC
),
deleteImages
(
imageGC
,
false
)}
resourceToReclaimFunc
[
resourceImageFs
]
=
nodeReclaimFuncs
{
delete
Logs
(
),
deleteImages
(
imageGC
,
true
)}
resourceToReclaimFunc
[
resourceImageFs
]
=
nodeReclaimFuncs
{
delete
TerminatedContainers
(
containerGC
),
deleteImages
(
imageGC
,
true
)}
resourceToReclaimFunc
[
resourceImageFsInodes
]
=
nodeReclaimFuncs
{
delete
Logs
(
),
deleteImages
(
imageGC
,
false
)}
resourceToReclaimFunc
[
resourceImageFsInodes
]
=
nodeReclaimFuncs
{
delete
TerminatedContainers
(
containerGC
),
deleteImages
(
imageGC
,
false
)}
}
}
return
resourceToReclaimFunc
return
resourceToReclaimFunc
}
}
// delete
Logs will delete log
s to free up disk pressure.
// delete
TerminatedContainers will delete terminated container
s to free up disk pressure.
func
delete
Logs
(
)
nodeReclaimFunc
{
func
delete
TerminatedContainers
(
containerGC
ContainerGC
)
nodeReclaimFunc
{
return
func
()
(
*
resource
.
Quantity
,
error
)
{
return
func
()
(
*
resource
.
Quantity
,
error
)
{
// TODO: not yet supported.
glog
.
Infof
(
"eviction manager: attempting to delete unused containers"
)
return
resource
.
NewQuantity
(
int64
(
0
),
resource
.
BinarySI
),
nil
err
:=
containerGC
.
DeleteAllUnusedContainers
()
// Calculating bytes freed is not yet supported.
return
resource
.
NewQuantity
(
int64
(
0
),
resource
.
BinarySI
),
err
}
}
}
}
...
...
pkg/kubelet/eviction/types.go
View file @
889afa5e
...
@@ -81,6 +81,13 @@ type ImageGC interface {
...
@@ -81,6 +81,13 @@ type ImageGC interface {
DeleteUnusedImages
()
(
int64
,
error
)
DeleteUnusedImages
()
(
int64
,
error
)
}
}
// ContainerGC is responsible for performing garbage collection of unused containers.
type
ContainerGC
interface
{
// DeleteAllUnusedContainers deletes all unused containers, even those that belong to pods that are terminated, but not deleted.
// It returns an error if it is unsuccessful.
DeleteAllUnusedContainers
()
error
}
// KillPodFunc kills a pod.
// KillPodFunc kills a pod.
// The pod status is updated, and then it is killed with the specified grace period.
// The pod status is updated, and then it is killed with the specified grace period.
// This function must block until either the pod is killed or an error is encountered.
// This function must block until either the pod is killed or an error is encountered.
...
...
pkg/kubelet/kubelet.go
View file @
889afa5e
...
@@ -671,7 +671,7 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub
...
@@ -671,7 +671,7 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub
klet
.
updatePodCIDR
(
kubeCfg
.
PodCIDR
)
klet
.
updatePodCIDR
(
kubeCfg
.
PodCIDR
)
// setup containerGC
// setup containerGC
containerGC
,
err
:=
kubecontainer
.
NewContainerGC
(
klet
.
containerRuntime
,
containerGCPolicy
)
containerGC
,
err
:=
kubecontainer
.
NewContainerGC
(
klet
.
containerRuntime
,
containerGCPolicy
,
klet
.
sourcesReady
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -761,7 +761,7 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub
...
@@ -761,7 +761,7 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub
klet
.
setNodeStatusFuncs
=
klet
.
defaultNodeStatusFuncs
()
klet
.
setNodeStatusFuncs
=
klet
.
defaultNodeStatusFuncs
()
// setup eviction manager
// setup eviction manager
evictionManager
,
evictionAdmitHandler
:=
eviction
.
NewManager
(
klet
.
resourceAnalyzer
,
evictionConfig
,
killPodNow
(
klet
.
podWorkers
,
kubeDeps
.
Recorder
),
klet
.
imageManager
,
kubeDeps
.
Recorder
,
nodeRef
,
klet
.
clock
)
evictionManager
,
evictionAdmitHandler
:=
eviction
.
NewManager
(
klet
.
resourceAnalyzer
,
evictionConfig
,
killPodNow
(
klet
.
podWorkers
,
kubeDeps
.
Recorder
),
klet
.
imageManager
,
k
let
.
containerGC
,
k
ubeDeps
.
Recorder
,
nodeRef
,
klet
.
clock
)
klet
.
evictionManager
=
evictionManager
klet
.
evictionManager
=
evictionManager
klet
.
admitHandlers
.
AddPodAdmitHandler
(
evictionAdmitHandler
)
klet
.
admitHandlers
.
AddPodAdmitHandler
(
evictionAdmitHandler
)
...
@@ -1184,7 +1184,7 @@ func (kl *Kubelet) setupDataDirs() error {
...
@@ -1184,7 +1184,7 @@ func (kl *Kubelet) setupDataDirs() error {
func
(
kl
*
Kubelet
)
StartGarbageCollection
()
{
func
(
kl
*
Kubelet
)
StartGarbageCollection
()
{
loggedContainerGCFailure
:=
false
loggedContainerGCFailure
:=
false
go
wait
.
Until
(
func
()
{
go
wait
.
Until
(
func
()
{
if
err
:=
kl
.
containerGC
.
GarbageCollect
(
kl
.
sourcesReady
.
AllReady
()
);
err
!=
nil
{
if
err
:=
kl
.
containerGC
.
GarbageCollect
();
err
!=
nil
{
glog
.
Errorf
(
"Container garbage collection failed: %v"
,
err
)
glog
.
Errorf
(
"Container garbage collection failed: %v"
,
err
)
kl
.
recorder
.
Eventf
(
kl
.
nodeRef
,
v1
.
EventTypeWarning
,
events
.
ContainerGCFailed
,
err
.
Error
())
kl
.
recorder
.
Eventf
(
kl
.
nodeRef
,
v1
.
EventTypeWarning
,
events
.
ContainerGCFailed
,
err
.
Error
())
loggedContainerGCFailure
=
true
loggedContainerGCFailure
=
true
...
...
pkg/kubelet/kubelet_test.go
View file @
889afa5e
...
@@ -270,7 +270,7 @@ func newTestKubeletWithImageList(
...
@@ -270,7 +270,7 @@ func newTestKubeletWithImageList(
Namespace
:
""
,
Namespace
:
""
,
}
}
// setup eviction manager
// setup eviction manager
evictionManager
,
evictionAdmitHandler
:=
eviction
.
NewManager
(
kubelet
.
resourceAnalyzer
,
eviction
.
Config
{},
killPodNow
(
kubelet
.
podWorkers
,
fakeRecorder
),
kubelet
.
imageManager
,
fakeRecorder
,
nodeRef
,
kubelet
.
clock
)
evictionManager
,
evictionAdmitHandler
:=
eviction
.
NewManager
(
kubelet
.
resourceAnalyzer
,
eviction
.
Config
{},
killPodNow
(
kubelet
.
podWorkers
,
fakeRecorder
),
kubelet
.
imageManager
,
kubelet
.
containerGC
,
fakeRecorder
,
nodeRef
,
kubelet
.
clock
)
kubelet
.
evictionManager
=
evictionManager
kubelet
.
evictionManager
=
evictionManager
kubelet
.
admitHandlers
.
AddPodAdmitHandler
(
evictionAdmitHandler
)
kubelet
.
admitHandlers
.
AddPodAdmitHandler
(
evictionAdmitHandler
)
...
...
pkg/kubelet/kuberuntime/kuberuntime_gc.go
View file @
889afa5e
...
@@ -209,7 +209,7 @@ func (cgc *containerGC) evictableContainers(minAge time.Duration) (containersByE
...
@@ -209,7 +209,7 @@ func (cgc *containerGC) evictableContainers(minAge time.Duration) (containersByE
}
}
// evict all containers that are evictable
// evict all containers that are evictable
func
(
cgc
*
containerGC
)
evictContainers
(
gcPolicy
kubecontainer
.
ContainerGCPolicy
,
allSourcesReady
bool
)
error
{
func
(
cgc
*
containerGC
)
evictContainers
(
gcPolicy
kubecontainer
.
ContainerGCPolicy
,
allSourcesReady
bool
,
evictNonDeletedPods
bool
)
error
{
// Separate containers by evict units.
// Separate containers by evict units.
evictUnits
,
err
:=
cgc
.
evictableContainers
(
gcPolicy
.
MinAge
)
evictUnits
,
err
:=
cgc
.
evictableContainers
(
gcPolicy
.
MinAge
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -219,7 +219,7 @@ func (cgc *containerGC) evictContainers(gcPolicy kubecontainer.ContainerGCPolicy
...
@@ -219,7 +219,7 @@ func (cgc *containerGC) evictContainers(gcPolicy kubecontainer.ContainerGCPolicy
// Remove deleted pod containers if all sources are ready.
// Remove deleted pod containers if all sources are ready.
if
allSourcesReady
{
if
allSourcesReady
{
for
key
,
unit
:=
range
evictUnits
{
for
key
,
unit
:=
range
evictUnits
{
if
cgc
.
isPodDeleted
(
key
.
uid
)
{
if
cgc
.
isPodDeleted
(
key
.
uid
)
||
evictNonDeletedPods
{
cgc
.
removeOldestN
(
unit
,
len
(
unit
))
// Remove all.
cgc
.
removeOldestN
(
unit
,
len
(
unit
))
// Remove all.
delete
(
evictUnits
,
key
)
delete
(
evictUnits
,
key
)
}
}
...
@@ -261,7 +261,7 @@ func (cgc *containerGC) evictContainers(gcPolicy kubecontainer.ContainerGCPolicy
...
@@ -261,7 +261,7 @@ func (cgc *containerGC) evictContainers(gcPolicy kubecontainer.ContainerGCPolicy
// 2. contains no containers.
// 2. contains no containers.
// 3. belong to a non-existent (i.e., already removed) pod, or is not the
// 3. belong to a non-existent (i.e., already removed) pod, or is not the
// most recently created sandbox for the pod.
// most recently created sandbox for the pod.
func
(
cgc
*
containerGC
)
evictSandboxes
()
error
{
func
(
cgc
*
containerGC
)
evictSandboxes
(
evictNonDeletedPods
bool
)
error
{
containers
,
err
:=
cgc
.
manager
.
getKubeletContainers
(
true
)
containers
,
err
:=
cgc
.
manager
.
getKubeletContainers
(
true
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
...
@@ -307,7 +307,7 @@ func (cgc *containerGC) evictSandboxes() error {
...
@@ -307,7 +307,7 @@ func (cgc *containerGC) evictSandboxes() error {
}
}
for
podUID
,
sandboxes
:=
range
sandboxesByPod
{
for
podUID
,
sandboxes
:=
range
sandboxesByPod
{
if
cgc
.
isPodDeleted
(
podUID
)
{
if
cgc
.
isPodDeleted
(
podUID
)
||
evictNonDeletedPods
{
// Remove all evictable sandboxes if the pod has been removed.
// Remove all evictable sandboxes if the pod has been removed.
// Note that the latest dead sandbox is also removed if there is
// Note that the latest dead sandbox is also removed if there is
// already an active one.
// already an active one.
...
@@ -367,14 +367,14 @@ func (cgc *containerGC) evictPodLogsDirectories(allSourcesReady bool) error {
...
@@ -367,14 +367,14 @@ func (cgc *containerGC) evictPodLogsDirectories(allSourcesReady bool) error {
// * removes oldest dead containers by enforcing gcPolicy.MaxContainers.
// * removes oldest dead containers by enforcing gcPolicy.MaxContainers.
// * gets evictable sandboxes which are not ready and contains no containers.
// * gets evictable sandboxes which are not ready and contains no containers.
// * removes evictable sandboxes.
// * removes evictable sandboxes.
func
(
cgc
*
containerGC
)
GarbageCollect
(
gcPolicy
kubecontainer
.
ContainerGCPolicy
,
allSourcesReady
bool
)
error
{
func
(
cgc
*
containerGC
)
GarbageCollect
(
gcPolicy
kubecontainer
.
ContainerGCPolicy
,
allSourcesReady
bool
,
evictNonDeletedPods
bool
)
error
{
// Remove evictable containers
// Remove evictable containers
if
err
:=
cgc
.
evictContainers
(
gcPolicy
,
allSourcesReady
);
err
!=
nil
{
if
err
:=
cgc
.
evictContainers
(
gcPolicy
,
allSourcesReady
,
evictNonDeletedPods
);
err
!=
nil
{
return
err
return
err
}
}
// Remove sandboxes with zero containers
// Remove sandboxes with zero containers
if
err
:=
cgc
.
evictSandboxes
();
err
!=
nil
{
if
err
:=
cgc
.
evictSandboxes
(
evictNonDeletedPods
);
err
!=
nil
{
return
err
return
err
}
}
...
...
pkg/kubelet/kuberuntime/kuberuntime_gc_test.go
View file @
889afa5e
This diff is collapsed.
Click to expand it.
pkg/kubelet/kuberuntime/kuberuntime_manager.go
View file @
889afa5e
...
@@ -877,8 +877,8 @@ func (m *kubeGenericRuntimeManager) GetNetNS(_ kubecontainer.ContainerID) (strin
...
@@ -877,8 +877,8 @@ func (m *kubeGenericRuntimeManager) GetNetNS(_ kubecontainer.ContainerID) (strin
}
}
// GarbageCollect removes dead containers using the specified container gc policy.
// GarbageCollect removes dead containers using the specified container gc policy.
func
(
m
*
kubeGenericRuntimeManager
)
GarbageCollect
(
gcPolicy
kubecontainer
.
ContainerGCPolicy
,
allSourcesReady
bool
)
error
{
func
(
m
*
kubeGenericRuntimeManager
)
GarbageCollect
(
gcPolicy
kubecontainer
.
ContainerGCPolicy
,
allSourcesReady
bool
,
evictNonDeletedPods
bool
)
error
{
return
m
.
containerGC
.
GarbageCollect
(
gcPolicy
,
allSourcesReady
)
return
m
.
containerGC
.
GarbageCollect
(
gcPolicy
,
allSourcesReady
,
evictNonDeletedPods
)
}
}
// GetPodContainerID gets pod sandbox ID
// GetPodContainerID gets pod sandbox ID
...
...
pkg/kubelet/rkt/rkt.go
View file @
889afa5e
...
@@ -1955,7 +1955,7 @@ func (r *Runtime) getPodSystemdServiceFiles() ([]os.FileInfo, error) {
...
@@ -1955,7 +1955,7 @@ func (r *Runtime) getPodSystemdServiceFiles() ([]os.FileInfo, error) {
// - If the number of containers exceeds gcPolicy.MaxContainers,
// - If the number of containers exceeds gcPolicy.MaxContainers,
// then containers whose ages are older than gcPolicy.minAge will
// then containers whose ages are older than gcPolicy.minAge will
// be removed.
// be removed.
func
(
r
*
Runtime
)
GarbageCollect
(
gcPolicy
kubecontainer
.
ContainerGCPolicy
,
allSourcesReady
bool
)
error
{
func
(
r
*
Runtime
)
GarbageCollect
(
gcPolicy
kubecontainer
.
ContainerGCPolicy
,
allSourcesReady
bool
,
_
bool
)
error
{
var
errlist
[]
error
var
errlist
[]
error
var
totalInactiveContainers
int
var
totalInactiveContainers
int
var
inactivePods
[]
*
rktapi
.
Pod
var
inactivePods
[]
*
rktapi
.
Pod
...
...
pkg/kubelet/rkt/rkt_test.go
View file @
889afa5e
...
@@ -1831,7 +1831,8 @@ func TestGarbageCollect(t *testing.T) {
...
@@ -1831,7 +1831,8 @@ func TestGarbageCollect(t *testing.T) {
}
}
allSourcesReady
:=
true
allSourcesReady
:=
true
err
:=
rkt
.
GarbageCollect
(
tt
.
gcPolicy
,
allSourcesReady
)
evictNonDeletedPods
:=
false
err
:=
rkt
.
GarbageCollect
(
tt
.
gcPolicy
,
allSourcesReady
,
evictNonDeletedPods
)
assert
.
NoError
(
t
,
err
,
testCaseHint
)
assert
.
NoError
(
t
,
err
,
testCaseHint
)
sort
.
Sort
(
sortedStringList
(
tt
.
expectedCommands
))
sort
.
Sort
(
sortedStringList
(
tt
.
expectedCommands
))
...
...
pkg/kubelet/runonce_test.go
View file @
889afa5e
...
@@ -126,7 +126,7 @@ func TestRunOnce(t *testing.T) {
...
@@ -126,7 +126,7 @@ func TestRunOnce(t *testing.T) {
fakeKillPodFunc
:=
func
(
pod
*
v1
.
Pod
,
podStatus
v1
.
PodStatus
,
gracePeriodOverride
*
int64
)
error
{
fakeKillPodFunc
:=
func
(
pod
*
v1
.
Pod
,
podStatus
v1
.
PodStatus
,
gracePeriodOverride
*
int64
)
error
{
return
nil
return
nil
}
}
evictionManager
,
evictionAdmitHandler
:=
eviction
.
NewManager
(
kb
.
resourceAnalyzer
,
eviction
.
Config
{},
fakeKillPodFunc
,
nil
,
kb
.
recorder
,
nodeRef
,
kb
.
clock
)
evictionManager
,
evictionAdmitHandler
:=
eviction
.
NewManager
(
kb
.
resourceAnalyzer
,
eviction
.
Config
{},
fakeKillPodFunc
,
nil
,
nil
,
kb
.
recorder
,
nodeRef
,
kb
.
clock
)
kb
.
evictionManager
=
evictionManager
kb
.
evictionManager
=
evictionManager
kb
.
admitHandlers
.
AddPodAdmitHandler
(
evictionAdmitHandler
)
kb
.
admitHandlers
.
AddPodAdmitHandler
(
evictionAdmitHandler
)
...
...
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