Skip to content

Commit 2e9a711

Browse files
Merge pull request cri-o#5277 from ajwock/cgv2-rw
Make /sys/fs/cgroup writable when non-privileged and using cgroups v2
2 parents b026482 + 10f8f17 commit 2e9a711

File tree

4 files changed

+87
-5
lines changed

4 files changed

+87
-5
lines changed

pkg/annotations/annotations.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ const (
88
// UsernsMode is the user namespace mode to use
99
UsernsModeAnnotation = "io.kubernetes.cri-o.userns-mode"
1010

11+
// CgroupRW specifies mounting v2 cgroups as an rw filesystem.
12+
Cgroup2RWAnnotation = "io.kubernetes.cri-o.cgroup2-mount-hierarchy-rw"
13+
1114
// UnifiedCgroupAnnotation specifies the unified configuration for cgroup v2
1215
UnifiedCgroupAnnotation = "io.kubernetes.cri-o.UnifiedCgroup"
1316

@@ -39,6 +42,7 @@ const (
3942

4043
var AllAllowedAnnotations = []string{
4144
UsernsModeAnnotation,
45+
Cgroup2RWAnnotation,
4246
UnifiedCgroupAnnotation,
4347
ShmSizeAnnotation,
4448
DevicesAnnotation,

pkg/config/template.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,7 @@ const templateStringCrioRuntimeRuntimesRuntimeHandler = `# The "crio.runtime.run
10241024
# a list of experimental annotations that this runtime handler is allowed to process.
10251025
# The currently recognized values are:
10261026
# "io.kubernetes.cri-o.userns-mode" for configuring a user namespace for the pod.
1027+
# "io.kubernetes.cri-o.cgroup2-mount-hierarchy-rw" for mounting cgroups writably when set to "true".
10271028
# "io.kubernetes.cri-o.Devices" for configuring devices for the pod.
10281029
# "io.kubernetes.cri-o.ShmSize" for configuring the size of /dev/shm.
10291030
# "io.kubernetes.cri-o.UnifiedCgroup.$CTR_NAME" for configuring the cgroup v2 unified block for a container.

server/container_create_linux.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,9 @@ func (s *Server) createSandboxContainer(ctx context.Context, ctr ctrIface.Contai
291291
skipRelabel = true
292292
}
293293

294-
containerVolumes, ociMounts, err := addOCIBindMounts(ctx, ctr, mountLabel, s.config.RuntimeConfig.BindMountPrefix, s.config.AbsentMountSourcesToReject, maybeRelabel, skipRelabel)
294+
cgroup2RW := node.CgroupIsV2() && sb.Annotations()[crioann.Cgroup2RWAnnotation] == "true"
295+
296+
containerVolumes, ociMounts, err := addOCIBindMounts(ctx, ctr, mountLabel, s.config.RuntimeConfig.BindMountPrefix, s.config.AbsentMountSourcesToReject, maybeRelabel, skipRelabel, cgroup2RW)
295297
if err != nil {
296298
return nil, err
297299
}
@@ -843,7 +845,7 @@ func clearReadOnly(m *rspec.Mount) {
843845
m.Options = append(m.Options, "rw")
844846
}
845847

846-
func addOCIBindMounts(ctx context.Context, ctr ctrIface.Container, mountLabel, bindMountPrefix string, absentMountSourcesToReject []string, maybeRelabel, skipRelabel bool) ([]oci.ContainerVolume, []rspec.Mount, error) {
848+
func addOCIBindMounts(ctx context.Context, ctr ctrIface.Container, mountLabel, bindMountPrefix string, absentMountSourcesToReject []string, maybeRelabel, skipRelabel, cgroup2RW bool) ([]oci.ContainerVolume, []rspec.Mount, error) {
847849
volumes := []oci.ContainerVolume{}
848850
ociMounts := []rspec.Mount{}
849851
containerConfig := ctr.Config()
@@ -978,7 +980,13 @@ func addOCIBindMounts(ctx context.Context, ctr ctrIface.Container, mountLabel, b
978980
Destination: "/sys/fs/cgroup",
979981
Type: "cgroup",
980982
Source: "cgroup",
981-
Options: []string{"nosuid", "noexec", "nodev", "relatime", "ro"},
983+
Options: []string{"nosuid", "noexec", "nodev", "relatime"},
984+
}
985+
986+
if cgroup2RW {
987+
m.Options = append(m.Options, "rw")
988+
} else {
989+
m.Options = append(m.Options, "ro")
982990
}
983991
specgen.AddMount(m)
984992
}

server/container_create_linux_test.go

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func TestAddOCIBindsForDev(t *testing.T) {
3434
t.Error(err)
3535
}
3636

37-
_, binds, err := addOCIBindMounts(context.Background(), ctr, "", "", nil, false, false)
37+
_, binds, err := addOCIBindMounts(context.Background(), ctr, "", "", nil, false, false, false)
3838
if err != nil {
3939
t.Error(err)
4040
}
@@ -78,7 +78,7 @@ func TestAddOCIBindsForSys(t *testing.T) {
7878
t.Error(err)
7979
}
8080

81-
_, binds, err := addOCIBindMounts(context.Background(), ctr, "", "", nil, false, false)
81+
_, binds, err := addOCIBindMounts(context.Background(), ctr, "", "", nil, false, false, false)
8282
if err != nil {
8383
t.Error(err)
8484
}
@@ -92,3 +92,72 @@ func TestAddOCIBindsForSys(t *testing.T) {
9292
t.Error("there is not a single /sys bind mount")
9393
}
9494
}
95+
96+
func TestAddOCIBindsCGroupRW(t *testing.T) {
97+
ctr, err := container.New()
98+
if err != nil {
99+
t.Error(err)
100+
}
101+
102+
if err := ctr.SetConfig(&types.ContainerConfig{
103+
Metadata: &types.ContainerMetadata{
104+
Name: "testctr",
105+
},
106+
}, &types.PodSandboxConfig{
107+
Metadata: &types.PodSandboxMetadata{
108+
Name: "testpod",
109+
},
110+
}); err != nil {
111+
t.Error(err)
112+
}
113+
_, _, err = addOCIBindMounts(context.Background(), ctr, "", "", nil, false, false, true)
114+
if err != nil {
115+
t.Error(err)
116+
}
117+
var hasCgroupRW bool
118+
for _, m := range ctr.Spec().Mounts() {
119+
if m.Destination == "/sys/fs/cgroup" {
120+
for _, o := range m.Options {
121+
if o == "rw" {
122+
hasCgroupRW = true
123+
}
124+
}
125+
}
126+
}
127+
if !hasCgroupRW {
128+
t.Error("Cgroup mount not added with RW.")
129+
}
130+
131+
ctr, err = container.New()
132+
if err != nil {
133+
t.Error(err)
134+
}
135+
if err := ctr.SetConfig(&types.ContainerConfig{
136+
Metadata: &types.ContainerMetadata{
137+
Name: "testctr",
138+
},
139+
}, &types.PodSandboxConfig{
140+
Metadata: &types.PodSandboxMetadata{
141+
Name: "testpod",
142+
},
143+
}); err != nil {
144+
t.Error(err)
145+
}
146+
var hasCgroupRO bool
147+
_, _, err = addOCIBindMounts(context.Background(), ctr, "", "", nil, false, false, false)
148+
if err != nil {
149+
t.Error(err)
150+
}
151+
for _, m := range ctr.Spec().Mounts() {
152+
if m.Destination == "/sys/fs/cgroup" {
153+
for _, o := range m.Options {
154+
if o == "ro" {
155+
hasCgroupRO = true
156+
}
157+
}
158+
}
159+
}
160+
if !hasCgroupRO {
161+
t.Error("Cgroup mount not added with RO.")
162+
}
163+
}

0 commit comments

Comments
 (0)