diff --git a/docs/src/building/users-and-groups.md b/docs/src/building/users-and-groups.md index 6f05f40b..deb1c51c 100644 --- a/docs/src/building/users-and-groups.md +++ b/docs/src/building/users-and-groups.md @@ -55,31 +55,45 @@ credentials from a [CRD](https://kubernetes.io/docs/tasks/extend-kubernetes/cust hosted in the API server. (To do things like this it's suggested to reuse the kubelet credentials) -### Adding users and credentials statically in the container build +### System users and groups (added via packages, etc) -Relative to package-oriented systems, a new ability is to inject -users and credentials as part of a derived build: +It is common for packages (deb/rpm/etc) to allocate system users +or groups as part of e.g `apt|dnf install ` such as Apache or MySQL, +and this is often done by directly invoking `useradd` or `groupadd` as part +of package pre/post installation scripts. -```dockerfile -RUN useradd someuser -``` +With the`shadow-utils` implementation of `useradd` and the default glibc `files` this will +result in changes to the traditional `/etc/passwd` and `/etc/shadow` files +as part of the container build. -However, it is important to understand some two very important issues -with this as it exists today (the `shadow-utils` implementation of `useradd`) -and the default glibc `files` backend for the traditional `/etc/passwd` -and `/etc/shadow` files. +#### System drift from local /etc/passwd modifications -It is common for user/group IDs are allocated dynamically, and this can result in "drift" (see below). +When the system is initially installed, the `/etc/passwd` in the container image will be +applied and contain desired users. -Further, if `/etc/passwd` is modified locally (because there is a machine-local user), -then any added users injected via `useradd` *will not appear* on subsequent updates by default (they will be +By default (without `etc = transient`, see below), the `/etc` directory is machine-local +persistent state. If subsequently `/etc/passwd` is modified local to the machine +(as is common for e.g. setting a root password) then any new changes in the container +image (such as users from new packages) *will not appear* on subsequent updates by default (they will be in `/usr/etc/passwd` instead - the default image version). -These "system users" that may be created by packaging tools invoking `useradd` (e.g. `apt|dnf install httpd`) that do -not also install a `sysusers.d` file. Currently for example, this is the case with -the CentOS Stream 9 `httpd` package. Per below, the general solution to this -is to avoid invoking `useradd` in container builds, and prefer one of the below -solutions. +The general best fix for this is to use `systemd-sysusers` instead of allocating +a user/group at build time at all. + +##### Using systemd-sysusers + +See [systemd-sysusers](https://www.freedesktop.org/software/systemd/man/latest/systemd-sysusers.html). +For example in your derived build: + +``` +COPY mycustom-user.conf /usr/lib/sysusers.d +``` + +A key aspect of how this works is that `sysusers` will make changes +to the traditional `/etc/passwd` file as necessary on boot instead +of at build time. If `/etc` is persistent, this can avoid uid/gid drift (but +in the general case it does mean that uid/gid allocation can +depend on how a specific machine was upgraded over time). #### User and group home directories and `/var` @@ -96,20 +110,6 @@ This is significantly better than the pattern of allocating users/groups at "package install time" (e.g. [Fedora package user/group guidelines](https://docs.fedoraproject.org/en-US/packaging-guidelines/UsersAndGroups/)) because it avoids potential UID/GID drift (see below). -#### Using systemd-sysusers - -See [systemd-sysusers](https://www.freedesktop.org/software/systemd/man/latest/systemd-sysusers.html). For example in your derived build: - -``` -COPY mycustom-user.conf /usr/lib/sysusers.d -``` - -A key aspect of how this works is that `sysusers` will make changes -to the traditional `/etc/passwd` file as necessary on boot. If -`/etc` is persistent, this can avoid uid/gid drift (but -in the general case it does mean that uid/gid allocation can -depend on how a specific machine was upgraded over time). - #### Using systemd JSON user records See [JSON user records](https://systemd.io/USER_RECORD/). Unlike `sysusers`, @@ -193,6 +193,23 @@ them; this is the pattern used by cloud-init and [afterburn](https://github.com/ ### UID/GID drift +Any invocation of `useradd` or `groupadd` that does not allocate a *fixed* UID/GID may +be subject to "drift" in subsequent rebuilds by default. + +One possibility is to explicitly force these user/group allocations into a static +state, via `systemd-sysusers` (per above) or explicitly adding the users with +static IDs *before* a dpkg/RPM installation script operates on it: + +``` +RUN <