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
e0611972
Unverified
Commit
e0611972
authored
Feb 09, 2021
by
Brad Davidson
Committed by
GitHub
Feb 09, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve handling of comounted cpu,cpuacct controllers (#2911)
* Improve handling of comounted cpu,cpuacct controllers Signed-off-by:
Brad Davidson
<
brad.davidson@rancher.com
>
parent
41fd27ab
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
40 additions
and
26 deletions
+40
-26
agent.go
pkg/daemons/agent/agent.go
+40
-26
No files found.
pkg/daemons/agent/agent.go
View file @
e0611972
...
@@ -184,14 +184,11 @@ func addFeatureGate(current, new string) string {
...
@@ -184,14 +184,11 @@ func addFeatureGate(current, new string) string {
}
}
func
checkCgroups
()
(
kubeletRoot
,
runtimeRoot
string
,
hasCFS
,
hasPIDs
bool
)
{
func
checkCgroups
()
(
kubeletRoot
,
runtimeRoot
string
,
hasCFS
,
hasPIDs
bool
)
{
f
,
err
:=
os
.
Open
(
"/proc/self/cgroup"
)
cgroupsModeV2
:=
cgroups
.
Mode
()
==
cgroups
.
Unified
if
err
!=
nil
{
return
""
,
""
,
false
,
false
}
defer
f
.
Close
()
v2
:=
cgroups
.
Mode
()
==
cgroups
.
Unified
// For Unified (v2) cgroups we can directly check to see what controllers are mounted
if
v2
{
// under the unified hierarchy.
if
cgroupsModeV2
{
m
,
err
:=
cgroupsv2
.
LoadManager
(
"/sys/fs/cgroup"
,
"/"
)
m
,
err
:=
cgroupsv2
.
LoadManager
(
"/sys/fs/cgroup"
,
"/"
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
""
,
false
,
false
return
""
,
""
,
false
,
false
...
@@ -200,33 +197,35 @@ func checkCgroups() (kubeletRoot, runtimeRoot string, hasCFS, hasPIDs bool) {
...
@@ -200,33 +197,35 @@ func checkCgroups() (kubeletRoot, runtimeRoot string, hasCFS, hasPIDs bool) {
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
""
,
false
,
false
return
""
,
""
,
false
,
false
}
}
for
_
,
c
:=
range
controllers
{
// Intentionally using an expressionless switch to match the logic below
switch
c
{
for
_
,
controller
:=
range
controllers
{
case
"cpu"
:
switch
{
case
controller
==
"cpu"
:
hasCFS
=
true
hasCFS
=
true
case
"pids"
:
case
controller
==
"pids"
:
hasPIDs
=
true
hasPIDs
=
true
}
}
}
}
}
}
f
,
err
:=
os
.
Open
(
"/proc/self/cgroup"
)
if
err
!=
nil
{
return
""
,
""
,
false
,
false
}
defer
f
.
Close
()
scan
:=
bufio
.
NewScanner
(
f
)
scan
:=
bufio
.
NewScanner
(
f
)
for
scan
.
Scan
()
{
for
scan
.
Scan
()
{
parts
:=
strings
.
Split
(
scan
.
Text
(),
":"
)
parts
:=
strings
.
Split
(
scan
.
Text
(),
":"
)
if
len
(
parts
)
<
3
{
if
len
(
parts
)
<
3
{
continue
continue
}
}
systems
:=
strings
.
Split
(
parts
[
1
],
","
)
controllers
:=
strings
.
Split
(
parts
[
1
],
","
)
// when v2, systems = {""} (only contains a single empty string)
// For v1 or hybrid, controller can be a single value {"blkio"}, or a comounted set {"cpu","cpuacct"}
for
_
,
system
:=
range
systems
{
// For v2, controllers = {""} (only contains a single empty string)
if
system
==
"pids"
{
for
_
,
controller
:=
range
controllers
{
hasPIDs
=
true
switch
{
}
else
if
system
==
"cpu"
{
case
controller
==
"name=systemd"
||
cgroupsModeV2
:
p
:=
filepath
.
Join
(
"/sys/fs/cgroup"
,
parts
[
1
],
parts
[
2
],
"cpu.cfs_period_us"
)
if
_
,
err
:=
os
.
Stat
(
p
);
err
==
nil
{
hasCFS
=
true
}
}
else
if
system
==
"name=systemd"
||
v2
{
// If we detect that we are running under a `.scope` unit with systemd
// If we detect that we are running under a `.scope` unit with systemd
// we can assume we are being directly invoked from the command line
// we can assume we are being directly invoked from the command line
// and thus need to set our kubelet root to something out of the context
// and thus need to set our kubelet root to something out of the context
...
@@ -240,10 +239,23 @@ func checkCgroups() (kubeletRoot, runtimeRoot string, hasCFS, hasPIDs bool) {
...
@@ -240,10 +239,23 @@ func checkCgroups() (kubeletRoot, runtimeRoot string, hasCFS, hasPIDs bool) {
if
i
>
0
{
if
i
>
0
{
kubeletRoot
=
"/"
+
version
.
Program
kubeletRoot
=
"/"
+
version
.
Program
}
}
case
controller
==
"cpu"
:
// It is common for this to show up multiple times in /sys/fs/cgroup if the controllers are comounted:
// as "cpu" and "cpuacct", symlinked to the actual hierarchy at "cpu,cpuacct". Unfortunately the order
// listed in /proc/self/cgroups may not be the same order used in /sys/fs/cgroup, so this check
// can fail if we use the comma-separated name. Instead, we check for the controller using the symlink.
p
:=
filepath
.
Join
(
"/sys/fs/cgroup"
,
controller
,
parts
[
2
],
"cpu.cfs_period_us"
)
if
_
,
err
:=
os
.
Stat
(
p
);
err
==
nil
{
hasCFS
=
true
}
case
controller
==
"pids"
:
hasPIDs
=
true
}
}
}
}
}
}
// If we're running with v1 and didn't find a scope assigned by systemd, we need to create our own root cgroup to avoid
// just inheriting from the parent process. The kubelet will take care of moving us into it when we start it up later.
if
kubeletRoot
==
""
{
if
kubeletRoot
==
""
{
// Examine process ID 1 to see if there is a cgroup assigned to it.
// Examine process ID 1 to see if there is a cgroup assigned to it.
// When we are not in a container, process 1 is likely to be systemd or some other service manager.
// When we are not in a container, process 1 is likely to be systemd or some other service manager.
...
@@ -261,10 +273,12 @@ func checkCgroups() (kubeletRoot, runtimeRoot string, hasCFS, hasPIDs bool) {
...
@@ -261,10 +273,12 @@ func checkCgroups() (kubeletRoot, runtimeRoot string, hasCFS, hasPIDs bool) {
if
len
(
parts
)
<
3
{
if
len
(
parts
)
<
3
{
continue
continue
}
}
systems
:=
strings
.
Split
(
parts
[
1
],
","
)
controllers
:=
strings
.
Split
(
parts
[
1
],
","
)
// when v2, systems = {""} (only contains a single empty string)
// For v1 or hybrid, controller can be a single value {"blkio"}, or a comounted set {"cpu","cpuacct"}
for
_
,
system
:=
range
systems
{
// For v2, controllers = {""} (only contains a single empty string)
if
system
==
"name=systemd"
||
v2
{
for
_
,
controller
:=
range
controllers
{
switch
{
case
controller
==
"name=systemd"
||
cgroupsModeV2
:
last
:=
parts
[
len
(
parts
)
-
1
]
last
:=
parts
[
len
(
parts
)
-
1
]
if
last
!=
"/"
&&
last
!=
"/init.scope"
{
if
last
!=
"/"
&&
last
!=
"/init.scope"
{
kubeletRoot
=
"/"
+
version
.
Program
kubeletRoot
=
"/"
+
version
.
Program
...
...
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