Why the File It Wrote Is Owned by Root
Last timeLayers, and Why the Build Is Slow
The identity a container runs as is a number, the number means different things on the two sides of the boundary, and a permission error on a mounted directory is arithmetic over two of them.
The symptom is the same every time. A directory on the host is mounted into the
container, the directory is plainly writable, and the service inside reports
that permission was denied. Setting the mode to 0777 makes the message go away,
which is why that is the most common repair and why it is the wrong one. It did
not fix an arithmetic error. It granted write access on that directory to every
process on the host.
The arithmetic is worth doing instead, because there is not much of it. The
whole mechanism is two numbers, a set of further numbers, and nine bits.
The host directory is the one lesson three mounted: /var/lib/service-data on the
host, appearing as /srv/data inside. It is owned by the user who runs the
service, numbered 1000, in the group numbered 1000, with mode 0755. The image
declares that the service runs as the user numbered 10001, in the group numbered
10001, which is the sensible modern default and is where the trouble starts.
The identity is a number
What the kernel holds for a running process is not a user. It is a real user
number and an effective user number, the same pair for groups, and a set of
supplementary group numbers. Every one of those is an integer. The effective
user number is the one almost all permission checks consult, and it is the one
meant below wherever a single number is named.
The names are not in there. When a program prints that it is running as root, it
took the number 0 and looked it up in a text file, and that file is reached
through this process's own root directory, which lesson three replaced. So the
name beside the number is supplied by whichever view is doing the looking. The
image's own file calls 0 root. It almost certainly has no entry at all for
10001, which is why a shell inside such a container announces that it has no
name, and that announcement is not a fault. It is a lookup that failed in a file
that was never going to contain the answer.
The same number means two things
With no mapping in place the number crosses unchanged, and that is not a
simplification. The number 0 inside is the number 0 outside. So a container
running as 0, which is still the default for a great many images, is the host's
root as far as that mounted directory is concerned, and the write succeeds for
the plainest possible reason.
The lesson stops here
6 more paragraphs to go
You have read the opening. The rest of the argument, the problems that check whether it landed, and the lines worth keeping at the end all come with a plan.
The first lesson of every course in the library reads the whole way through, free, so you can see exactly what the rest of them are.
See the planThe contentsThis is the reading half
Starting the course gives you your own copy of it. Every idea on every page has problems standing under it, marked with a reason rather than a tick, and any sentence you do not believe can be opened and argued with. None of that can happen on a page nobody owns.
The contents