Skip to content

Commit 847be85

Browse files
authored
Merge pull request kubernetes#128657 from ffromani/unshare-containermap-among-managers
node: cm: don't share containerMap instances between managers
2 parents aee1a91 + 2a99bfc commit 847be85

File tree

4 files changed

+100
-12
lines changed

4 files changed

+100
-12
lines changed

pkg/kubelet/cm/container_manager_linux.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -575,13 +575,13 @@ func (cm *containerManagerImpl) Start(ctx context.Context, node *v1.Node,
575575
}
576576

577577
// Initialize CPU manager
578-
err := cm.cpuManager.Start(cpumanager.ActivePodsFunc(activePods), sourcesReady, podStatusProvider, runtimeService, containerMap)
578+
err := cm.cpuManager.Start(cpumanager.ActivePodsFunc(activePods), sourcesReady, podStatusProvider, runtimeService, containerMap.Clone())
579579
if err != nil {
580580
return fmt.Errorf("start cpu manager error: %w", err)
581581
}
582582

583583
// Initialize memory manager
584-
err = cm.memoryManager.Start(memorymanager.ActivePodsFunc(activePods), sourcesReady, podStatusProvider, runtimeService, containerMap)
584+
err = cm.memoryManager.Start(memorymanager.ActivePodsFunc(activePods), sourcesReady, podStatusProvider, runtimeService, containerMap.Clone())
585585
if err != nil {
586586
return fmt.Errorf("start memory manager error: %w", err)
587587
}
@@ -643,7 +643,7 @@ func (cm *containerManagerImpl) Start(ctx context.Context, node *v1.Node,
643643
}
644644

