mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-18 17:01:07 +00:00
Add partial user namespace support
This adds the OCI parts needed into the yaml, but there are still permissions issues in practise so marked as experimental. It may just need further documentation to resolve the issues. Signed-off-by: Justin Cormack <justin.cormack@docker.com>
This commit is contained in:
parent
c7c4c9ef2a
commit
a73c3d3667
@ -158,6 +158,9 @@ bind mounted into a container.
|
||||
- `sysctl` sets a list of `sysctl` key value pairs that are set inside the container namespace.
|
||||
- `rmlimits` sets a list of `rlimit` values in the form `name,soft,hard`, eg `nofile,100,200`. You can use `unlimited` as a value too.
|
||||
|
||||
There are experimental `userns`, `uidMappings` and `gidMappings` options for user namespaces but these are not yet supported, and may have
|
||||
permissions issues in use.
|
||||
|
||||
### Mount Options
|
||||
When mounting filesystem paths into a container - whether as part of `onboot` or `services` - there are several options of which you need to be aware. Using them properly is necessary for your containers to function properly.
|
||||
|
||||
|
@ -51,34 +51,37 @@ type File struct {
|
||||
|
||||
// Image is the type of an image config
|
||||
type Image struct {
|
||||
Name string `yaml:"name" json:"name"`
|
||||
Image string `yaml:"image" json:"image"`
|
||||
Capabilities *[]string `yaml:"capabilities" json:"capabilities,omitempty"`
|
||||
Ambient *[]string `yaml:"ambient" json:"ambient,omitempty"`
|
||||
Mounts *[]specs.Mount `yaml:"mounts" json:"mounts,omitempty"`
|
||||
Binds *[]string `yaml:"binds" json:"binds,omitempty"`
|
||||
Tmpfs *[]string `yaml:"tmpfs" json:"tmpfs,omitempty"`
|
||||
Command *[]string `yaml:"command" json:"command,omitempty"`
|
||||
Env *[]string `yaml:"env" json:"env,omitempty"`
|
||||
Cwd string `yaml:"cwd" json:"cwd"`
|
||||
Net string `yaml:"net" json:"net"`
|
||||
Pid string `yaml:"pid" json:"pid"`
|
||||
Ipc string `yaml:"ipc" json:"ipc"`
|
||||
Uts string `yaml:"uts" json:"uts"`
|
||||
Hostname string `yaml:"hostname" json:"hostname"`
|
||||
Readonly *bool `yaml:"readonly" json:"readonly,omitempty"`
|
||||
MaskedPaths *[]string `yaml:"maskedPaths" json:"maskedPaths,omitempty"`
|
||||
ReadonlyPaths *[]string `yaml:"readonlyPaths" json:"readonlyPaths,omitempty"`
|
||||
UID *string `yaml:"uid" json:"uid,omitempty"`
|
||||
GID *string `yaml:"gid" json:"gid,omitempty"`
|
||||
AdditionalGids *[]string `yaml:"additionalGids" json:"additionalGids,omitempty"`
|
||||
NoNewPrivileges *bool `yaml:"noNewPrivileges" json:"noNewPrivileges,omitempty"`
|
||||
OOMScoreAdj *int `yaml:"oomScoreAdj" json:"oomScoreAdj,omitempty"`
|
||||
DisableOOMKiller *bool `yaml:"disableOOMKiller" json:"disableOOMKiller,omitempty"`
|
||||
RootfsPropagation *string `yaml:"rootfsPropagation" json:"rootfsPropagation,omitempty"`
|
||||
CgroupsPath *string `yaml:"cgroupsPath" json:"cgroupsPath,omitempty"`
|
||||
Sysctl *map[string]string `yaml:"sysctl" json:"sysctl,omitempty"`
|
||||
Rlimits *[]string `yaml:"rlimits" json:"rlimits,omitempty"`
|
||||
Name string `yaml:"name" json:"name"`
|
||||
Image string `yaml:"image" json:"image"`
|
||||
Capabilities *[]string `yaml:"capabilities" json:"capabilities,omitempty"`
|
||||
Ambient *[]string `yaml:"ambient" json:"ambient,omitempty"`
|
||||
Mounts *[]specs.Mount `yaml:"mounts" json:"mounts,omitempty"`
|
||||
Binds *[]string `yaml:"binds" json:"binds,omitempty"`
|
||||
Tmpfs *[]string `yaml:"tmpfs" json:"tmpfs,omitempty"`
|
||||
Command *[]string `yaml:"command" json:"command,omitempty"`
|
||||
Env *[]string `yaml:"env" json:"env,omitempty"`
|
||||
Cwd string `yaml:"cwd" json:"cwd"`
|
||||
Net string `yaml:"net" json:"net"`
|
||||
Pid string `yaml:"pid" json:"pid"`
|
||||
Ipc string `yaml:"ipc" json:"ipc"`
|
||||
Uts string `yaml:"uts" json:"uts"`
|
||||
Userns string `yaml:"userns" json:"userns"`
|
||||
Hostname string `yaml:"hostname" json:"hostname"`
|
||||
Readonly *bool `yaml:"readonly" json:"readonly,omitempty"`
|
||||
MaskedPaths *[]string `yaml:"maskedPaths" json:"maskedPaths,omitempty"`
|
||||
ReadonlyPaths *[]string `yaml:"readonlyPaths" json:"readonlyPaths,omitempty"`
|
||||
UID *string `yaml:"uid" json:"uid,omitempty"`
|
||||
GID *string `yaml:"gid" json:"gid,omitempty"`
|
||||
AdditionalGids *[]string `yaml:"additionalGids" json:"additionalGids,omitempty"`
|
||||
NoNewPrivileges *bool `yaml:"noNewPrivileges" json:"noNewPrivileges,omitempty"`
|
||||
OOMScoreAdj *int `yaml:"oomScoreAdj" json:"oomScoreAdj,omitempty"`
|
||||
DisableOOMKiller *bool `yaml:"disableOOMKiller" json:"disableOOMKiller,omitempty"`
|
||||
RootfsPropagation *string `yaml:"rootfsPropagation" json:"rootfsPropagation,omitempty"`
|
||||
CgroupsPath *string `yaml:"cgroupsPath" json:"cgroupsPath,omitempty"`
|
||||
Sysctl *map[string]string `yaml:"sysctl" json:"sysctl,omitempty"`
|
||||
Rlimits *[]string `yaml:"rlimits" json:"rlimits,omitempty"`
|
||||
UIDMappings *[]specs.LinuxIDMapping `yaml:"uidMappings" json:"uidMappings,omitempty"`
|
||||
GIDMappings *[]specs.LinuxIDMapping `yaml:"gidMappings" json:"gidMappings,omitempty"`
|
||||
}
|
||||
|
||||
// github.com/go-yaml/yaml treats map keys as interface{} while encoding/json
|
||||
@ -390,6 +393,17 @@ func assignString(v1, v2 *string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// assignMappings does prdered overrides from UID, GID maps
|
||||
func assignMappings(v1, v2 *[]specs.LinuxIDMapping) []specs.LinuxIDMapping {
|
||||
if v2 != nil {
|
||||
return *v2
|
||||
}
|
||||
if v1 != nil {
|
||||
return *v1
|
||||
}
|
||||
return []specs.LinuxIDMapping{}
|
||||
}
|
||||
|
||||
// assignStringEmpty does ordered overrides if strings are empty, for
|
||||
// values where there is always an explicit override eg "none"
|
||||
func assignStringEmpty(v1, v2 string) string {
|
||||
@ -604,7 +618,7 @@ func ConfigInspectToOCI(yaml Image, inspect types.ImageInspect, idMap map[string
|
||||
namespaces := []specs.LinuxNamespace{}
|
||||
// to attach to an existing namespace, easiest to bind mount with nsfs in a system container
|
||||
|
||||
// net, ipc and uts namespaces: default to not creating a new namespace (usually host namespace)
|
||||
// net, ipc, and uts namespaces: default to not creating a new namespace (usually host namespace)
|
||||
netNS := assignStringEmpty3("root", label.Net, yaml.Net)
|
||||
if netNS != "host" && netNS != "root" {
|
||||
if netNS == "none" || netNS == "new" {
|
||||
@ -636,10 +650,19 @@ func ConfigInspectToOCI(yaml Image, inspect types.ImageInspect, idMap map[string
|
||||
namespaces = append(namespaces, specs.LinuxNamespace{Type: specs.PIDNamespace, Path: pidNS})
|
||||
}
|
||||
|
||||
// do not create a user namespace unless asked, needs additional configuration
|
||||
userNS := assignStringEmpty3("root", label.Userns, yaml.Userns)
|
||||
if userNS != "host" && userNS != "root" {
|
||||
if userNS == "new" {
|
||||
userNS = ""
|
||||
}
|
||||
namespaces = append(namespaces, specs.LinuxNamespace{Type: specs.UserNamespace, Path: userNS})
|
||||
}
|
||||
|
||||
// Always create a new mount namespace
|
||||
namespaces = append(namespaces, specs.LinuxNamespace{Type: specs.MountNamespace})
|
||||
|
||||
// TODO user, cgroup namespaces
|
||||
// TODO cgroup namespaces
|
||||
|
||||
// Capabilities
|
||||
capCheck := map[string]bool{}
|
||||
@ -806,9 +829,9 @@ func ConfigInspectToOCI(yaml Image, inspect types.ImageInspect, idMap map[string
|
||||
oci.Mounts = mountList
|
||||
|
||||
oci.Linux = &specs.Linux{
|
||||
// UIDMappings
|
||||
// GIDMappings
|
||||
Sysctl: assignMaps(label.Sysctl, yaml.Sysctl),
|
||||
UIDMappings: assignMappings(label.UIDMappings, yaml.UIDMappings),
|
||||
GIDMappings: assignMappings(label.GIDMappings, yaml.GIDMappings),
|
||||
Sysctl: assignMaps(label.Sysctl, yaml.Sysctl),
|
||||
Resources: &specs.LinuxResources{
|
||||
// Devices
|
||||
DisableOOMKiller: assignBoolPtr(label.DisableOOMKiller, yaml.DisableOOMKiller),
|
||||
|
@ -59,6 +59,19 @@ var schema = string(`
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/mount" }
|
||||
},
|
||||
"idmapping": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"hostID": { "type": "integer" },
|
||||
"containerID": { "type": "integer" },
|
||||
"size": { "type": "integer" }
|
||||
}
|
||||
},
|
||||
"idmappings": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/idmapping" }
|
||||
},
|
||||
"image": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@ -78,6 +91,7 @@ var schema = string(`
|
||||
"pid": { "type": "string"},
|
||||
"ipc": { "type": "string"},
|
||||
"uts": { "type": "string"},
|
||||
"userns": { "type": "string"},
|
||||
"readonly": { "type": "boolean"},
|
||||
"maskedPaths": { "$ref": "#/definitions/strings" },
|
||||
"readonlyPaths": { "$ref": "#/definitions/strings" },
|
||||
@ -97,7 +111,9 @@ var schema = string(`
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/definitions/strings" }
|
||||
},
|
||||
"rlimits": { "$ref": "#/definitions/strings" }
|
||||
"rlimits": { "$ref": "#/definitions/strings" },
|
||||
"uidMappings": { "$ref": "#/definitions/idmappings" },
|
||||
"gidMappings": { "$ref": "#/definitions/idmappings" }
|
||||
}
|
||||
},
|
||||
"images": {
|
||||
|
Loading…
Reference in New Issue
Block a user