Skip to content

Commit dfcc111

Browse files
sjenningdeads2k
authored andcommitted
UPSTREAM: 53167: Do not GC exited containers in running pods
:100644 100644 28a8d1f652... 895fd233a9... M pkg/kubelet/kubelet_pods.go :100644 100644 ed9301afe0... f2809348bf... M pkg/kubelet/kuberuntime/fake_kuberuntime_manager.go :100644 100644 063a89d6b3... 28a831d848... M pkg/kubelet/kuberuntime/kuberuntime_gc.go :100644 100644 389b1e52cc... 4a419524dd... M pkg/kubelet/kuberuntime/kuberuntime_gc_test.go :100644 100644 7e5d1d0d29... 7286bf44c0... M pkg/kubelet/kuberuntime/kuberuntime_manager.go
1 parent 3fb16cc commit dfcc111

File tree

5 files changed

+85
-63
lines changed

5 files changed

+85
-63
lines changed

pkg/kubelet/kubelet_pods.go

+10
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,16 @@ func (kl *Kubelet) podIsTerminated(pod *v1.Pod) bool {
744744
return status.Phase == v1.PodFailed || status.Phase == v1.PodSucceeded || (pod.DeletionTimestamp != nil && notRunning(status.ContainerStatuses))
745745
}
746746

747+
// IsPodTerminated returns trus if the pod with the provided UID is in a terminated state ("Failed" or "Succeeded")
748+
// or if the pod has been deleted or removed
749+
func (kl *Kubelet) IsPodTerminated(uid types.UID) bool {
750+
pod, podFound := kl.podManager.GetPodByUID(uid)
751+
if !podFound {
752+
return true
753+
}
754+
return kl.podIsTerminated(pod)
755+
}
756+
747757
// IsPodDeleted returns true if the pod is deleted. For the pod to be deleted, either:
748758
// 1. The pod object is deleted
749759
// 2. The pod's status is evicted

pkg/kubelet/kuberuntime/fake_kuberuntime_manager.go

+15-8
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,25 @@ func (f *fakeHTTP) Get(url string) (*http.Response, error) {
4242
return nil, f.err
4343
}
4444

