Skip to content

Commit 946087b

Browse files
authored
Merge pull request kubernetes#77426 from Random-Liu/remove-terminated-pod
Remove terminated pod from summary api.
2 parents 5523be3 + 11cd424 commit 946087b

File tree

4 files changed

+98
-22
lines changed

4 files changed

+98
-22
lines changed

pkg/kubelet/stats/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ go_test(
8787
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
8888
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
8989
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
90+
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
9091
"//staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2:go_default_library",
9192
"//staging/src/k8s.io/cri-api/pkg/apis/testing:go_default_library",
9293
"//vendor/github.com/golang/mock/gomock:go_default_library",

pkg/kubelet/stats/cri_stats_provider.go

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ func (p *criStatsProvider) listPodStats(updateCPUNanoCoreUsage bool) ([]statsapi
137137
if err != nil {
138138
return nil, fmt.Errorf("failed to list all pod sandboxes: %v", err)
139139
}
140+
podSandboxes = removeTerminatedPods(podSandboxes)
140141
for _, s := range podSandboxes {
141142
podSandboxMap[s.Id] = s
142143
}
@@ -153,7 +154,7 @@ func (p *criStatsProvider) listPodStats(updateCPUNanoCoreUsage bool) ([]statsapi
153154
return nil, fmt.Errorf("failed to list all container stats: %v", err)
154155
}
155156

156-
containers = removeTerminatedContainer(containers)
157+
containers = removeTerminatedContainers(containers)
157158
// Creates container map.
158159
containerMap := make(map[string]*runtimeapi.Container)
159160
for _, c := range containers {
@@ -233,6 +234,7 @@ func (p *criStatsProvider) ListPodCPUAndMemoryStats() ([]statsapi.PodStats, erro
233234
if err != nil {
234235
return nil, fmt.Errorf("failed to list all pod sandboxes: %v", err)
235236
}
237+
podSandboxes = removeTerminatedPods(podSandboxes)
236238
for _, s := range podSandboxes {
237239
podSandboxMap[s.Id] = s
238240
}
@@ -245,7 +247,7 @@ func (p *criStatsProvider) ListPodCPUAndMemoryStats() ([]statsapi.PodStats, erro
245247
return nil, fmt.Errorf("failed to list all container stats: %v", err)
246248
}
247249

248-
containers = removeTerminatedContainer(containers)
250+
containers = removeTerminatedContainers(containers)
249251
// Creates container map.
250252
containerMap := make(map[string]*runtimeapi.Container)
251253
for _, c := range containers {
@@ -690,9 +692,51 @@ func (p *criStatsProvider) cleanupOutdatedCaches() {
690692
}
691693
}
692694

693-
// removeTerminatedContainer returns the specified container but with
694-
// the stats of the terminated containers removed.
695-
func removeTerminatedContainer(containers []*runtimeapi.Container) []*runtimeapi.Container {
695+
// removeTerminatedPods returns pods with terminated ones removed.
696+
// It only removes a terminated pod when there is a running instance
697+
// of the pod with the same name and namespace.
698+
// This is needed because:
699+
// 1) PodSandbox may be recreated;
700+
// 2) Pod may be recreated with the same name and namespace.
701+
func removeTerminatedPods(pods []*runtimeapi.PodSandbox) []*runtimeapi.PodSandbox {
702+
podMap := make(map[statsapi.PodReference][]*runtimeapi.PodSandbox)
703+
// Sort order by create time
704+
sort.Slice(pods, func(i, j int) bool {
705+
return pods[i].CreatedAt < pods[j].CreatedAt
706+
})
707+
for _, pod := range pods {
708+
refID := statsapi.PodReference{
709+
Name: pod.GetMetadata().GetName(),
710+
Namespace: pod.GetMetadata().GetNamespace(),
711+
// UID is intentionally left empty.
712+
}
713+
podMap[refID] = append(podMap[refID], pod)
714+
}
715+
716+
result := make([]*runtimeapi.PodSandbox, 0)
717+
for _, refs := range podMap {
718+
if len(refs) == 1 {
719+
result = append(result, refs[0])
720+
continue
721+
}
722+
found := false
723+
for i := 0; i < len(refs); i++ {
724+
if refs[i].State == runtimeapi.PodSandboxState_SANDBOX_READY {
725+
found = true
726+
result = append(result, refs[i])
727+
}
728+
}
729+
if !found {
730+
result = append(result, refs[len(refs)-1])
731+
}
732+
}
733+
return result
734+
}
735+
736+
// removeTerminatedContainers returns containers with terminated ones.
737+
// It only removes a terminated container when there is a running instance
738+
// of the container.
739+
func removeTerminatedContainers(containers []*runtimeapi.Container) []*runtimeapi.Container {
696740
containerMap := make(map[containerID][]*runtimeapi.Container)
697741
// Sort order by create time
698742
sort.Slice(containers, func(i, j int) bool {

pkg/kubelet/stats/cri_stats_provider_test.go

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"k8s.io/apimachinery/pkg/api/resource"
3232
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3333
"k8s.io/apimachinery/pkg/types"
34+
"k8s.io/apimachinery/pkg/util/uuid"
3435
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
3536
critest "k8s.io/cri-api/pkg/apis/testing"
3637
statsapi "k8s.io/kubernetes/pkg/kubelet/apis/stats/v1alpha1"
@@ -77,6 +78,8 @@ const (
7778
cName2 = "container2-name"
7879
cName3 = "container3-name"
7980
cName5 = "container5-name"
81+
cName6 = "container6-name"
82+
cName7 = "container7-name"
8083
)
8184

8285
func TestCRIListPodStats(t *testing.T) {
@@ -86,7 +89,7 @@ func TestCRIListPodStats(t *testing.T) {
8689
imageFsInfo = getTestFsInfo(2000)
8790
rootFsInfo = getTestFsInfo(1000)
8891

89-
sandbox0 = makeFakePodSandbox("sandbox0-name", "sandbox0-uid", "sandbox0-ns")
92+
sandbox0 = makeFakePodSandbox("sandbox0-name", "sandbox0-uid", "sandbox0-ns", false)
9093
sandbox0Cgroup = "/" + cm.GetPodCgroupNameSuffix(types.UID(sandbox0.PodSandboxStatus.Metadata.Uid))
9194
container0 = makeFakeContainer(sandbox0, cName0, 0, false)
9295
containerStats0 = makeFakeContainerStats(container0, imageFsMountpoint)
@@ -95,25 +98,35 @@ func TestCRIListPodStats(t *testing.T) {
9598
containerStats1 = makeFakeContainerStats(container1, unknownMountpoint)
9699
containerLogStats1 = makeFakeLogStats(2000)
97100

98-
sandbox1 = makeFakePodSandbox("sandbox1-name", "sandbox1-uid", "sandbox1-ns")
101+
sandbox1 = makeFakePodSandbox("sandbox1-name", "sandbox1-uid", "sandbox1-ns", false)
99102
sandbox1Cgroup = "/" + cm.GetPodCgroupNameSuffix(types.UID(sandbox1.PodSandboxStatus.Metadata.Uid))
100103
container2 = makeFakeContainer(sandbox1, cName2, 0, false)
101104
containerStats2 = makeFakeContainerStats(container2, imageFsMountpoint)
102105
containerLogStats2 = makeFakeLogStats(3000)
103106

104-
sandbox2 = makeFakePodSandbox("sandbox2-name", "sandbox2-uid", "sandbox2-ns")
107+
sandbox2 = makeFakePodSandbox("sandbox2-name", "sandbox2-uid", "sandbox2-ns", false)
105108
sandbox2Cgroup = "/" + cm.GetPodCgroupNameSuffix(types.UID(sandbox2.PodSandboxStatus.Metadata.Uid))
106109
container3 = makeFakeContainer(sandbox2, cName3, 0, true)
107110
containerStats3 = makeFakeContainerStats(container3, imageFsMountpoint)
108111
container4 = makeFakeContainer(sandbox2, cName3, 1, false)
109112
containerStats4 = makeFakeContainerStats(container4, imageFsMountpoint)
110113
containerLogStats4 = makeFakeLogStats(4000)
111114

112-
sandbox3 = makeFakePodSandbox("sandbox3-name", "sandbox3-uid", "sandbox3-ns")
115+
sandbox3 = makeFakePodSandbox("sandbox3-name", "sandbox3-uid", "sandbox3-ns", false)
113116
container5 = makeFakeContainer(sandbox3, cName5, 0, true)
114117
containerStats5 = makeFakeContainerStats(container5, imageFsMountpoint)
115118
containerLogStats5 = makeFakeLogStats(5000)
116119

120+
// Terminated pod sandbox
121+
sandbox4 = makeFakePodSandbox("sandbox1-name", "sandbox1-uid", "sandbox1-ns", true)
122+
container6 = makeFakeContainer(sandbox4, cName6, 0, true)
123+
containerStats6 = makeFakeContainerStats(container6, imageFsMountpoint)
124+
125+
// Terminated pod
126+
sandbox5 = makeFakePodSandbox("sandbox1-name", "sandbox5-uid", "sandbox1-ns", true)
127+
container7 = makeFakeContainer(sandbox5, cName7, 0, true)
128+
containerStats7 = makeFakeContainerStats(container7, imageFsMountpoint)
129+
117130
podLogName0 = "pod-log-0"
118131
podLogName1 = "pod-log-1"
119132
podLogStats0 = makeFakeLogStats(5000)
@@ -157,13 +170,13 @@ func TestCRIListPodStats(t *testing.T) {
157170
On("GetDirFsInfo", imageFsMountpoint).Return(imageFsInfo, nil).
158171
On("GetDirFsInfo", unknownMountpoint).Return(cadvisorapiv2.FsInfo{}, cadvisorfs.ErrNoSuchDevice)
159172
fakeRuntimeService.SetFakeSandboxes([]*critest.FakePodSandbox{
160-
sandbox0, sandbox1, sandbox2, sandbox3,
173+
sandbox0, sandbox1, sandbox2, sandbox3, sandbox4, sandbox5,
161174
})
162175
fakeRuntimeService.SetFakeContainers([]*critest.FakeContainer{
163-
container0, container1, container2, container3, container4, container5,
176+
container0, container1, container2, container3, container4, container5, container6, container7,
164177
})
165178
fakeRuntimeService.SetFakeContainerStats([]*runtimeapi.ContainerStats{
166-
containerStats0, containerStats1, containerStats2, containerStats3, containerStats4, containerStats5,
179+
containerStats0, containerStats1, containerStats2, containerStats3, containerStats4, containerStats5, containerStats6, containerStats7,
167180
})
168181

169182
ephemeralVolumes := makeFakeVolumeStats([]string{"ephVolume1, ephVolumes2"})
@@ -304,28 +317,38 @@ func TestCRIListPodCPUAndMemoryStats(t *testing.T) {
304317
imageFsMountpoint = "/test/mount/point"
305318
unknownMountpoint = "/unknown/mount/point"
306319

307-
sandbox0 = makeFakePodSandbox("sandbox0-name", "sandbox0-uid", "sandbox0-ns")
320+
sandbox0 = makeFakePodSandbox("sandbox0-name", "sandbox0-uid", "sandbox0-ns", false)
308321
sandbox0Cgroup = "/" + cm.GetPodCgroupNameSuffix(types.UID(sandbox0.PodSandboxStatus.Metadata.Uid))
309322
container0 = makeFakeContainer(sandbox0, cName0, 0, false)
310323
containerStats0 = makeFakeContainerStats(container0, imageFsMountpoint)
311324
container1 = makeFakeContainer(sandbox0, cName1, 0, false)
312325
containerStats1 = makeFakeContainerStats(container1, unknownMountpoint)
313326

314-
sandbox1 = makeFakePodSandbox("sandbox1-name", "sandbox1-uid", "sandbox1-ns")
327+
sandbox1 = makeFakePodSandbox("sandbox1-name", "sandbox1-uid", "sandbox1-ns", false)
315328
sandbox1Cgroup = "/" + cm.GetPodCgroupNameSuffix(types.UID(sandbox1.PodSandboxStatus.Metadata.Uid))
316329
container2 = makeFakeContainer(sandbox1, cName2, 0, false)
317330
containerStats2 = makeFakeContainerStats(container2, imageFsMountpoint)
318331

319-
sandbox2 = makeFakePodSandbox("sandbox2-name", "sandbox2-uid", "sandbox2-ns")
332+
sandbox2 = makeFakePodSandbox("sandbox2-name", "sandbox2-uid", "sandbox2-ns", false)
320333
sandbox2Cgroup = "/" + cm.GetPodCgroupNameSuffix(types.UID(sandbox2.PodSandboxStatus.Metadata.Uid))
321334
container3 = makeFakeContainer(sandbox2, cName3, 0, true)
322335
containerStats3 = makeFakeContainerStats(container3, imageFsMountpoint)
323336
container4 = makeFakeContainer(sandbox2, cName3, 1, false)
324337
containerStats4 = makeFakeContainerStats(container4, imageFsMountpoint)
325338

326-
sandbox3 = makeFakePodSandbox("sandbox3-name", "sandbox3-uid", "sandbox3-ns")
339+
sandbox3 = makeFakePodSandbox("sandbox3-name", "sandbox3-uid", "sandbox3-ns", false)
327340
container5 = makeFakeContainer(sandbox3, cName5, 0, true)
328341
containerStats5 = makeFakeContainerStats(container5, imageFsMountpoint)
342+
343+
// Terminated pod sandbox
344+
sandbox4 = makeFakePodSandbox("sandbox1-name", "sandbox1-uid", "sandbox1-ns", true)
345+
container6 = makeFakeContainer(sandbox4, cName6, 0, true)
346+
containerStats6 = makeFakeContainerStats(container6, imageFsMountpoint)
347+
348+
// Terminated pod
349+
sandbox5 = makeFakePodSandbox("sandbox1-name", "sandbox5-uid", "sandbox1-ns", true)
350+
container7 = makeFakeContainer(sandbox5, cName7, 0, true)
351+
containerStats7 = makeFakeContainerStats(container7, imageFsMountpoint)
329352
)
330353

331354
var (
@@ -361,13 +384,13 @@ func TestCRIListPodCPUAndMemoryStats(t *testing.T) {
361384
mockCadvisor.
362385
On("ContainerInfoV2", "/", options).Return(infos, nil)
363386
fakeRuntimeService.SetFakeSandboxes([]*critest.FakePodSandbox{
364-
sandbox0, sandbox1, sandbox2, sandbox3,
387+
sandbox0, sandbox1, sandbox2, sandbox3, sandbox4, sandbox5,
365388
})
366389
fakeRuntimeService.SetFakeContainers([]*critest.FakeContainer{
367-
container0, container1, container2, container3, container4, container5,
390+
container0, container1, container2, container3, container4, container5, container6, container7,
368391
})
369392
fakeRuntimeService.SetFakeContainerStats([]*runtimeapi.ContainerStats{
370-
containerStats0, containerStats1, containerStats2, containerStats3, containerStats4, containerStats5,
393+
containerStats0, containerStats1, containerStats2, containerStats3, containerStats4, containerStats5, containerStats6, containerStats7,
371394
})
372395

373396
ephemeralVolumes := makeFakeVolumeStats([]string{"ephVolume1, ephVolumes2"})
@@ -523,7 +546,7 @@ func TestCRIImagesFsStats(t *testing.T) {
523546
mockCadvisor.AssertExpectations(t)
524547
}
525548

526-
func makeFakePodSandbox(name, uid, namespace string) *critest.FakePodSandbox {
549+
func makeFakePodSandbox(name, uid, namespace string, terminated bool) *critest.FakePodSandbox {
527550
p := &critest.FakePodSandbox{
528551
PodSandboxStatus: runtimeapi.PodSandboxStatus{
529552
Metadata: &runtimeapi.PodSandboxMetadata{
@@ -535,7 +558,10 @@ func makeFakePodSandbox(name, uid, namespace string) *critest.FakePodSandbox {
535558
CreatedAt: time.Now().UnixNano(),
536559
},
537560
}
538-
p.PodSandboxStatus.Id = critest.BuildSandboxName(p.PodSandboxStatus.Metadata)
561+
if terminated {
562+
p.PodSandboxStatus.State = runtimeapi.PodSandboxState_SANDBOX_NOTREADY
563+
}
564+
p.PodSandboxStatus.Id = string(uuid.NewUUID())
539565
return p
540566
}
541567

@@ -561,7 +587,7 @@ func makeFakeContainer(sandbox *critest.FakePodSandbox, name string, attempt uin
561587
} else {
562588
c.ContainerStatus.State = runtimeapi.ContainerState_CONTAINER_RUNNING
563589
}
564-
c.ContainerStatus.Id = critest.BuildContainerName(c.ContainerStatus.Metadata, sandboxID)
590+
c.ContainerStatus.Id = string(uuid.NewUUID())
565591
return c
566592
}
567593

pkg/kubelet/stats/log_metrics_provider_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package stats
1818

1919
import (
20+
"fmt"
21+
2022
"k8s.io/kubernetes/pkg/volume"
2123
)
2224

@@ -41,5 +43,8 @@ func NewFakeMetricsDu(path string, stats *volume.Metrics) volume.MetricsProvider
4143
}
4244

4345
func (f *fakeMetricsDu) GetMetrics() (*volume.Metrics, error) {
46+
if f.fakeStats == nil {
47+
return nil, fmt.Errorf("no stats provided")
48+
}
4449
return f.fakeStats, nil
4550
}

0 commit comments

Comments
 (0)