Merge pull request #11456 from k8s-infra-cherrypick-robot/cherry-pick-11271-to-release/2.0
[release/2.0] Fix privileged container sysfs can't be rw because pod is ro by default
This commit is contained in:
commit
b98cdb39df
@ -428,3 +428,83 @@ func testStats(t *testing.T,
|
|||||||
require.NotEmpty(t, s.GetWritableLayer().GetInodesUsed().GetValue())
|
require.NotEmpty(t, s.GetWritableLayer().GetInodesUsed().GetValue())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContainerSysfsStatsWithPrivilegedPod(t *testing.T) {
|
||||||
|
if goruntime.GOOS == "windows" {
|
||||||
|
t.Skip("Doesn't care about filesystem properties on windows")
|
||||||
|
}
|
||||||
|
testImage := images.Get(images.BusyBox)
|
||||||
|
testcases := []struct {
|
||||||
|
name string
|
||||||
|
privilegedPod, privilegedContainer bool
|
||||||
|
expectedSysfsOption, expectedErr string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "sandbox and container with privileged=true, sysfs is rw",
|
||||||
|
privilegedPod: true,
|
||||||
|
privilegedContainer: true,
|
||||||
|
expectedSysfsOption: "rw",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "sandbox with privileged=true, and container with privileged=false, sysfs is ro",
|
||||||
|
privilegedPod: true,
|
||||||
|
privilegedContainer: false,
|
||||||
|
expectedSysfsOption: "ro",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "sandbox and container with privileged=false, sysfs is ro",
|
||||||
|
privilegedPod: false,
|
||||||
|
privilegedContainer: false,
|
||||||
|
expectedSysfsOption: "ro",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "sandbox with privileged=false, and container with privileged=true, create container failed",
|
||||||
|
privilegedPod: false,
|
||||||
|
privilegedContainer: true,
|
||||||
|
expectedErr: "failed to generate spec opts: no privileged container allowed in sandbox",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range testcases {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
EnsureImageExists(t, testImage)
|
||||||
|
sb, sbConfig := PodSandboxConfigWithCleanup(
|
||||||
|
t,
|
||||||
|
"sandbox",
|
||||||
|
"sysfs-stats-with-privileged",
|
||||||
|
WithPodSecurityContext(test.privilegedPod),
|
||||||
|
)
|
||||||
|
cnConfig := ContainerConfig(
|
||||||
|
"container",
|
||||||
|
testImage,
|
||||||
|
WithCommand("sh", "-c", "top"),
|
||||||
|
WithSecurityContext(test.privilegedContainer),
|
||||||
|
)
|
||||||
|
cn, err := runtimeService.CreateContainer(sb, cnConfig, sbConfig)
|
||||||
|
if test.expectedErr != "" && err != nil {
|
||||||
|
assert.Contains(t, err.Error(), test.expectedErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer func() {
|
||||||
|
if test.expectedErr == "" {
|
||||||
|
assert.NoError(t, runtimeService.RemoveContainer(cn))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
t.Log("Start the container")
|
||||||
|
require.NoError(t, runtimeService.StartContainer(cn))
|
||||||
|
defer func() {
|
||||||
|
assert.NoError(t, runtimeService.StopContainer(cn, 10))
|
||||||
|
}()
|
||||||
|
|
||||||
|
t.Logf("Execute cmd in container by sync")
|
||||||
|
mountinfo, _, err := runtimeService.ExecSync(cn, []string{
|
||||||
|
"sh",
|
||||||
|
"-c",
|
||||||
|
"mount |grep sysfs",
|
||||||
|
}, 10)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Contains(t, string(mountinfo), test.expectedSysfsOption)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -218,6 +218,19 @@ func WithPodLabels(kvs map[string]string) PodSandboxOpts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithSecurityContext set container privileged.
|
||||||
|
func WithPodSecurityContext(privileged bool) PodSandboxOpts {
|
||||||
|
return func(p *runtime.PodSandboxConfig) {
|
||||||
|
if p.Linux == nil {
|
||||||
|
p.Linux = &runtime.LinuxPodSandboxConfig{}
|
||||||
|
}
|
||||||
|
if p.Linux.SecurityContext == nil {
|
||||||
|
p.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{}
|
||||||
|
}
|
||||||
|
p.Linux.SecurityContext.Privileged = privileged
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// PodSandboxConfig generates a pod sandbox config for test.
|
// PodSandboxConfig generates a pod sandbox config for test.
|
||||||
func PodSandboxConfig(name, ns string, opts ...PodSandboxOpts) *runtime.PodSandboxConfig {
|
func PodSandboxConfig(name, ns string, opts ...PodSandboxOpts) *runtime.PodSandboxConfig {
|
||||||
var cgroupParent string
|
var cgroupParent string
|
||||||
@ -462,6 +475,19 @@ func WithSupplementalGroups(gids []int64) ContainerOpts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithSecurityContext set container privileged.
|
||||||
|
func WithSecurityContext(privileged bool) ContainerOpts {
|
||||||
|
return func(c *runtime.ContainerConfig) {
|
||||||
|
if c.Linux == nil {
|
||||||
|
c.Linux = &runtime.LinuxContainerConfig{}
|
||||||
|
}
|
||||||
|
if c.Linux.SecurityContext == nil {
|
||||||
|
c.Linux.SecurityContext = &runtime.LinuxContainerSecurityContext{}
|
||||||
|
}
|
||||||
|
c.Linux.SecurityContext.Privileged = privileged
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithDevice adds a device mount.
|
// WithDevice adds a device mount.
|
||||||
func WithDevice(containerPath, hostPath, permissions string) ContainerOpts {
|
func WithDevice(containerPath, hostPath, permissions string) ContainerOpts {
|
||||||
return func(c *runtime.ContainerConfig) {
|
return func(c *runtime.ContainerConfig) {
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/containerd/log"
|
"github.com/containerd/log"
|
||||||
"github.com/containerd/nri"
|
"github.com/containerd/nri"
|
||||||
@ -136,6 +137,7 @@ func (c *Controller) Start(ctx context.Context, id string) (cin sandbox.Controll
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return cin, fmt.Errorf("failed to generate sandbox container spec: %w", err)
|
return cin, fmt.Errorf("failed to generate sandbox container spec: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.G(ctx).WithField("podsandboxid", id).Debugf("sandbox container spec: %#+v", spew.NewFormatter(spec))
|
log.G(ctx).WithField("podsandboxid", id).Debugf("sandbox container spec: %#+v", spew.NewFormatter(spec))
|
||||||
|
|
||||||
metadata.ProcessLabel = spec.Process.SelinuxLabel
|
metadata.ProcessLabel = spec.Process.SelinuxLabel
|
||||||
@ -155,6 +157,18 @@ func (c *Controller) Start(ctx context.Context, id string) (cin sandbox.Controll
|
|||||||
// If privileged don't set selinux label, but we still record the MCS label so that
|
// If privileged don't set selinux label, but we still record the MCS label so that
|
||||||
// the unused label can be freed later.
|
// the unused label can be freed later.
|
||||||
spec.Process.SelinuxLabel = ""
|
spec.Process.SelinuxLabel = ""
|
||||||
|
// If privileged is enabled, sysfs should have the rw attribute
|
||||||
|
for i, k := range spec.Mounts {
|
||||||
|
if filepath.Clean(k.Destination) == "/sys" {
|
||||||
|
for j, v := range spec.Mounts[i].Options {
|
||||||
|
if v == "ro" {
|
||||||
|
spec.Mounts[i].Options[j] = "rw"
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate spec options that will be applied to the spec later.
|
// Generate spec options that will be applied to the spec later.
|
||||||
|
Loading…
Reference in New Issue
Block a user