-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Postgres fails to start when Kubernetes doesn't chown volume upon mount #1690
Comments
Here's what seems to be working for me. After installing kotsadm, wait for spec:
template:
spec:
securityContext:
# Run as root so we can create user to match NFS UID. We will drop permissions later on.
fsGroup: 0
runAsUser: 0
containers:
- name: kotsadm-postgres
command: ['/bin/bash']
args:
- '-x'
- '-c'
- |
# This should match mountPath of the container
mountpath=/var/lib/postgresql/data
# Path to file that tells us whether DB has already been initialized
kotsadm_initialized="$mountpath/kotsadm_initialized"
# Grab group ID and user ID of the mounted volume.
# Many storage implementations will generate these every time the volume is mounted.
gid="$(stat -c '%g' "$mountpath")"
uid="$(stat -c '%u' "$mountpath")"
# User to run postgres as. When restarting this pod, a pguser account may already exist.
pguser="pgdataowner$uid"
if ! id "$pguser" &> /dev/null; then
echo "Adding user $pguser as $uid:$gid"
groupadd --system --gid "$gid" "$pguser"
useradd --system --uid "$uid" -g "$pguser" --shell /usr/sbin/nologin "$pguser"
fi
if [ ! -e "$kotsadm_initialized" ]; then
# Delete half-initialized data from last time this container ran initdb.
# We want docker-entry-point.sh to rerun initdb with the correct owner.
rm -rf "$mountpath"/*
# Don't delete data next time this pod restarts.
touch "$kotsadm_initialized"
fi
# Run regular entrypoint as our custom user,
# with extra logging so that we can confirm it's initialized everything correctly
gosu "$pguser:$pguser" bash -x docker-entrypoint.sh postgres This effectively forces postgres to run as the UID that owns the mount directory. While chowning the mount directory to the postgres UID (999) would be simpler, that doesn't work on NFS shares that have root squashing enabled. Once the StatefulSet is patched, you'll then have to delete the existing After One last note, it looks like there may be plans to change the postgres container to alpine. That would probably require tweaking this patch. Although since we're already patching the StatefulSet, we can always substitute in whatever Docker image we want. |
Here's the relevant PG code that enforces the ownership check. It seems like there's no way to relax this in PG. |
FYI, #1695, which is included in v1.37.0+, breaks the above workaround since the alpine container doesn't include things like EDIT: more importantly, it's now using a read-only volume for /etc/passwd, so you can't add users |
If the Postgres data directory is not owned by the same user ID as the postgres process (currently
999
[1]),kotsadm-postgres-0
will crash with the following error:With persistent volumes backed my most block storage devices, Kubernetes will recursively call
chown
andchmod
on the mounted files and directories inside the volume, so the Postgres data directory will have the correct owner. But Kubernetes will not callchown
/chmod
for all volume types. The details are best summarized in this blog post:All this means that if you use something like NFS for your persistent volumes, Kubernetes won't [2] call
chown
when the volume is mounted. Thus, Postgres will fail to start.The traditional solution to this is to run
chown
on the relevant directories before Postgres starts, e.g. via an entrypoint or some other process pre-mounting the volume and runningchown
. But to do this, you'd have to be able to edit kotsadm's Postgres deployment, and kots doesn't really make it possible to edit its resources before installing. Instead, all you can do is patch the postgres deployment manually after kotsadm is installed.A better solution may be for kots to
chown
the Postgres data directory itself on startup.[1]
kots/pkg/kotsadm/objects/postgres_objects.go
Lines 29 to 30 in fe49146
[2] At some point, Kubernetes will stabilize the
fsGroupPolicy
interface and CSI drivers can opt in to this behavior explicitly. But even then, enabling that on the default storage class just so kotsadm's Postgres works probably isn't the best solution.The text was updated successfully, but these errors were encountered: