1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #10093 from crosbymichael/readonly-containers

Add --read-only for read only container rootfs
This commit is contained in:
Alexander Morozov 2015-01-14 15:56:51 -08:00
commit 95c0f07966
11 changed files with 62 additions and 1 deletions

View file

@ -294,6 +294,7 @@ func populateCommand(c *Container, env []string) error {
c.command = &execdriver.Command{ c.command = &execdriver.Command{
ID: c.ID, ID: c.ID,
Rootfs: c.RootfsPath(), Rootfs: c.RootfsPath(),
ReadonlyRootfs: c.hostConfig.ReadonlyRootfs,
InitPath: "/.dockerinit", InitPath: "/.dockerinit",
WorkingDir: c.Config.WorkingDir, WorkingDir: c.Config.WorkingDir,
Network: en, Network: en,

View file

@ -125,7 +125,8 @@ type ProcessConfig struct {
// Process wrapps an os/exec.Cmd to add more metadata // Process wrapps an os/exec.Cmd to add more metadata
type Command struct { type Command struct {
ID string `json:"id"` ID string `json:"id"`
Rootfs string `json:"rootfs"` // root fs of the container Rootfs string `json:"rootfs"` // root fs of the container
ReadonlyRootfs bool `json:"readonly_rootfs"`
InitPath string `json:"initpath"` // dockerinit InitPath string `json:"initpath"` // dockerinit
WorkingDir string `json:"working_dir"` WorkingDir string `json:"working_dir"`
ConfigPath string `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver ConfigPath string `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver

View file

@ -31,6 +31,7 @@ func (d *driver) createContainer(c *execdriver.Command) (*libcontainer.Config, e
container.Cgroups.AllowedDevices = c.AllowedDevices container.Cgroups.AllowedDevices = c.AllowedDevices
container.MountConfig.DeviceNodes = c.AutoCreatedDevices container.MountConfig.DeviceNodes = c.AutoCreatedDevices
container.RootFs = c.Rootfs container.RootFs = c.Rootfs
container.MountConfig.ReadonlyFs = c.ReadonlyRootfs
// check to see if we are running in ramdisk to disable pivot root // check to see if we are running in ramdisk to disable pivot root
container.MountConfig.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != "" container.MountConfig.NoPivotRoot = os.Getenv("DOCKER_RAMDISK") != ""

View file

@ -34,6 +34,7 @@ docker-create - Create a new container
[**-p**|**--publish**[=*[]*]] [**-p**|**--publish**[=*[]*]]
[**--pid**[=*[]*]] [**--pid**[=*[]*]]
[**--privileged**[=*false*]] [**--privileged**[=*false*]]
[**--read-only**[=*false*]]
[**--restart**[=*RESTART*]] [**--restart**[=*RESTART*]]
[**--security-opt**[=*[]*]] [**--security-opt**[=*[]*]]
[**-t**|**--tty**[=*false*]] [**-t**|**--tty**[=*false*]]
@ -140,6 +141,9 @@ IMAGE [COMMAND] [ARG...]
**--privileged**=*true*|*false* **--privileged**=*true*|*false*
Give extended privileges to this container. The default is *false*. Give extended privileges to this container. The default is *false*.
**--read-only**=*true*|*false*
Mount the container's root filesystem as read only.
**--restart**="" **--restart**=""
Restart policy to apply when a container exits (no, on-failure[:max-retry], always) Restart policy to apply when a container exits (no, on-failure[:max-retry], always)

View file

@ -35,6 +35,7 @@ docker-run - Run a command in a new container
[**-p**|**--publish**[=*[]*]] [**-p**|**--publish**[=*[]*]]
[**--pid**[=*[]*]] [**--pid**[=*[]*]]
[**--privileged**[=*false*]] [**--privileged**[=*false*]]
[**--read-only**[=*false*]]
[**--restart**[=*RESTART*]] [**--restart**[=*RESTART*]]
[**--rm**[=*false*]] [**--rm**[=*false*]]
[**--security-opt**[=*[]*]] [**--security-opt**[=*[]*]]
@ -253,6 +254,13 @@ to all devices on the host as well as set some configuration in AppArmor to
allow the container nearly all the same access to the host as processes running allow the container nearly all the same access to the host as processes running
outside of a container on the host. outside of a container on the host.
**--read-only**=*true*|*false*
Mount the container's root filesystem as read only.
By default a container will have its root filesystem writable allowing processes
to write files anywhere. By specifying the `--read-only` flag the container will have
its root filesystem mounted as read only prohibiting any writes.
**--restart**="" **--restart**=""
Restart policy to apply when a container exits (no, on-failure[:max-retry], always) Restart policy to apply when a container exits (no, on-failure[:max-retry], always)

View file

@ -61,6 +61,13 @@ This endpoint now returns the list current execs associated with the container (
**New!** **New!**
New endpoint to rename a container `id` to a new name. New endpoint to rename a container `id` to a new name.
`POST /containers/create`
`POST /containers/(id)/start`
**New!**
(`ReadonlyRootfs`) can be passed in the host config to mount the container's
root filesystem as read only.
## v1.16 ## v1.16
### Full Documentation ### Full Documentation

View file

@ -146,6 +146,7 @@ Create a container
"PortBindings": { "22/tcp": [{ "HostPort": "11022" }] }, "PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
"PublishAllPorts": false, "PublishAllPorts": false,
"Privileged": false, "Privileged": false,
"ReadonlyRootfs": false,
"Dns": ["8.8.8.8"], "Dns": ["8.8.8.8"],
"DnsSearch": [""], "DnsSearch": [""],
"VolumesFrom": ["parent", "other:ro"], "VolumesFrom": ["parent", "other:ro"],
@ -218,6 +219,8 @@ Json Parameters:
exposed ports. Specified as a boolean value. exposed ports. Specified as a boolean value.
- **Privileged** - Gives the container full access to the host. Specified as - **Privileged** - Gives the container full access to the host. Specified as
a boolean value. a boolean value.
- **ReadonlyRootfs** - Mount the container's root filesystem as read only.
Specified as a boolean value.
- **Dns** - A list of dns servers for the container to use. - **Dns** - A list of dns servers for the container to use.
- **DnsSearch** - A list of DNS search domains - **DnsSearch** - A list of DNS search domains
- **VolumesFrom** - A list of volumes to inherit from another container. - **VolumesFrom** - A list of volumes to inherit from another container.
@ -323,6 +326,7 @@ Return low-level information on the container `id`
"NetworkMode": "bridge", "NetworkMode": "bridge",
"PortBindings": {}, "PortBindings": {},
"Privileged": false, "Privileged": false,
"ReadonlyRootfs": false,
"PublishAllPorts": false, "PublishAllPorts": false,
"RestartPolicy": { "RestartPolicy": {
"MaximumRetryCount": 2, "MaximumRetryCount": 2,

View file

@ -755,6 +755,7 @@ Creates a new container.
When specifying ranges for both, the number of container ports in the range must match the number of host ports in the range. (e.g., `-p 1234-1236:1234-1236/tcp`) When specifying ranges for both, the number of container ports in the range must match the number of host ports in the range. (e.g., `-p 1234-1236:1234-1236/tcp`)
(use 'docker port' to see the actual mapping) (use 'docker port' to see the actual mapping)
--privileged=false Give extended privileges to this container --privileged=false Give extended privileges to this container
--read-only=false Mount the container's root filesystem as read only
--restart="" Restart policy to apply when a container exits (no, on-failure[:max-retry], always) --restart="" Restart policy to apply when a container exits (no, on-failure[:max-retry], always)
--security-opt=[] Security Options --security-opt=[] Security Options
-t, --tty=false Allocate a pseudo-TTY -t, --tty=false Allocate a pseudo-TTY
@ -1608,6 +1609,7 @@ removed before the image is removed.
(use 'docker port' to see the actual mapping) (use 'docker port' to see the actual mapping)
--pid=host 'host': use the host PID namespace inside the container. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure. --pid=host 'host': use the host PID namespace inside the container. Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure.
--privileged=false Give extended privileges to this container --privileged=false Give extended privileges to this container
--read-only=false Mount the container's root filesystem as read only
--restart="" Restart policy to apply when a container exits (no, on-failure[:max-retry], always) --restart="" Restart policy to apply when a container exits (no, on-failure[:max-retry], always)
--rm=false Automatically remove the container when it exits (incompatible with -d) --rm=false Automatically remove the container when it exits (incompatible with -d)
--security-opt=[] Security Options --security-opt=[] Security Options
@ -1683,6 +1685,13 @@ will automatically create this directory on the host for you. In the
example above, Docker will create the `/doesnt/exist` example above, Docker will create the `/doesnt/exist`
folder before starting your container. folder before starting your container.
$ sudo docker run --read-only -v /icanwrite busybox touch /icanwrite here
Volumes can be used in combination with `--read-only` to control where
a container writes files. The `--read only` flag mounts the container's root
filesystem as read only prohibiting writes to locations other than the
specified volumes for the container.
$ sudo docker run -t -i -v /var/run/docker.sock:/var/run/docker.sock -v ./static-docker:/usr/bin/docker busybox sh $ sudo docker run -t -i -v /var/run/docker.sock:/var/run/docker.sock -v ./static-docker:/usr/bin/docker busybox sh
By bind-mounting the docker unix socket and statically linked docker By bind-mounting the docker unix socket and statically linked docker

View file

@ -3036,3 +3036,25 @@ func TestRunRestartMaxRetries(t *testing.T) {
} }
logDone("run - test max-retries for --restart") logDone("run - test max-retries for --restart")
} }
func TestRunContainerWithWritableRootfs(t *testing.T) {
defer deleteAllContainers()
out, err := exec.Command(dockerBinary, "run", "--rm", "busybox", "touch", "/file").CombinedOutput()
if err != nil {
t.Fatal(string(out), err)
}
logDone("run - writable rootfs")
}
func TestRunContainerWithReadonlyRootfs(t *testing.T) {
defer deleteAllContainers()
out, err := exec.Command(dockerBinary, "run", "--read-only", "--rm", "busybox", "touch", "/file").CombinedOutput()
if err == nil {
t.Fatal("expected container to error on run with read only error")
}
expected := "Read-only file system"
if !strings.Contains(string(out), expected) {
t.Fatalf("expected output from failure to contain %s but contains %s", expected, out)
}
logDone("run - read only rootfs")
}

View file

@ -118,6 +118,7 @@ type HostConfig struct {
CapDrop []string CapDrop []string
RestartPolicy RestartPolicy RestartPolicy RestartPolicy
SecurityOpt []string SecurityOpt []string
ReadonlyRootfs bool
} }
// This is used by the create command when you want to set both the // This is used by the create command when you want to set both the
@ -148,6 +149,7 @@ func ContainerHostConfigFromJob(job *engine.Job) *HostConfig {
NetworkMode: NetworkMode(job.Getenv("NetworkMode")), NetworkMode: NetworkMode(job.Getenv("NetworkMode")),
IpcMode: IpcMode(job.Getenv("IpcMode")), IpcMode: IpcMode(job.Getenv("IpcMode")),
PidMode: PidMode(job.Getenv("PidMode")), PidMode: PidMode(job.Getenv("PidMode")),
ReadonlyRootfs: job.GetenvBool("ReadonlyRootfs"),
} }
job.GetenvJson("LxcConf", &hostConfig.LxcConf) job.GetenvJson("LxcConf", &hostConfig.LxcConf)

View file

@ -63,6 +63,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
flMacAddress = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)") flMacAddress = cmd.String([]string{"-mac-address"}, "", "Container MAC address (e.g. 92:d0:c6:0a:29:33)")
flIpcMode = cmd.String([]string{"-ipc"}, "", "Default is to create a private IPC namespace (POSIX SysV IPC) for the container\n'container:<name|id>': reuses another container shared memory, semaphores and message queues\n'host': use the host shared memory,semaphores and message queues inside the container. Note: the host mode gives the container full access to local shared memory and is therefore considered insecure.") flIpcMode = cmd.String([]string{"-ipc"}, "", "Default is to create a private IPC namespace (POSIX SysV IPC) for the container\n'container:<name|id>': reuses another container shared memory, semaphores and message queues\n'host': use the host shared memory,semaphores and message queues inside the container. Note: the host mode gives the container full access to local shared memory and is therefore considered insecure.")
flRestartPolicy = cmd.String([]string{"-restart"}, "", "Restart policy to apply when a container exits (no, on-failure[:max-retry], always)") flRestartPolicy = cmd.String([]string{"-restart"}, "", "Restart policy to apply when a container exits (no, on-failure[:max-retry], always)")
flReadonlyRootfs = cmd.Bool([]string{"-read-only"}, false, "Mount the container's root filesystem as read only")
) )
cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to STDIN, STDOUT or STDERR.") cmd.Var(&flAttach, []string{"a", "-attach"}, "Attach to STDIN, STDOUT or STDERR.")
@ -312,6 +313,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
CapDrop: flCapDrop.GetAll(), CapDrop: flCapDrop.GetAll(),
RestartPolicy: restartPolicy, RestartPolicy: restartPolicy,
SecurityOpt: flSecurityOpt.GetAll(), SecurityOpt: flSecurityOpt.GetAll(),
ReadonlyRootfs: *flReadonlyRootfs,
} }
// When allocating stdin in attached mode, close stdin at client disconnect // When allocating stdin in attached mode, close stdin at client disconnect