difference between cgroups and namespaces
The proper links for those two notions have been fixed in PR 14307:
Under the hood, Docker is built on the following components:
The cgroups and
namespaces
capabilities of the Linux kernel
With:
- cgroup: Control Groups provide a mechanism for aggregating/partitioning sets of tasks, and all their future children, into hierarchical groups with specialized behaviour.
- namespace: wraps a global system resource in an abstraction that makes it appear to the processes within the namespace that they have their own isolated instance of the global resource.
In short:
- Cgroups = limits how much you can use;
- namespaces = limits what you can see (and therefore use)
See more at "Anatomy of a Container: Namespaces, cgroups & Some Filesystem Magic" by Jérôme Petazzoni.
Cgroups involve resource metering and limiting:
- memory
- CPU
- block I/O
- network
Namespaces provide processes with their own view of the system
Multiple namespaces:
- pid
- net
- mnt
- uts
- ipc
- user: userns it is graduating from experimental in docker 1.10
(per-daemon-instance remapping of container root to an unprivileged user is in progress: PR 12648: see its design)
Docker(containers) cgroup/namespace setup vs running Dockerfile commands as root?
A container can only access the host filesystem if the operator explicitly gives it access. For example, try without any docker run -v
options:
docker run \
--rm \ # clean up the container when done
-u root \ # explicitly request root user
busybox \ # image to run
cat /etc/shadow # dumps the _container's_ password file
More generally, the rule (on native Linux without user namespace remapping) is that, if files are bind-mounted from the host into a container, they are accessible if the container's numeric user or group IDs match the file's ownership and permissions. If a file is owned by uid 1000 on the host with mode 0600, it can be read by uids 0 or 1000 in the container, regardless of the corresponding container and host users' names.
The corollary to this is that anyone who can run any docker run
command at all can pretty trivially root the entire host.
docker run \
--rm \
-u root \
-v /:/host \ # bind-mount the host filesystem into the container
busybox \
cat /host/etc/shadow # dumps the host's encrypted password file
The root user in a container is further limited by Linux capabilities: without giving special additional Docker options, even running as root, a container can't change filesystem mounts, modify the network configuration, load kernel modules, reboot the host, or do several other extra-privileged things. (And it's usually better to do these things outside a container than to give extra permission to Docker; don't casually run containers --privileged
.)
It's still generally better practice to run containers as non-root users. The user ID doesn't need to match any user ID in particular, it just needs to not be 0 (matching a specific host uid isn't portable across hosts and isn't recommended). The files in the container generally should be owned by root, so they can't be accidentally overwritten.
FROM debian
# Create the non-root user
RUN adduser --system --no-create-home nonroot
# Do the normal installation, as root
COPY ... # no --chown option
RUN ... # does not run chown either
# Specify the non-root user only for the final container
EXPOSE 12345
USER nonroot
CMD the main container command
If the container does need to read or (especially) write host files, bind-mount the host directory into some data-specific directory in the container (do not overwrite the application code with this mount) and use the docker run -u
option to specify the host uid that the container needs to run as. The user does not specifically need to exist in the container's /etc/passwd
file.
docker run \
-v "$PWD:/app/data" \ # bind-mount the current directory as data
-u $(id -u) \ # specify the user ID to use
...
Related Topics
Bash Variable Assignment Not Working Expected
How to Force a Cifs Connection to Unmount
How to Shield a CPU from the Linux Scheduler (Prevent It Scheduling Threads Onto That Cpu)
Linux: Which Process Is Causing "Device Busy" When Doing Umount
Does Linux Kill Background Processes If We Close the Terminal from Which It Has Started
How to Fetch Java Version Using Single Line Command in Linux
How to Check That Two Folders Are the Same in Linux
Mongodb Service Will Not Start After Initial Setup
Creating an Installer for Linux Application
I Want to Remove Multiple Line of Text on Linux
Difference Between Cgroups and Namespaces
How to Create a Directory and Give Permission in Single Command
Linux: Merging Multiple Files, Each on a New Line
How to Pipe Output from Grep to Cp