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
c2be2fc9
Unverified
Commit
c2be2fc9
authored
Aug 16, 2019
by
Kubernetes Prow Robot
Committed by
GitHub
Aug 16, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #81248 from liyanhui1228/automated-cherry-pick-of-#80176-upstream-release-1.15
Automated cherry pick of #80176: Make kubelet report usageNanoCores for node on Windows
parents
32884077
e2e76678
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
90 additions
and
4 deletions
+90
-4
perfcounter_nodestats.go
pkg/kubelet/winstats/perfcounter_nodestats.go
+28
-4
perfcounters.go
pkg/kubelet/winstats/perfcounters.go
+4
-0
winstats.go
pkg/kubelet/winstats/winstats.go
+11
-0
winstats_test.go
pkg/kubelet/winstats/winstats_test.go
+47
-0
No files found.
pkg/kubelet/winstats/perfcounter_nodestats.go
View file @
c2be2fc9
...
@@ -53,7 +53,11 @@ var (
...
@@ -53,7 +53,11 @@ var (
// NewPerfCounterClient creates a client using perf counters
// NewPerfCounterClient creates a client using perf counters
func
NewPerfCounterClient
()
(
Client
,
error
)
{
func
NewPerfCounterClient
()
(
Client
,
error
)
{
return
newClient
(
&
perfCounterNodeStatsClient
{})
// Initialize the cache
initCache
:=
cpuUsageCoreNanoSecondsCache
{
0
,
0
}
return
newClient
(
&
perfCounterNodeStatsClient
{
cpuUsageCoreNanoSecondsCache
:
initCache
,
})
}
}
// perfCounterNodeStatsClient is a client that provides Windows Stats via PerfCounters
// perfCounterNodeStatsClient is a client that provides Windows Stats via PerfCounters
...
@@ -61,6 +65,8 @@ type perfCounterNodeStatsClient struct {
...
@@ -61,6 +65,8 @@ type perfCounterNodeStatsClient struct {
nodeMetrics
nodeMetrics
mu
sync
.
RWMutex
// mu protects nodeMetrics
mu
sync
.
RWMutex
// mu protects nodeMetrics
nodeInfo
nodeInfo
// cpuUsageCoreNanoSecondsCache caches the cpu usage for nodes.
cpuUsageCoreNanoSecondsCache
}
}
func
(
p
*
perfCounterNodeStatsClient
)
startMonitoring
()
error
{
func
(
p
*
perfCounterNodeStatsClient
)
startMonitoring
()
error
{
...
@@ -110,6 +116,17 @@ func (p *perfCounterNodeStatsClient) startMonitoring() error {
...
@@ -110,6 +116,17 @@ func (p *perfCounterNodeStatsClient) startMonitoring() error {
p
.
collectMetricsData
(
cpuCounter
,
memWorkingSetCounter
,
memCommittedBytesCounter
,
networkAdapterCounter
)
p
.
collectMetricsData
(
cpuCounter
,
memWorkingSetCounter
,
memCommittedBytesCounter
,
networkAdapterCounter
)
},
perfCounterUpdatePeriod
)
},
perfCounterUpdatePeriod
)
// Cache the CPU usage every defaultCachePeriod
go
wait
.
Forever
(
func
()
{
newValue
:=
p
.
nodeMetrics
.
cpuUsageCoreNanoSeconds
p
.
mu
.
Lock
()
defer
p
.
mu
.
Unlock
()
p
.
cpuUsageCoreNanoSecondsCache
=
cpuUsageCoreNanoSecondsCache
{
previousValue
:
p
.
cpuUsageCoreNanoSecondsCache
.
latestValue
,
latestValue
:
newValue
,
}
},
defaultCachePeriod
)
return
nil
return
nil
}
}
...
@@ -145,6 +162,7 @@ func (p *perfCounterNodeStatsClient) getNodeInfo() nodeInfo {
...
@@ -145,6 +162,7 @@ func (p *perfCounterNodeStatsClient) getNodeInfo() nodeInfo {
func
(
p
*
perfCounterNodeStatsClient
)
collectMetricsData
(
cpuCounter
,
memWorkingSetCounter
,
memCommittedBytesCounter
*
perfCounter
,
networkAdapterCounter
*
networkCounter
)
{
func
(
p
*
perfCounterNodeStatsClient
)
collectMetricsData
(
cpuCounter
,
memWorkingSetCounter
,
memCommittedBytesCounter
*
perfCounter
,
networkAdapterCounter
*
networkCounter
)
{
cpuValue
,
err
:=
cpuCounter
.
getData
()
cpuValue
,
err
:=
cpuCounter
.
getData
()
cpuCores
:=
runtime
.
NumCPU
()
if
err
!=
nil
{
if
err
!=
nil
{
klog
.
Errorf
(
"Unable to get cpu perf counter data; err: %v"
,
err
)
klog
.
Errorf
(
"Unable to get cpu perf counter data; err: %v"
,
err
)
return
return
...
@@ -171,7 +189,8 @@ func (p *perfCounterNodeStatsClient) collectMetricsData(cpuCounter, memWorkingSe
...
@@ -171,7 +189,8 @@ func (p *perfCounterNodeStatsClient) collectMetricsData(cpuCounter, memWorkingSe
p
.
mu
.
Lock
()
p
.
mu
.
Lock
()
defer
p
.
mu
.
Unlock
()
defer
p
.
mu
.
Unlock
()
p
.
nodeMetrics
=
nodeMetrics
{
p
.
nodeMetrics
=
nodeMetrics
{
cpuUsageCoreNanoSeconds
:
p
.
convertCPUValue
(
cpuValue
),
cpuUsageCoreNanoSeconds
:
p
.
convertCPUValue
(
cpuCores
,
cpuValue
),
cpuUsageNanoCores
:
p
.
getCPUUsageNanoCores
(),
memoryPrivWorkingSetBytes
:
memWorkingSetValue
,
memoryPrivWorkingSetBytes
:
memWorkingSetValue
,
memoryCommittedBytes
:
memCommittedBytesValue
,
memoryCommittedBytes
:
memCommittedBytesValue
,
interfaceStats
:
networkAdapterStats
,
interfaceStats
:
networkAdapterStats
,
...
@@ -179,8 +198,7 @@ func (p *perfCounterNodeStatsClient) collectMetricsData(cpuCounter, memWorkingSe
...
@@ -179,8 +198,7 @@ func (p *perfCounterNodeStatsClient) collectMetricsData(cpuCounter, memWorkingSe
}
}
}
}
func
(
p
*
perfCounterNodeStatsClient
)
convertCPUValue
(
cpuValue
uint64
)
uint64
{
func
(
p
*
perfCounterNodeStatsClient
)
convertCPUValue
(
cpuCores
int
,
cpuValue
uint64
)
uint64
{
cpuCores
:=
runtime
.
NumCPU
()
// This converts perf counter data which is cpu percentage for all cores into nanoseconds.
// This converts perf counter data which is cpu percentage for all cores into nanoseconds.
// The formula is (cpuPercentage / 100.0) * #cores * 1e+9 (nano seconds). More info here:
// The formula is (cpuPercentage / 100.0) * #cores * 1e+9 (nano seconds). More info here:
// https://github.com/kubernetes/heapster/issues/650
// https://github.com/kubernetes/heapster/issues/650
...
@@ -188,6 +206,12 @@ func (p *perfCounterNodeStatsClient) convertCPUValue(cpuValue uint64) uint64 {
...
@@ -188,6 +206,12 @@ func (p *perfCounterNodeStatsClient) convertCPUValue(cpuValue uint64) uint64 {
return
newValue
return
newValue
}
}
func
(
p
*
perfCounterNodeStatsClient
)
getCPUUsageNanoCores
()
uint64
{
cachePeriodSeconds
:=
uint64
(
defaultCachePeriod
/
time
.
Second
)
cpuUsageNanoCores
:=
(
p
.
cpuUsageCoreNanoSecondsCache
.
latestValue
-
p
.
cpuUsageCoreNanoSecondsCache
.
previousValue
)
/
cachePeriodSeconds
return
cpuUsageNanoCores
}
func
getPhysicallyInstalledSystemMemoryBytes
()
(
uint64
,
error
)
{
func
getPhysicallyInstalledSystemMemoryBytes
()
(
uint64
,
error
)
{
// We use GlobalMemoryStatusEx instead of GetPhysicallyInstalledSystemMemory
// We use GlobalMemoryStatusEx instead of GetPhysicallyInstalledSystemMemory
// on Windows node for the following reasons:
// on Windows node for the following reasons:
...
...
pkg/kubelet/winstats/perfcounters.go
View file @
c2be2fc9
...
@@ -34,6 +34,10 @@ const (
...
@@ -34,6 +34,10 @@ const (
// Perf counters are updated every second. This is the same as the default cadvisor collection period
// Perf counters are updated every second. This is the same as the default cadvisor collection period
// see https://github.com/google/cadvisor/blob/master/docs/runtime_options.md#housekeeping
// see https://github.com/google/cadvisor/blob/master/docs/runtime_options.md#housekeeping
perfCounterUpdatePeriod
=
1
*
time
.
Second
perfCounterUpdatePeriod
=
1
*
time
.
Second
// defaultCachePeriod is the default cache period for each cpuUsage.
// This matches with the cadvisor setting and the time interval we use for containers.
// see https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/cadvisor/cadvisor_linux.go#L63
defaultCachePeriod
=
10
*
time
.
Second
)
)
type
perfCounter
struct
{
type
perfCounter
struct
{
...
...
pkg/kubelet/winstats/winstats.go
View file @
c2be2fc9
...
@@ -55,6 +55,7 @@ type winNodeStatsClient interface {
...
@@ -55,6 +55,7 @@ type winNodeStatsClient interface {
type
nodeMetrics
struct
{
type
nodeMetrics
struct
{
cpuUsageCoreNanoSeconds
uint64
cpuUsageCoreNanoSeconds
uint64
cpuUsageNanoCores
uint64
memoryPrivWorkingSetBytes
uint64
memoryPrivWorkingSetBytes
uint64
memoryCommittedBytes
uint64
memoryCommittedBytes
uint64
timeStamp
time
.
Time
timeStamp
time
.
Time
...
@@ -69,6 +70,11 @@ type nodeInfo struct {
...
@@ -69,6 +70,11 @@ type nodeInfo struct {
startTime
time
.
Time
startTime
time
.
Time
}
}
type
cpuUsageCoreNanoSecondsCache
struct
{
latestValue
uint64
previousValue
uint64
}
// newClient constructs a Client.
// newClient constructs a Client.
func
newClient
(
statsNodeClient
winNodeStatsClient
)
(
Client
,
error
)
{
func
newClient
(
statsNodeClient
winNodeStatsClient
)
(
Client
,
error
)
{
statsClient
:=
new
(
StatsClient
)
statsClient
:=
new
(
StatsClient
)
...
@@ -122,6 +128,11 @@ func (c *StatsClient) createRootContainerInfo() (*cadvisorapiv2.ContainerInfo, e
...
@@ -122,6 +128,11 @@ func (c *StatsClient) createRootContainerInfo() (*cadvisorapiv2.ContainerInfo, e
Total
:
nodeMetrics
.
cpuUsageCoreNanoSeconds
,
Total
:
nodeMetrics
.
cpuUsageCoreNanoSeconds
,
},
},
},
},
CpuInst
:
&
cadvisorapiv2
.
CpuInstStats
{
Usage
:
cadvisorapiv2
.
CpuInstUsage
{
Total
:
nodeMetrics
.
cpuUsageNanoCores
,
},
},
Memory
:
&
cadvisorapi
.
MemoryStats
{
Memory
:
&
cadvisorapi
.
MemoryStats
{
WorkingSet
:
nodeMetrics
.
memoryPrivWorkingSetBytes
,
WorkingSet
:
nodeMetrics
.
memoryPrivWorkingSetBytes
,
Usage
:
nodeMetrics
.
memoryCommittedBytes
,
Usage
:
nodeMetrics
.
memoryCommittedBytes
,
...
...
pkg/kubelet/winstats/winstats_test.go
View file @
c2be2fc9
...
@@ -38,6 +38,7 @@ func (f fakeWinNodeStatsClient) startMonitoring() error {
...
@@ -38,6 +38,7 @@ func (f fakeWinNodeStatsClient) startMonitoring() error {
func
(
f
fakeWinNodeStatsClient
)
getNodeMetrics
()
(
nodeMetrics
,
error
)
{
func
(
f
fakeWinNodeStatsClient
)
getNodeMetrics
()
(
nodeMetrics
,
error
)
{
return
nodeMetrics
{
return
nodeMetrics
{
cpuUsageCoreNanoSeconds
:
123
,
cpuUsageCoreNanoSeconds
:
123
,
cpuUsageNanoCores
:
23
,
memoryPrivWorkingSetBytes
:
1234
,
memoryPrivWorkingSetBytes
:
1234
,
memoryCommittedBytes
:
12345
,
memoryCommittedBytes
:
12345
,
timeStamp
:
timeStamp
,
timeStamp
:
timeStamp
,
...
@@ -78,6 +79,11 @@ func TestWinContainerInfos(t *testing.T) {
...
@@ -78,6 +79,11 @@ func TestWinContainerInfos(t *testing.T) {
Total
:
123
,
Total
:
123
,
},
},
},
},
CpuInst
:
&
cadvisorapiv2
.
CpuInstStats
{
Usage
:
cadvisorapiv2
.
CpuInstUsage
{
Total
:
23
,
},
},
Memory
:
&
cadvisorapi
.
MemoryStats
{
Memory
:
&
cadvisorapi
.
MemoryStats
{
WorkingSet
:
1234
,
WorkingSet
:
1234
,
Usage
:
12345
,
Usage
:
12345
,
...
@@ -100,6 +106,7 @@ func TestWinContainerInfos(t *testing.T) {
...
@@ -100,6 +106,7 @@ func TestWinContainerInfos(t *testing.T) {
assert
.
Equal
(
t
,
actualRootInfos
[
"/"
]
.
Spec
,
infos
[
"/"
]
.
Spec
)
assert
.
Equal
(
t
,
actualRootInfos
[
"/"
]
.
Spec
,
infos
[
"/"
]
.
Spec
)
assert
.
Equal
(
t
,
len
(
actualRootInfos
[
"/"
]
.
Stats
),
len
(
infos
[
"/"
]
.
Stats
))
assert
.
Equal
(
t
,
len
(
actualRootInfos
[
"/"
]
.
Stats
),
len
(
infos
[
"/"
]
.
Stats
))
assert
.
Equal
(
t
,
actualRootInfos
[
"/"
]
.
Stats
[
0
]
.
Cpu
,
infos
[
"/"
]
.
Stats
[
0
]
.
Cpu
)
assert
.
Equal
(
t
,
actualRootInfos
[
"/"
]
.
Stats
[
0
]
.
Cpu
,
infos
[
"/"
]
.
Stats
[
0
]
.
Cpu
)
assert
.
Equal
(
t
,
actualRootInfos
[
"/"
]
.
Stats
[
0
]
.
CpuInst
,
infos
[
"/"
]
.
Stats
[
0
]
.
CpuInst
)
assert
.
Equal
(
t
,
actualRootInfos
[
"/"
]
.
Stats
[
0
]
.
Memory
,
infos
[
"/"
]
.
Stats
[
0
]
.
Memory
)
assert
.
Equal
(
t
,
actualRootInfos
[
"/"
]
.
Stats
[
0
]
.
Memory
,
infos
[
"/"
]
.
Stats
[
0
]
.
Memory
)
}
}
...
@@ -123,6 +130,46 @@ func TestWinVersionInfo(t *testing.T) {
...
@@ -123,6 +130,46 @@ func TestWinVersionInfo(t *testing.T) {
KernelVersion
:
"v42"
})
KernelVersion
:
"v42"
})
}
}
func
TestConvertCPUValue
(
t
*
testing
.
T
)
{
testCases
:=
[]
struct
{
cpuValue
uint64
expected
uint64
}{
{
cpuValue
:
uint64
(
50
),
expected
:
uint64
(
2000000000
)},
{
cpuValue
:
uint64
(
0
),
expected
:
uint64
(
0
)},
{
cpuValue
:
uint64
(
100
),
expected
:
uint64
(
4000000000
)},
}
var
cpuCores
=
4
for
_
,
tc
:=
range
testCases
{
p
:=
perfCounterNodeStatsClient
{}
newValue
:=
p
.
convertCPUValue
(
cpuCores
,
tc
.
cpuValue
)
assert
.
Equal
(
t
,
newValue
,
tc
.
expected
)
}
}
func
TestGetCPUUsageNanoCores
(
t
*
testing
.
T
)
{
testCases
:=
[]
struct
{
latestValue
uint64
previousValue
uint64
expected
uint64
}{
{
latestValue
:
uint64
(
0
),
previousValue
:
uint64
(
0
),
expected
:
uint64
(
0
)},
{
latestValue
:
uint64
(
2000000000
),
previousValue
:
uint64
(
0
),
expected
:
uint64
(
200000000
)},
{
latestValue
:
uint64
(
5000000000
),
previousValue
:
uint64
(
2000000000
),
expected
:
uint64
(
300000000
)},
}
for
_
,
tc
:=
range
testCases
{
p
:=
perfCounterNodeStatsClient
{}
p
.
cpuUsageCoreNanoSecondsCache
=
cpuUsageCoreNanoSecondsCache
{
latestValue
:
tc
.
latestValue
,
previousValue
:
tc
.
previousValue
,
}
cpuUsageNanoCores
:=
p
.
getCPUUsageNanoCores
()
assert
.
Equal
(
t
,
cpuUsageNanoCores
,
tc
.
expected
)
}
}
func
getClient
(
t
*
testing
.
T
)
Client
{
func
getClient
(
t
*
testing
.
T
)
Client
{
f
:=
fakeWinNodeStatsClient
{}
f
:=
fakeWinNodeStatsClient
{}
c
,
err
:=
newClient
(
f
)
c
,
err
:=
newClient
(
f
)
...
...
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