From f798cee51e9b194a416945f28e97b98ceb6ff7c3 Mon Sep 17 00:00:00 2001 From: Paul Fisher Date: Fri, 30 Aug 2019 09:58:59 -0700 Subject: [PATCH 1/2] pkg/kubelet: fix uint64 overflow when elapsed UsageCoreNanoSeconds exceeds 18446744073 --- pkg/kubelet/stats/cri_stats_provider.go | 3 ++- pkg/kubelet/stats/cri_stats_provider_test.go | 26 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/pkg/kubelet/stats/cri_stats_provider.go b/pkg/kubelet/stats/cri_stats_provider.go index 492c16bbd77..7c23166be36 100644 --- a/pkg/kubelet/stats/cri_stats_provider.go +++ b/pkg/kubelet/stats/cri_stats_provider.go @@ -661,7 +661,8 @@ func (p *criStatsProvider) getAndUpdateContainerUsageNanoCores(stats *runtimeapi if nanoSeconds <= 0 { return nil, fmt.Errorf("zero or negative interval (%v - %v)", newStats.Timestamp, cachedStats.Timestamp) } - usageNanoCores := (newStats.UsageCoreNanoSeconds.Value - cachedStats.UsageCoreNanoSeconds.Value) * uint64(time.Second/time.Nanosecond) / uint64(nanoSeconds) + usageNanoCores := uint64(float64(newStats.UsageCoreNanoSeconds.Value-cachedStats.UsageCoreNanoSeconds.Value) / + float64(nanoSeconds) * float64(time.Second/time.Nanosecond)) // Update cache with new value. usageToUpdate := usageNanoCores diff --git a/pkg/kubelet/stats/cri_stats_provider_test.go b/pkg/kubelet/stats/cri_stats_provider_test.go index 8d65e71ea4c..cf7852705a5 100644 --- a/pkg/kubelet/stats/cri_stats_provider_test.go +++ b/pkg/kubelet/stats/cri_stats_provider_test.go @@ -757,6 +757,7 @@ func makeFakeLogStats(seed int) *volume.Metrics { func TestGetContainerUsageNanoCores(t *testing.T) { var value0 uint64 var value1 uint64 = 10000000000 + var value2 uint64 = 188427786383 tests := []struct { desc string @@ -856,6 +857,31 @@ func TestGetContainerUsageNanoCores(t *testing.T) { }, expected: &value1, }, + { + desc: "should return correct value if elapsed UsageCoreNanoSeconds exceeds 18446744073", + stats: &runtimeapi.ContainerStats{ + Attributes: &runtimeapi.ContainerAttributes{ + Id: "1", + }, + Cpu: &runtimeapi.CpuUsage{ + Timestamp: int64(time.Second / time.Nanosecond), + UsageCoreNanoSeconds: &runtimeapi.UInt64Value{ + Value: 68172016162105, + }, + }, + }, + cpuUsageCache: map[string]*cpuUsageRecord{ + "1": { + stats: &runtimeapi.CpuUsage{ + Timestamp: 0, + UsageCoreNanoSeconds: &runtimeapi.UInt64Value{ + Value: 67983588375722, + }, + }, + }, + }, + expected: &value2, + }, } for _, test := range tests { From d32aa6af1d7efae531f0b4d671a827155ad0f436 Mon Sep 17 00:00:00 2001 From: Paul Fisher Date: Wed, 4 Sep 2019 11:49:15 -0700 Subject: [PATCH 2/2] Add comment for testing 100+ CPU usage --- pkg/kubelet/stats/cri_stats_provider_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/kubelet/stats/cri_stats_provider_test.go b/pkg/kubelet/stats/cri_stats_provider_test.go index cf7852705a5..18f70ba65bd 100644 --- a/pkg/kubelet/stats/cri_stats_provider_test.go +++ b/pkg/kubelet/stats/cri_stats_provider_test.go @@ -757,6 +757,8 @@ func makeFakeLogStats(seed int) *volume.Metrics { func TestGetContainerUsageNanoCores(t *testing.T) { var value0 uint64 var value1 uint64 = 10000000000 + + // Test with a large container of 100+ CPUs var value2 uint64 = 188427786383 tests := []struct {