45-
type fakePodDeletionProvider struct {
46-
pods map[types.UID]struct{}
45+
type fakePodStateProvider struct {
46+
existingPods map[types.UID]struct{}
47+
runningPods map[types.UID]struct{}
4748
}
4849

49-
func newFakePodDeletionProvider() *fakePodDeletionProvider {
50-
return &fakePodDeletionProvider{
51-
pods: make(map[types.UID]struct{}),
50+
func newFakePodStateProvider() *fakePodStateProvider {
51+
return &fakePodStateProvider{
52+
existingPods: make(map[types.UID]struct{}),
53+
runningPods: make(map[types.UID]struct{}),
5254
}
5355
}
5456

55-
func (f *fakePodDeletionProvider) IsPodDeleted(uid types.UID) bool {
56-
_, found := f.pods[uid]
57+
func (f *fakePodStateProvider) IsPodDeleted(uid types.UID) bool {
58+
_, found := f.existingPods[uid]
59+
return !found
60+
}
61+
62+
func (f *fakePodStateProvider) IsPodTerminated(uid types.UID) bool {
63+
_, found := f.runningPods[uid]
5764
return !found
5865
}
5966

@@ -77,7 +84,7 @@ func NewFakeKubeRuntimeManager(runtimeService internalapi.RuntimeService, imageS
7784
return nil, err
7885
}
7986

80-
kubeRuntimeManager.containerGC = NewContainerGC(runtimeService, newFakePodDeletionProvider(), kubeRuntimeManager)
87+
kubeRuntimeManager.containerGC = NewContainerGC(runtimeService, newFakePodStateProvider(), kubeRuntimeManager)
8188
kubeRuntimeManager.runtimeName = typedVersion.RuntimeName
8289
kubeRuntimeManager.imagePuller = images.NewImageManager(
8390
kubecontainer.FilterEventRecorder(recorder),

pkg/kubelet/kuberuntime/kuberuntime_gc.go

+15-15
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,17 @@ import (
3232

3333
// containerGC is the manager of garbage collection.
3434
type containerGC struct {
35-
client internalapi.RuntimeService
36-
manager *kubeGenericRuntimeManager
37-
podDeletionProvider podDeletionProvider
35+
client internalapi.RuntimeService
36+
manager *kubeGenericRuntimeManager
37+
podStateProvider podStateProvider
3838
}
3939

4040
// NewContainerGC creates a new containerGC.
41-
func NewContainerGC(client internalapi.RuntimeService, podDeletionProvider podDeletionProvider, manager *kubeGenericRuntimeManager) *containerGC {
41+
func NewContainerGC(client internalapi.RuntimeService, podStateProvider podStateProvider, manager *kubeGenericRuntimeManager) *containerGC {
4242
return &containerGC{
43-
client: client,
44-
manager: manager,
45-
podDeletionProvider: podDeletionProvider,
43+
client: client,
44+
manager: manager,
45+
podStateProvider: podStateProvider,
4646
}
4747
}
4848

@@ -200,7 +200,7 @@ func (cgc *containerGC) evictableContainers(minAge time.Duration) (containersByE
200200
}
201201

202202
// evict all containers that are evictable
203-
func (cgc *containerGC) evictContainers(gcPolicy kubecontainer.ContainerGCPolicy, allSourcesReady bool, evictNonDeletedPods bool) error {
203+
func (cgc *containerGC) evictContainers(gcPolicy kubecontainer.ContainerGCPolicy, allSourcesReady bool, evictTerminatedPods bool) error {
204204
// Separate containers by evict units.
205205
evictUnits, err := cgc.evictableContainers(gcPolicy.MinAge)
206206
if err != nil {
@@ -210,7 +210,7 @@ func (cgc *containerGC) evictContainers(gcPolicy kubecontainer.ContainerGCPolicy
210210
// Remove deleted pod containers if all sources are ready.
211211
if allSourcesReady {
212212
for key, unit := range evictUnits {
213-
if cgc.podDeletionProvider.IsPodDeleted(key.uid) || evictNonDeletedPods {
213+
if cgc.podStateProvider.IsPodDeleted(key.uid) || (cgc.podStateProvider.IsPodTerminated(key.uid) && evictTerminatedPods) {
214214
cgc.removeOldestN(unit, len(unit)) // Remove all.
215215
delete(evictUnits, key)
216216
}
@@ -252,7 +252,7 @@ func (cgc *containerGC) evictContainers(gcPolicy kubecontainer.ContainerGCPolicy
252252
// 2. contains no containers.
253253
// 3. belong to a non-existent (i.e., already removed) pod, or is not the
254254
// most recently created sandbox for the pod.
255-
func (cgc *containerGC) evictSandboxes(evictNonDeletedPods bool) error {
255+
func (cgc *containerGC) evictSandboxes(evictTerminatedPods bool) error {
256256
containers, err := cgc.manager.getKubeletContainers(true)
257257
if err != nil {
258258
return err
@@ -298,7 +298,7 @@ func (cgc *containerGC) evictSandboxes(evictNonDeletedPods bool) error {
298298
}
299299

300300
for podUID, sandboxes := range sandboxesByPod {
301-
if cgc.podDeletionProvider.IsPodDeleted(podUID) || evictNonDeletedPods {
301+
if cgc.podStateProvider.IsPodDeleted(podUID) || (cgc.podStateProvider.IsPodTerminated(podUID) && evictTerminatedPods) {
302302
// Remove all evictable sandboxes if the pod has been removed.
303303
// Note that the latest dead sandbox is also removed if there is
304304
// already an active one.
@@ -324,7 +324,7 @@ func (cgc *containerGC) evictPodLogsDirectories(allSourcesReady bool) error {
324324
for _, dir := range dirs {
325325
name := dir.Name()
326326
podUID := types.UID(name)
327-
if !cgc.podDeletionProvider.IsPodDeleted(podUID) {
327+
if !cgc.podStateProvider.IsPodDeleted(podUID) {
328328
continue
329329
}
330330
err := osInterface.RemoveAll(filepath.Join(podLogsRootDirectory, name))
@@ -358,14 +358,14 @@ func (cgc *containerGC) evictPodLogsDirectories(allSourcesReady bool) error {
358358
// * removes oldest dead containers by enforcing gcPolicy.MaxContainers.
359359
// * gets evictable sandboxes which are not ready and contains no containers.
360360
// * removes evictable sandboxes.
361-
func (cgc *containerGC) GarbageCollect(gcPolicy kubecontainer.ContainerGCPolicy, allSourcesReady bool, evictNonDeletedPods bool) error {
361+
func (cgc *containerGC) GarbageCollect(gcPolicy kubecontainer.ContainerGCPolicy, allSourcesReady bool, evictTerminatedPods bool) error {
362362
// Remove evictable containers
363-
if err := cgc.evictContainers(gcPolicy, allSourcesReady, evictNonDeletedPods); err != nil {
363+
if err := cgc.evictContainers(gcPolicy, allSourcesReady, evictTerminatedPods); err != nil {
364364
return err
365365
}
366366

367367
// Remove sandboxes with zero containers
368-
if err := cgc.evictSandboxes(evictNonDeletedPods); err != nil {
368+
if err := cgc.evictSandboxes(evictTerminatedPods); err != nil {
369369
return err
370370
}
371371

0 commit comments

Comments
 (0)