Skip to content

Commit 0f5cd78

Browse files
committed
feature: namespace options and supplemental groups for cri manager
Signed-off-by: YaoZengzeng <[email protected]>
1 parent b41c5f0 commit 0f5cd78

File tree

6 files changed

+107
-17
lines changed

6 files changed

+107
-17
lines changed

cli/common_flags.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ func addCommonFlags(flagSet *pflag.FlagSet) *container {
6969
// user
7070
flagSet.StringVarP(&c.user, "user", "u", "", "UID")
7171

72+
flagSet.StringSliceVar(&c.groupAdd, "group-add", nil, "Add additional groups to join")
73+
7274
flagSet.StringVar(&c.utsMode, "uts", "", "UTS namespace to use")
7375

7476
flagSet.StringSliceVarP(&c.volume, "volume", "v", nil, "Bind mount volumes to container")

cli/container.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type container struct {
2323
entrypoint string
2424
workdir string
2525
user string
26+
groupAdd []string
2627
hostname string
2728
cpushare int64
2829
cpusetcpus string
@@ -169,6 +170,7 @@ func (c *container) config() (*types.ContainerCreateConfig, error) {
169170
IpcMode: c.ipcMode,
170171
PidMode: c.pidMode,
171172
UTSMode: c.utsMode,
173+
GroupAdd: c.groupAdd,
172174
Sysctls: sysctls,
173175
SecurityOpt: c.securityOpt,
174176
NetworkMode: networkMode,

daemon/mgr/cri.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ const (
4343
nameDelimiter = "_"
4444

4545
defaultSandboxImage = "k8s.gcr.io/pause-amd64:3.0"
46+
47+
namespaceModeHost = "host"
48+
namespaceModeNone = "none"
4649
)
4750

4851
var (

daemon/mgr/cri_utils.go

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,59 @@ func parseSandboxName(name string) (*runtime.PodSandboxMetadata, error) {
157157
}, nil
158158
}
159159

160+
func modifySandboxNamespaceOptions(nsOpts *runtime.NamespaceOption, hostConfig *apitypes.HostConfig) {
161+
if nsOpts == nil {
162+
return
163+
}
164+
if nsOpts.HostPid {
165+
hostConfig.PidMode = namespaceModeHost
166+
}
167+
if nsOpts.HostIpc {
168+
hostConfig.IpcMode = namespaceModeHost
169+
}
170+
if nsOpts.HostNetwork {
171+
hostConfig.NetworkMode = namespaceModeHost
172+
}
173+
}
174+
175+
func applySandboxSecurityContext(lc *runtime.LinuxPodSandboxConfig, config *apitypes.ContainerConfig, hc *apitypes.HostConfig) error {
176+
if lc == nil {
177+
return nil
178+
}
179+
180+
var sc *runtime.LinuxContainerSecurityContext
181+
if lc.SecurityContext != nil {
182+
sc = &runtime.LinuxContainerSecurityContext{
183+
SupplementalGroups: lc.SecurityContext.SupplementalGroups,
184+
RunAsUser: lc.SecurityContext.RunAsUser,
185+
ReadonlyRootfs: lc.SecurityContext.ReadonlyRootfs,
186+
SelinuxOptions: lc.SecurityContext.SelinuxOptions,
187+
NamespaceOptions: lc.SecurityContext.NamespaceOptions,
188+
}
189+
}
190+
191+
modifyContainerConfig(sc, config)
192+
err := modifyHostConfig(sc, hc)
193+
if err != nil {
194+
return err
195+
}
196+
modifySandboxNamespaceOptions(sc.GetNamespaceOptions(), hc)
197+
198+
return nil
199+
}
200+
160201
// applySandboxLinuxOptions applies LinuxPodSandboxConfig to pouch's HostConfig and ContainerCreateConfig.
161202
func applySandboxLinuxOptions(hc *apitypes.HostConfig, lc *runtime.LinuxPodSandboxConfig, createConfig *apitypes.ContainerCreateConfig, image string) error {
162203
if lc == nil {
163204
return nil
164205
}
165206

207+
// Apply security context.
208+
err := applySandboxSecurityContext(lc, &createConfig.ContainerConfig, hc)
209+
if err != nil {
210+
return err
211+
}
212+
166213
// Set sysctls.
167214
hc.Sysctls = lc.Sysctls
168215
return nil
@@ -290,12 +337,33 @@ func parseContainerName(name string) (*runtime.ContainerMetadata, error) {
290337

291338
// modifyContainerNamespaceOptions apply namespace options for container.
292339
func modifyContainerNamespaceOptions(nsOpts *runtime.NamespaceOption, podSandboxID string, hostConfig *apitypes.HostConfig) {
340+
if nsOpts == nil {
341+
return
342+
}
293343
sandboxNSMode := fmt.Sprintf("container:%v", podSandboxID)
294-
295-
hostConfig.PidMode = sandboxNSMode
296-
hostConfig.NetworkMode = sandboxNSMode
297-
hostConfig.IpcMode = sandboxNSMode
298-
hostConfig.UTSMode = sandboxNSMode
344+
for _, n := range []struct {
345+
hostMode bool
346+
nsMode *string
347+
}{
348+
{
349+
hostMode: nsOpts.HostPid,
350+
nsMode: &hostConfig.PidMode,
351+
},
352+
{
353+
hostMode: nsOpts.HostIpc,
354+
nsMode: &hostConfig.IpcMode,
355+
},
356+
{
357+
hostMode: nsOpts.HostNetwork,
358+
nsMode: &hostConfig.NetworkMode,
359+
},
360+
} {
361+
if n.hostMode {
362+
*n.nsMode = namespaceModeHost
363+
} else {
364+
*n.nsMode = sandboxNSMode
365+
}
366+
}
299367
}
300368

301369
// getAppArmorSecurityOpts gets appArmor options from container config.
@@ -346,6 +414,11 @@ func modifyHostConfig(sc *runtime.LinuxContainerSecurityContext, hostConfig *api
346414
return nil
347415
}
348416

417+
// Apply supplemental groups.
418+
for _, group := range sc.SupplementalGroups {
419+
hostConfig.GroupAdd = append(hostConfig.GroupAdd, strconv.FormatInt(group, 10))
420+
}
421+
349422
// TODO: apply other security options.
350423

351424
// Apply capability options.

daemon/mgr/spec_process.go

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"strings"
77

88
specs "github.com/opencontainers/runtime-spec/specs-go"
9+
"github.com/sirupsen/logrus"
910
)
1011

1112
func setupCap(ctx context.Context, c *ContainerMeta, spec *SpecWrapper) error {
@@ -58,21 +59,30 @@ func setupProcessTTY(ctx context.Context, c *ContainerMeta, spec *SpecWrapper) e
5859
}
5960

6061
func setupProcessUser(ctx context.Context, c *ContainerMeta, spec *SpecWrapper) (err error) {
62+
user := specs.User{}
63+
6164
// The user option is complicated, now we only handle case "uid".
6265
// TODO: handle other cases like "user", "uid:gid", etc.
63-
if c.Config.User == "" {
64-
return nil
66+
if c.Config.User != "" {
67+
fields := strings.Split(c.Config.User, ":")
68+
var u string
69+
u = fields[0]
70+
if uid, err := strconv.Atoi(u); err == nil {
71+
user.UID = uint32(uid)
72+
} else {
73+
user.Username = u
74+
}
6575
}
6676

67-
fields := strings.Split(c.Config.User, ":")
68-
var u string
69-
u = fields[0]
70-
user := specs.User{}
71-
if uid, err := strconv.Atoi(u); err == nil {
72-
user.UID = uint32(uid)
73-
} else {
74-
user.Username = u
77+
for _, group := range c.HostConfig.GroupAdd {
78+
gid, err := strconv.ParseUint(group, 10, 32)
79+
if err != nil {
80+
logrus.Errorf("failed to parse supplemental group id %s: %v", group, err)
81+
continue
82+
}
83+
user.AdditionalGids = append(user.AdditionalGids, uint32(gid))
7584
}
85+
7686
spec.s.Process.User = user
7787

7888
return nil

hack/cri-test/test-cri.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ POUCH_SOCK="/var/run/pouchcri.sock"
2323

2424
# CRI_FOCUS focuses the test to run.
2525
# With the CRI manager completes its function, we may need to expand this field.
26-
CRI_FOCUS=${CRI_FOCUS:-"PodSandbox|AppArmor|Privileged is true|basic operations on container|Runtime info|mount propagation|volume and device|RunAsUser|container port"}
26+
CRI_FOCUS=${CRI_FOCUS:-"PodSandbox|AppArmor|Privileged is true|basic operations on container|Runtime info|mount propagation|volume and device|RunAsUser|container port|NamespaceOption|SupplementalGroups"}
2727

2828
# CRI_SKIP skips the test to skip.
29-
CRI_SKIP=${CRI_SKIP:-"RunAsUserName"}
29+
CRI_SKIP=${CRI_SKIP:-"RunAsUserName|HostNetwork"}
3030
# REPORT_DIR is the the directory to store test logs.
3131
REPORT_DIR=${REPORT_DIR:-"/tmp/test-cri"}
3232

0 commit comments

Comments
 (0)