645645
// Starts device manager.
646-
if err := cm.deviceManager.Start(devicemanager.ActivePodsFunc(activePods), sourcesReady, containerMap, containerRunningSet); err != nil {
646+
if err := cm.deviceManager.Start(devicemanager.ActivePodsFunc(activePods), sourcesReady, containerMap.Clone(), containerRunningSet); err != nil {
647647
return err
648648
}
649649

pkg/kubelet/cm/container_manager_windows.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ package cm
2525
import (
2626
"context"
2727
"fmt"
28+
"sync"
29+
2830
utilfeature "k8s.io/apiserver/pkg/util/feature"
2931
kubefeatures "k8s.io/kubernetes/pkg/features"
3032
"k8s.io/kubernetes/pkg/kubelet/cm/memorymanager"
31-
"sync"
3233

3334
"k8s.io/klog/v2"
3435
"k8s.io/mount-utils"
@@ -96,14 +97,14 @@ func (cm *containerManagerImpl) Start(ctx context.Context, node *v1.Node,
9697

9798
// Initialize CPU manager
9899
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.WindowsCPUAndMemoryAffinity) {
99-
err := cm.cpuManager.Start(cpumanager.ActivePodsFunc(activePods), sourcesReady, podStatusProvider, runtimeService, containerMap)
100+
err := cm.cpuManager.Start(cpumanager.ActivePodsFunc(activePods), sourcesReady, podStatusProvider, runtimeService, containerMap.Clone())
100101
if err != nil {
101102
return fmt.Errorf("start cpu manager error: %v", err)
102103
}
103104
}
104105

105106
// Starts device manager.
106-
if err := cm.deviceManager.Start(devicemanager.ActivePodsFunc(activePods), sourcesReady, containerMap, containerRunningSet); err != nil {
107+
if err := cm.deviceManager.Start(devicemanager.ActivePodsFunc(activePods), sourcesReady, containerMap.Clone(), containerRunningSet); err != nil {
107108
return err
108109
}
109110

pkg/kubelet/cm/containermap/container_map.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,35 @@ import (
2020
"fmt"
2121
)
2222

23-
// ContainerMap maps (containerID)->(*v1.Pod, *v1.Container)
24-
type ContainerMap map[string]struct {
23+
// cmItem (ContainerMap ITEM) is a pair podUID, containerName
24+
type cmItem struct {
2525
podUID string
2626
containerName string
2727
}
2828

29+
// ContainerMap maps (containerID)->(podUID, containerName)
30+
type ContainerMap map[string]cmItem
31+
2932
// NewContainerMap creates a new ContainerMap struct
3033
func NewContainerMap() ContainerMap {
3134
return make(ContainerMap)
3235
}
3336

37+
// Clone creates a deep copy of the ContainerMap
38+
func (cm ContainerMap) Clone() ContainerMap {
39+
ret := make(ContainerMap, len(cm))
40+
for key, val := range cm {
41+
ret[key] = val
42+
}
43+
return ret
44+
}
45+
3446
// Add adds a mapping of (containerID)->(podUID, containerName) to the ContainerMap
3547
func (cm ContainerMap) Add(podUID, containerName, containerID string) {
36-
cm[containerID] = struct {
37-
podUID string
38-
containerName string
39-
}{podUID, containerName}
48+
cm[containerID] = cmItem{
49+
podUID: podUID,
50+
containerName: containerName,
51+
}
4052
}
4153

4254
// RemoveByContainerID removes a mapping of (containerID)->(podUID, containerName) from the ContainerMap

pkg/kubelet/cm/containermap/container_map_test.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,65 @@ import (
2020
"testing"
2121
)
2222

23+
func TestContainerMapCloneEqual(t *testing.T) {
24+
cm := NewContainerMap()
25+
// add random fake data
26+
cm.Add("fakePodUID-1", "fakeContainerName-a1", "fakeContainerID-A")
27+
cm.Add("fakePodUID-2", "fakeContainerName-b2", "fakeContainerID-B")
28+
cm.Add("fakePodUID-2", "fakeContainerName-c2", "fakeContainerID-C")
29+
cm.Add("fakePodUID-3", "fakeContainerName-d3", "fakeContainerID-D")
30+
cm.Add("fakePodUID-3", "fakeContainerName-e3", "fakeContainerID-E")
31+
cm.Add("fakePodUID-3", "fakeContainerName-f3", "fakeContainerID-F")
32+
33+
cloned := cm.Clone()
34+
if !areEqual(cm, cloned) {
35+
t.Fatalf("clone %+#v different from original %+#v", cloned, cm)
36+
}
37+
}
38+
39+
func TestContainerMapCloneUnshared(t *testing.T) {
40+
cm := NewContainerMap()
41+
// add random fake data
42+
cm.Add("fakePodUID-1", "fakeContainerName-a1", "fakeContainerID-A")
43+
cm.Add("fakePodUID-2", "fakeContainerName-b2", "fakeContainerID-B")
44+
cm.Add("fakePodUID-2", "fakeContainerName-c2", "fakeContainerID-C")
45+
cm.Add("fakePodUID-3", "fakeContainerName-d3", "fakeContainerID-D")
46+
cm.Add("fakePodUID-3", "fakeContainerName-e3", "fakeContainerID-E")
47+
cm.Add("fakePodUID-3", "fakeContainerName-f3", "fakeContainerID-F")
48+
49+
// early sanity check, random ID, no special meaning
50+
podUID, containerName, err := cm.GetContainerRef("fakeContainerID-C")
51+
if err != nil {
52+
t.Fatalf("unexpected error: %v", err)
53+
}
54+
if podUID != "fakePodUID-2" || containerName != "fakeContainerName-c2" {
55+
t.Fatalf("unexpected data: uid=%q name=%q", podUID, containerName)
56+
}
57+
if cID, err := cm.GetContainerID(podUID, containerName); err != nil || cID != "fakeContainerID-C" {
58+
t.Fatalf("unexpected data: cid=%q err=%v", cID, err)
59+
}
60+
61+
cloned := cm.Clone()
62+
cloned.RemoveByContainerRef("fakePodUID-2", "fakeContainerName-c2")
63+
// check is actually gone
64+
if cID, err := cloned.GetContainerID("fakePodUID-2", "fakeContainerName-c2"); err == nil || cID != "" {
65+
t.Fatalf("unexpected data found: cid=%q", cID)
66+
}
67+
68+
// check the original copy didn't change
69+
// early sanity check, random ID, no special meaning
70+
podUIDRedo, containerNameRedo, err2 := cm.GetContainerRef("fakeContainerID-C")
71+
if err != nil {
72+
t.Fatalf("unexpected error: %v", err2)
73+
}
74+
if podUIDRedo != "fakePodUID-2" || containerNameRedo != "fakeContainerName-c2" {
75+
t.Fatalf("unexpected data: uid=%q name=%q", podUIDRedo, containerNameRedo)
76+
}
77+
if cID, err := cm.GetContainerID(podUIDRedo, containerNameRedo); err != nil || cID != "fakeContainerID-C" {
78+
t.Fatalf("unexpected data: cid=%q", cID)
79+
}
80+
}
81+
2382
func TestContainerMap(t *testing.T) {
2483
testCases := []struct {
2584
podUID string
@@ -84,3 +143,19 @@ func TestContainerMap(t *testing.T) {
84143
}
85144
}
86145
}
146+
147+
func areEqual(cm1, cm2 ContainerMap) bool {
148+
if len(cm1) != len(cm2) {
149+
return false
150+
}
151+
for key1, item1 := range cm1 {
152+
item2, ok := cm2[key1]
153+
if !ok {
154+
return false
155+
}
156+
if item1 != item2 {
157+
return false
158+
}
159+
}
160+
return true
161+
}

0 commit comments

Comments
 (0)