Azure / azurefile-dockervolumedriver

Docker Volume Driver for Azure File Service over SMB/CIFS :whale:
Apache License 2.0
169 stars 57 forks source link

Containers "chown"ing files in Azure File Storage #65

Closed williamayerst closed 6 years ago

williamayerst commented 8 years ago

The Postgresql container (https://hub.docker.com/_/postgres/) runs a script on start which attempts to own its data folder, and this fails:

The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "en_US.utf8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are disabled.

initdb: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted
fixing permissions on existing directory /var/lib/postgresql/data ...

I am mounting the Azure file storage location to /var/lib/postgresql/data as below:

services:
  db:
    ...
    volumes:
      - postgresql:/var/lib/postgresql/data
    ...
volumes:
  postgresql:
    driver: azurefile
    driver_opts:
      share: "postgresql"

I have tried creating a remotepath "data" and it makes no difference. I take it this is because the storage driver can't interpret that call, is there a workaround?

williamayerst commented 8 years ago

I could not find a workaround for this, even specifying pgdata=/var/lib/postgresql/data/A-SUBFOLDER/ in the docker image options fails with the same permissionning error. It would make sense to create my own dockerfile which avoids this somehow, but in the meantime I have migrated my data to MySQL and it's working fine with no further changes.

ahmetb commented 8 years ago

@williamayerst First I can suggest having a postgres user in the container (see the USER directive in Dockerfiles). Then you can use uid volume option that this driver supports. But I believe that uid will refer to a uid on host; not inside the container. For that, I suggest you to check out docker run --user argument or user namespaces (--userns argument).

I have not done it myself but this volume driver lets you configure uid/gid for the Azure File Storage mounts. Please refer to README for the full set of options. If that answers your question, please consider closing the issue.

williamayerst commented 8 years ago

@ahmetalpbalkan The container already does run postgresql as a user called postgresql - I will check the namespace thing though.

It's worth mentioning that this only occurs using the volume driver, it is able to chown the folder successfully if I am using local storage on the container host.

ahmetb commented 8 years ago

@williamayerst This volume driver is not doing any magic. Under the covers it runs a mount command on the host (described here) with uid and gid arguments to and hands the mount path to the Docker Engine.

The passed uid and gid arguments correspond to users/groups on the host. What I can suggest is, try running the mount command yourself and see if you can mount that path into a container that you manually run. Than try to create users in the container (e.g. useradd) then try to chmod files in the mounted volume.

I am guessing SMB protocol does not allow you do chmod/chown. This is why you're getting the Operation not permitted error.

I am not sure what to do in this context as I have not played with multi-user containers myself, but I can tell the uid/gid mount options this plugin offers you will be the part of the solution. If you can find a way to associate users on the host to users inside the container, that might let you manage the files.

Alternatively, can you try - postgresql:/var/lib/postgresql/ (do not include /data)? Maybe this'll work.

spiderhc commented 7 years ago

@ahmetalpbalkan About your commentary:

I am guessing SMB protocol does not allow you do chmod/chown. This is why you're getting the Operation not permitted error.

I have the same problem here, seems this error happens in this line in docker postgres image: https://github.com/docker-library/postgres/blob/a00e979002aaa80840d58a5f8cc541342e06788f/docker-entrypoint.sh#L32

As this command is not successful, the database is not written to directory.

I tried with uid/ gid, like for instance:

But the problem persists.

Do you know a workaround for this?

markojak commented 7 years ago

Hi All, planning on using Azure Storage as a persistent data volume and since we depend on postgresql in the stack this is worrying.

Has anyone found a workaround as yet for the permissions issue?

It seems that Postgresql image tries to create the data directory with 998:998

spiderhc commented 7 years ago

@marchofreason I still with this problem, if you find the solution, please let me know.

saikatguha commented 7 years ago

I got postgres to work on docker+azurefile. It's not pretty, but it's a start. Would appreciate improvements.

  1. uid/gid/mode issue: postgres does need the correct owner and mode. azurefile already provides the needed options. Create the volume using -o uid=999,gid=999,filemode=0600,dirmode=0700

  2. chown/chmod issue: this problem is with initdb only. postgres itself doesn't care. I modified docker-entrypoint.sh near line 18 to run initdb outside the volume, and mv the data back in.

    rm -rf /tmp/init 
    mkdir -p /tmp/init && chmod 700 /tmp/init && chown -R postgres /tmp/init
    eval "gosu postgres initdb -D /tmp/init $POSTGRES_INITDB_ARGS"
    mv /tmp/init/* $PGDATA/
  3. fsync issue: fsync is enabled by default, and results in fatal error since azurefile/cifs doesn't support it. Disable fsync by passing -o "-c fsync=off -c full_page_writes=off" to pg_ctl (around line 51), and again -c fsync=off -c full_page_writes=off to postgres around line 94.

That's it! postgres should now be working on azurefile in docker.

The ugly: With fsync off, postgres will not be able to recover from sudden crashes. see runtime-config-wal for a discussion on fsync issues. Additionally, write ordering and caching issues in cifs may result in silent data-corruption. see pgsql-general.

Thoughts on how to address or mitigate?

fvilers commented 7 years ago

Same issue with mysql:5.7. The script that chowns (and files) seems to be fixed in mysql:5.7.16, maybe you can investigate what the maintainer changed in the image and do the same for postgres.

ziXet commented 6 years ago

Same issue here. Any progress? Can SMB protocol handle this situation at all? I mean changing the owner of the directories for each client?

nieldw commented 6 years ago

Same issue with Artifactory-OSS

msftgits commented 6 years ago

This driver is no longer supported and will not be maintained moving forward. We recommend users use CloudStor for Docker native solutions.

Thanks for your contribution, but to reduce confusion, we are closing issues, pull requests, and marking the repo as 'Archive' for the time being.