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
9067833a
Commit
9067833a
authored
Dec 13, 2015
by
k8s-merge-robot
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #18382 from yujuhong/resource_usage
Auto commit by PR queue bot
parents
725a84ff
7e8f4d83
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
117 additions
and
32 deletions
+117
-32
config-test.sh
cluster/gce/config-test.sh
+1
-1
e2e.sh
hack/jenkins/e2e.sh
+2
-2
kubelet_perf.go
test/e2e/kubelet_perf.go
+76
-22
kubelet_stats.go
test/e2e/kubelet_stats.go
+38
-7
No files found.
cluster/gce/config-test.sh
View file @
9067833a
...
@@ -71,7 +71,7 @@ ENABLE_CLUSTER_MONITORING="${KUBE_ENABLE_CLUSTER_MONITORING:-influxdb}"
...
@@ -71,7 +71,7 @@ ENABLE_CLUSTER_MONITORING="${KUBE_ENABLE_CLUSTER_MONITORING:-influxdb}"
TEST_CLUSTER_LOG_LEVEL
=
"
${
TEST_CLUSTER_LOG_LEVEL
:-
--v=4
}
"
TEST_CLUSTER_LOG_LEVEL
=
"
${
TEST_CLUSTER_LOG_LEVEL
:-
--v=4
}
"
TEST_CLUSTER_RESYNC_PERIOD
=
"
${
TEST_CLUSTER_RESYNC_PERIOD
:-
--min-resync-period=3m
}
"
TEST_CLUSTER_RESYNC_PERIOD
=
"
${
TEST_CLUSTER_RESYNC_PERIOD
:-
--min-resync-period=3m
}
"
KUBELET_TEST_ARGS
=
"--max-pods=1
0
0
$TEST_CLUSTER_LOG_LEVEL
"
KUBELET_TEST_ARGS
=
"--max-pods=1
1
0
$TEST_CLUSTER_LOG_LEVEL
"
APISERVER_TEST_ARGS
=
"--runtime-config=extensions/v1beta1
${
TEST_CLUSTER_LOG_LEVEL
}
"
APISERVER_TEST_ARGS
=
"--runtime-config=extensions/v1beta1
${
TEST_CLUSTER_LOG_LEVEL
}
"
CONTROLLER_MANAGER_TEST_ARGS
=
"
${
TEST_CLUSTER_LOG_LEVEL
}
${
TEST_CLUSTER_RESYNC_PERIOD
}
"
CONTROLLER_MANAGER_TEST_ARGS
=
"
${
TEST_CLUSTER_LOG_LEVEL
}
${
TEST_CLUSTER_RESYNC_PERIOD
}
"
SCHEDULER_TEST_ARGS
=
"
${
TEST_CLUSTER_LOG_LEVEL
}
"
SCHEDULER_TEST_ARGS
=
"
${
TEST_CLUSTER_LOG_LEVEL
}
"
...
...
hack/jenkins/e2e.sh
View file @
9067833a
...
@@ -289,7 +289,7 @@ GKE_REQUIRED_SKIP_TESTS=(
...
@@ -289,7 +289,7 @@ GKE_REQUIRED_SKIP_TESTS=(
"Nodes"
"Nodes"
"Etcd
\s
Failure"
"Etcd
\s
Failure"
"MasterCerts"
"MasterCerts"
"experimental
\s
resource
\s
usage
\s
tracking"
# Expect --max-pods=1
0
0
"experimental
\s
resource
\s
usage
\s
tracking"
# Expect --max-pods=1
1
0
"ServiceLoadBalancer"
# issue: #16602
"ServiceLoadBalancer"
# issue: #16602
"Shell"
"Shell"
# Alpha features, remove from skip when these move to beta
# Alpha features, remove from skip when these move to beta
...
@@ -312,7 +312,7 @@ GKE_DEFAULT_SKIP_TESTS=(
...
@@ -312,7 +312,7 @@ GKE_DEFAULT_SKIP_TESTS=(
# Tests which cannot be run on AWS.
# Tests which cannot be run on AWS.
AWS_REQUIRED_SKIP_TESTS
=(
AWS_REQUIRED_SKIP_TESTS
=(
"experimental
\s
resource
\s
usage
\s
tracking"
# Expect --max-pods=1
0
0
"experimental
\s
resource
\s
usage
\s
tracking"
# Expect --max-pods=1
1
0
"GCE
\s
L7
\s
LoadBalancer
\s
Controller"
# GCE L7 loadbalancing
"GCE
\s
L7
\s
LoadBalancer
\s
Controller"
# GCE L7 loadbalancing
)
)
...
...
test/e2e/kubelet_perf.go
View file @
9067833a
...
@@ -18,6 +18,7 @@ package e2e
...
@@ -18,6 +18,7 @@ package e2e
import
(
import
(
"fmt"
"fmt"
"strings"
"time"
"time"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/unversioned"
...
@@ -31,13 +32,18 @@ import (
...
@@ -31,13 +32,18 @@ import (
const
(
const
(
// Interval to poll /stats/container on a node
// Interval to poll /stats/container on a node
containerStatsPollingPeriod
=
10
*
time
.
Second
containerStatsPollingPeriod
=
3
*
time
.
Second
// The monitoring time for one test.
// The monitoring time for one test.
monitoringTime
=
3
0
*
time
.
Minute
monitoringTime
=
2
0
*
time
.
Minute
// The periodic reporting period.
// The periodic reporting period.
reportingPeriod
=
5
*
time
.
Minute
reportingPeriod
=
5
*
time
.
Minute
)
)
type
resourceTest
struct
{
podsPerNode
int
limits
containersCPUSummary
}
func
logPodsOnNodes
(
c
*
client
.
Client
,
nodeNames
[]
string
)
{
func
logPodsOnNodes
(
c
*
client
.
Client
,
nodeNames
[]
string
)
{
for
_
,
n
:=
range
nodeNames
{
for
_
,
n
:=
range
nodeNames
{
podList
,
err
:=
GetKubeletPods
(
c
,
n
)
podList
,
err
:=
GetKubeletPods
(
c
,
n
)
...
@@ -49,7 +55,7 @@ func logPodsOnNodes(c *client.Client, nodeNames []string) {
...
@@ -49,7 +55,7 @@ func logPodsOnNodes(c *client.Client, nodeNames []string) {
}
}
}
}
func
runResourceTrackingTest
(
framework
*
Framework
,
podsPerNode
int
,
nodeNames
sets
.
String
,
r
esourceMonitor
*
resourceMonitor
)
{
func
runResourceTrackingTest
(
framework
*
Framework
,
podsPerNode
int
,
nodeNames
sets
.
String
,
r
m
*
resourceMonitor
,
expected
map
[
string
]
map
[
float64
]
float64
)
{
numNodes
:=
nodeNames
.
Len
()
numNodes
:=
nodeNames
.
Len
()
totalPods
:=
podsPerNode
*
numNodes
totalPods
:=
podsPerNode
*
numNodes
By
(
fmt
.
Sprintf
(
"Creating a RC of %d pods and wait until all pods of this RC are running"
,
totalPods
))
By
(
fmt
.
Sprintf
(
"Creating a RC of %d pods and wait until all pods of this RC are running"
,
totalPods
))
...
@@ -65,8 +71,8 @@ func runResourceTrackingTest(framework *Framework, podsPerNode int, nodeNames se
...
@@ -65,8 +71,8 @@ func runResourceTrackingTest(framework *Framework, podsPerNode int, nodeNames se
}))
.
NotTo
(
HaveOccurred
())
}))
.
NotTo
(
HaveOccurred
())
// Log once and flush the stats.
// Log once and flush the stats.
r
esourceMonitor
.
LogLatest
()
r
m
.
LogLatest
()
r
esourceMonitor
.
Reset
()
r
m
.
Reset
()
By
(
"Start monitoring resource usage"
)
By
(
"Start monitoring resource usage"
)
// Periodically dump the cpu summary until the deadline is met.
// Periodically dump the cpu summary until the deadline is met.
...
@@ -76,8 +82,6 @@ func runResourceTrackingTest(framework *Framework, podsPerNode int, nodeNames se
...
@@ -76,8 +82,6 @@ func runResourceTrackingTest(framework *Framework, podsPerNode int, nodeNames se
// entries if we plan to monitor longer (e.g., 8 hours).
// entries if we plan to monitor longer (e.g., 8 hours).
deadline
:=
time
.
Now
()
.
Add
(
monitoringTime
)
deadline
:=
time
.
Now
()
.
Add
(
monitoringTime
)
for
time
.
Now
()
.
Before
(
deadline
)
{
for
time
.
Now
()
.
Before
(
deadline
)
{
Logf
(
"Still running...%v left"
,
deadline
.
Sub
(
time
.
Now
()))
time
.
Sleep
(
reportingPeriod
)
timeLeft
:=
deadline
.
Sub
(
time
.
Now
())
timeLeft
:=
deadline
.
Sub
(
time
.
Now
())
Logf
(
"Still running...%v left"
,
timeLeft
)
Logf
(
"Still running...%v left"
,
timeLeft
)
if
timeLeft
<
reportingPeriod
{
if
timeLeft
<
reportingPeriod
{
...
@@ -90,17 +94,54 @@ func runResourceTrackingTest(framework *Framework, podsPerNode int, nodeNames se
...
@@ -90,17 +94,54 @@ func runResourceTrackingTest(framework *Framework, podsPerNode int, nodeNames se
By
(
"Reporting overall resource usage"
)
By
(
"Reporting overall resource usage"
)
logPodsOnNodes
(
framework
.
Client
,
nodeNames
.
List
())
logPodsOnNodes
(
framework
.
Client
,
nodeNames
.
List
())
resourceMonitor
.
LogCPUSummary
()
rm
.
LogLatest
()
resourceMonitor
.
LogLatest
()
summary
:=
rm
.
GetCPUSummary
()
Logf
(
"%s"
,
rm
.
FormatCPUSummary
(
summary
))
verifyCPULimits
(
expected
,
summary
)
By
(
"Deleting the RC"
)
By
(
"Deleting the RC"
)
DeleteRC
(
framework
.
Client
,
framework
.
Namespace
.
Name
,
rcName
)
DeleteRC
(
framework
.
Client
,
framework
.
Namespace
.
Name
,
rcName
)
}
}
func
verifyCPULimits
(
expected
containersCPUSummary
,
actual
nodesCPUSummary
)
{
if
expected
==
nil
{
return
}
var
errList
[]
string
for
nodeName
,
perNodeSummary
:=
range
actual
{
var
nodeErrs
[]
string
for
cName
,
expectedResult
:=
range
expected
{
perContainerSummary
,
ok
:=
perNodeSummary
[
cName
]
if
!
ok
{
nodeErrs
=
append
(
nodeErrs
,
fmt
.
Sprintf
(
"container %q: missing"
,
cName
))
continue
}
for
p
,
expectedValue
:=
range
expectedResult
{
actualValue
,
ok
:=
perContainerSummary
[
p
]
if
!
ok
{
nodeErrs
=
append
(
nodeErrs
,
fmt
.
Sprintf
(
"container %q: missing percentile %v"
,
cName
,
p
))
continue
}
if
actualValue
>
expectedValue
{
nodeErrs
=
append
(
nodeErrs
,
fmt
.
Sprintf
(
"container %q: expected %.0fth%% usage < %.3f; got %.3f"
,
cName
,
p
*
100
,
expectedValue
,
actualValue
))
}
}
}
if
len
(
nodeErrs
)
>
0
{
errList
=
append
(
errList
,
fmt
.
Sprintf
(
"node %v:
\n
%s"
,
nodeName
,
strings
.
Join
(
nodeErrs
,
", "
)))
}
}
if
len
(
errList
)
>
0
{
Failf
(
"CPU usage exceeding limits:
\n
%s"
,
strings
.
Join
(
errList
,
"
\n
"
))
}
}
var
_
=
Describe
(
"Kubelet"
,
func
()
{
var
_
=
Describe
(
"Kubelet"
,
func
()
{
var
nodeNames
sets
.
String
var
nodeNames
sets
.
String
framework
:=
NewFramework
(
"kubelet-perf"
)
framework
:=
NewFramework
(
"kubelet-perf"
)
var
r
esourceMonitor
*
resourceMonitor
var
r
m
*
resourceMonitor
BeforeEach
(
func
()
{
BeforeEach
(
func
()
{
nodes
,
err
:=
framework
.
Client
.
Nodes
()
.
List
(
unversioned
.
ListOptions
{})
nodes
,
err
:=
framework
.
Client
.
Nodes
()
.
List
(
unversioned
.
ListOptions
{})
...
@@ -109,33 +150,46 @@ var _ = Describe("Kubelet", func() {
...
@@ -109,33 +150,46 @@ var _ = Describe("Kubelet", func() {
for
_
,
node
:=
range
nodes
.
Items
{
for
_
,
node
:=
range
nodes
.
Items
{
nodeNames
.
Insert
(
node
.
Name
)
nodeNames
.
Insert
(
node
.
Name
)
}
}
r
esourceMonitor
=
newResourceMonitor
(
framework
.
Client
,
targetContainers
(),
containerStatsPollingPeriod
)
r
m
=
newResourceMonitor
(
framework
.
Client
,
targetContainers
(),
containerStatsPollingPeriod
)
r
esourceMonitor
.
Start
()
r
m
.
Start
()
})
})
AfterEach
(
func
()
{
AfterEach
(
func
()
{
r
esourceMonitor
.
Stop
()
r
m
.
Stop
()
})
})
Describe
(
"regular resource usage tracking"
,
func
()
{
Describe
(
"regular resource usage tracking"
,
func
()
{
density
:=
[]
int
{
0
,
35
}
rTests
:=
[]
resourceTest
{
for
i
:=
range
density
{
{
podsPerNode
:
0
,
podsPerNode
:=
density
[
i
]
limits
:
containersCPUSummary
{
"/kubelet"
:
{
0.50
:
0.05
,
0.95
:
0.15
},
"/docker-daemon"
:
{
0.50
:
0.03
,
0.95
:
0.06
},
},
},
{
podsPerNode
:
40
,
limits
:
containersCPUSummary
{
"/kubelet"
:
{
0.50
:
0.15
,
0.95
:
0.35
},
"/docker-daemon"
:
{
0.50
:
0.06
,
0.95
:
0.30
},
},
},
}
for
_
,
testArg
:=
range
rTests
{
itArg
:=
testArg
podsPerNode
:=
itArg
.
podsPerNode
name
:=
fmt
.
Sprintf
(
name
:=
fmt
.
Sprintf
(
"
over %v with %d pods per node"
,
monitoringTime
,
podsPerNod
e
)
"
for %d pods per node over %v"
,
podsPerNode
,
monitoringTim
e
)
It
(
name
,
func
()
{
It
(
name
,
func
()
{
runResourceTrackingTest
(
framework
,
podsPerNode
,
nodeNames
,
r
esourceMonitor
)
runResourceTrackingTest
(
framework
,
podsPerNode
,
nodeNames
,
r
m
,
itArg
.
limits
)
})
})
}
}
})
})
Describe
(
"experimental resource usage tracking"
,
func
()
{
Describe
(
"experimental resource usage tracking"
,
func
()
{
density
:=
[]
int
{
5
0
}
density
:=
[]
int
{
10
0
}
for
i
:=
range
density
{
for
i
:=
range
density
{
podsPerNode
:=
density
[
i
]
podsPerNode
:=
density
[
i
]
name
:=
fmt
.
Sprintf
(
name
:=
fmt
.
Sprintf
(
"
over %v with %d pods per node."
,
monitoringTime
,
podsPerNod
e
)
"
for %d pods per node over %v"
,
podsPerNode
,
monitoringTim
e
)
It
(
name
,
func
()
{
It
(
name
,
func
()
{
runResourceTrackingTest
(
framework
,
podsPerNode
,
nodeNames
,
r
esourceMonitor
)
runResourceTrackingTest
(
framework
,
podsPerNode
,
nodeNames
,
r
m
,
nil
)
})
})
}
}
})
})
...
...
test/e2e/kubelet_stats.go
View file @
9067833a
...
@@ -692,7 +692,7 @@ func (r *resourceMonitor) Start() {
...
@@ -692,7 +692,7 @@ func (r *resourceMonitor) Start() {
}
}
r
.
collectors
=
make
(
map
[
string
]
*
resourceCollector
,
0
)
r
.
collectors
=
make
(
map
[
string
]
*
resourceCollector
,
0
)
for
_
,
node
:=
range
nodes
.
Items
{
for
_
,
node
:=
range
nodes
.
Items
{
collector
:=
newResourceCollector
(
r
.
client
,
node
.
Name
,
r
.
containers
,
poll
Interval
)
collector
:=
newResourceCollector
(
r
.
client
,
node
.
Name
,
r
.
containers
,
r
.
polling
Interval
)
r
.
collectors
[
node
.
Name
]
=
collector
r
.
collectors
[
node
.
Name
]
=
collector
collector
.
Start
()
collector
.
Start
()
}
}
...
@@ -716,33 +716,64 @@ func (r *resourceMonitor) LogLatest() {
...
@@ -716,33 +716,64 @@ func (r *resourceMonitor) LogLatest() {
}
}
}
}
func
(
r
*
resourceMonitor
)
LogCPUSummary
()
{
// containersCPUSummary is indexed by the container name with each entry a
// (percentile, value) map.
type
containersCPUSummary
map
[
string
]
map
[
float64
]
float64
// nodesCPUSummary is indexed by the node name with each entry a
// containersCPUSummary map.
type
nodesCPUSummary
map
[
string
]
containersCPUSummary
func
(
r
*
resourceMonitor
)
FormatCPUSummary
(
summary
nodesCPUSummary
)
string
{
// Example output for a node (the percentiles may differ):
// Example output for a node (the percentiles may differ):
// CPU usage of containers on node "e2e-test-
yjhong
-minion-0vj7":
// CPU usage of containers on node "e2e-test-
foo
-minion-0vj7":
// container 5th% 50th% 90th% 95th%
// container 5th% 50th% 90th% 95th%
// "/" 0.051 0.159 0.387 0.455
// "/" 0.051 0.159 0.387 0.455
// "/docker-daemon" 0.000 0.000 0.146 0.166
// "/docker-daemon" 0.000 0.000 0.146 0.166
// "/kubelet" 0.036 0.053 0.091 0.154
// "/kubelet" 0.036 0.053 0.091 0.154
// "/system" 0.001 0.001 0.001 0.002
// "/system" 0.001 0.001 0.001 0.002
var
summaryStrings
[]
string
var
header
[]
string
var
header
[]
string
header
=
append
(
header
,
"container"
)
header
=
append
(
header
,
"container"
)
for
_
,
p
:=
range
percentiles
{
for
_
,
p
:=
range
percentiles
{
header
=
append
(
header
,
fmt
.
Sprintf
(
"%.0fth%%"
,
p
*
100
))
header
=
append
(
header
,
fmt
.
Sprintf
(
"%.0fth%%"
,
p
*
100
))
}
}
for
nodeName
,
co
llector
:=
range
r
.
collectors
{
for
nodeName
,
co
ntainers
:=
range
summary
{
buf
:=
&
bytes
.
Buffer
{}
buf
:=
&
bytes
.
Buffer
{}
w
:=
tabwriter
.
NewWriter
(
buf
,
1
,
0
,
1
,
' '
,
0
)
w
:=
tabwriter
.
NewWriter
(
buf
,
1
,
0
,
1
,
' '
,
0
)
fmt
.
Fprintf
(
w
,
"%s
\n
"
,
strings
.
Join
(
header
,
"
\t
"
))
fmt
.
Fprintf
(
w
,
"%s
\n
"
,
strings
.
Join
(
header
,
"
\t
"
))
for
_
,
containerName
:=
range
targetContainers
()
{
for
_
,
containerName
:=
range
targetContainers
()
{
data
:=
collector
.
GetBasicCPUStats
(
containerName
)
var
s
[]
string
var
s
[]
string
s
=
append
(
s
,
fmt
.
Sprintf
(
"%q"
,
containerName
))
s
=
append
(
s
,
fmt
.
Sprintf
(
"%q"
,
containerName
))
data
,
ok
:=
containers
[
containerName
]
for
_
,
p
:=
range
percentiles
{
for
_
,
p
:=
range
percentiles
{
s
=
append
(
s
,
fmt
.
Sprintf
(
"%.3f"
,
data
[
p
]))
value
:=
"N/A"
if
ok
{
value
=
fmt
.
Sprintf
(
"%.3f"
,
data
[
p
])
}
s
=
append
(
s
,
value
)
}
}
fmt
.
Fprintf
(
w
,
"%s
\n
"
,
strings
.
Join
(
s
,
"
\t
"
))
fmt
.
Fprintf
(
w
,
"%s
\n
"
,
strings
.
Join
(
s
,
"
\t
"
))
}
}
w
.
Flush
()
w
.
Flush
()
Logf
(
"
\n
CPU usage of containers on node %q:
\n
%s"
,
nodeName
,
buf
.
String
(
))
summaryStrings
=
append
(
summaryStrings
,
fmt
.
Sprintf
(
"CPU usage of containers on node %q
\n
:%s"
,
nodeName
,
buf
.
String
()
))
}
}
return
strings
.
Join
(
summaryStrings
,
"
\n
"
)
}
func
(
r
*
resourceMonitor
)
LogCPUSummary
()
{
summary
:=
r
.
GetCPUSummary
()
Logf
(
r
.
FormatCPUSummary
(
summary
))
}
func
(
r
*
resourceMonitor
)
GetCPUSummary
()
nodesCPUSummary
{
result
:=
make
(
nodesCPUSummary
)
for
nodeName
,
collector
:=
range
r
.
collectors
{
result
[
nodeName
]
=
make
(
containersCPUSummary
)
for
_
,
containerName
:=
range
targetContainers
()
{
data
:=
collector
.
GetBasicCPUStats
(
containerName
)
result
[
nodeName
][
containerName
]
=
data
}
}
return
result
}
}
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