How can I fix the permissions using docker on a bl

2019-02-22 10:03发布

问题:

In a container, I am trying to start mysqld.

I was able to create an image and push to the registry but when I want to start it, the /var/lib/mysql volume can't be initialized as I try to do a chown mysql on it and it is not allowed.

I checked docker specific solutions but for now I couldn't make any work.

Is there a way to set the right permissions on a bind-mounted folder from bluemix? Or is the option --volumes-from supported, I can't seem to make it work.

The only solution I can see right now is running mysqld as root, but I would rather not.

Try with mount-bind

  1. created a volume on bluemix using cf ic volume create database
  2. try to run mysql_install_db on my db container to initialize it's content

    docker run --name init_vol -v database:/var/lib/mysql registry.ng.bluemix.net/<namespace>/<image>:<tag> mysql_install_db --user=mysql
    

mysql_install_db is supposed to populate the /var/lib/mysql and set the rights to the owner set in the --user option, but I get:

chown: changing ownership of '/var/lib/mysql': Permission denied.

I also tried the above in different ways, using sudo or a script. I tried with mysql_install_db --user=root, which does setup my folder correctly, except it is owned by the root user, and I would rather keep mysql running as the mysql user.

Try with volumes-from data container

  1. I create a data container with a volume /var/lib/mysql

    docker run --name db_data -v /var/lib/mysql registry.ng.bluemix.net/<namespace>/<image>:<tag> mysql_install_db --user=mysql
    
  2. I run my db container with the option --volumes-from

    docker run --name db_srv --volumes-from=db_data registry.ng.bluemix.net/<namespace>/<image>:<tag> sh -c 'mysqld_safe & tail -f /var/log/mysql.err'
    

docker inspect db_srv shows:

[{ "BluemixApp": null, "Config": { ..., "WorkingDir": "", ... } ... }]

cf ic logs db_srv shows:

150731 15:25:11 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql 150731 15:25:11 [Note] /usr/sbin/mysqld (mysqld 5.5.44-0ubuntu0.14.04.1-log) starting as process 377 .. /usr/sbin/mysqld: File './mysql-bin.index' not found (Errcode: 13) 150731 15:25:11 [ERROR] Aborting

which is due to --volumes-from not being supported, and to data created in the first not staying in the second run.

回答1:

In IBM Containers, the user namespace is enabled for docker engine. The "Permission denied " issue appears to be because the NFS is not allowing mapped user, from container, to perform the operation.

On my local setup, on the docker host, mounted a NFS (exported with no_root_squash option). and attached the volume to container using -v option. When the container is spawned from docker with disabled user namespace, I am able to change the ownership for bind-mount inside the container. But With user namespace enabled docker, I am getting chown: changing ownership of ‘/mnt/volmnt’: Operation not permitted

The volume created by cf (cf ic volume create ...) is a NFS, to verify just try mount -t nfs4 from container. When, the user namespace is enabled for docker engine. The effective root inside the container is a non-root user out side the container process and NFS is not allowing the mapped non-root user to perform the chown operation on the volume inside the container.

Here is the work-around, you may want to try

  1. In the Dockerfile

    1.1 Create user mysql with UID 1010, or any free ID, before MySql installation. Other Container or new Container can access mysql data files on Volume with UID 1010

    RUN groupadd --gid 1010 mysql

    RUN useradd --uid 1010 --gid 1010 -m --shell /bin/bash mysql

    1.2 Install MySqlL but do not initialize database

    RUN apt-get update && apt-get install -y mysql-server && rm -rf /var/lib/mysql && rm -rf /var/lib/apt/lists/*

  2. In the entry point script

    2.1 Create mysql Data directory under bind-mount as user mysql and then link it as /var/lib/mysql

    Suppose the volume is mounted at /mnt/db inside the container (ice run -v <volume name>:/mnt/db --publish 3306... or cf ic run --volume <volume name>:/mnt/db ...). Define mountpath env var

    MOUNTPATH="/mnt/db"

    Add mysql to group "root"

    adduser mysql root

    Set permission for mounted volume so that root group members can create directory and files

    chmod 775 $MOUNTPATH

    Create mysql directory under Volume

    su -c "mkdir -p /mnt/db/mysql" mysql

    su -c "chmod 700 /mnt/db/mysql" mysql

    Link the directory to /var/lib/mysql

    ln -sf /mnt/db/mysql /var/lib/mysql

    chown -h mysql:mysql /var/lib/mysql

    Remove mysql from group root

    deluser mysql root

    chmod 755 $MOUNTPATH

    2.2 For first time, initialize database as user mysql

    su -c "mysql_install_db --datadir=/var/lib/mysql" mysql

    2.3 Start the mysql server as user mysql

    su -c "/usr/bin/mysqld_safe" mysql



回答2:

You have multiple questions here. I will try to address some. Perhaps that will get you a step further in the right direction.

--volumes-from is not supported yet in IBM Containers. You can get around that by using the same --volume (-v) option on the first and subsequent containers, instead of using -v on the first container creation command and --volumes-from on the subsequent ones.

--user option is not supported also by IBM Containers.

I see your syntax for using --user (I suppose on localhost docker) is not correct. All options for the docker run command must come before the image name. Anything after the image name is considered a command to run inside the container. In this case "--user=mysql" will be considered as a command that the system will attempt to run and fail.

The last error message you shared shows that there is some file not found in the working dir which causes the app to abort. You may work around that by using a script as the command to run in the container which changes dir to the right location.