Descripción de la propiedad de los archivos de usuario en docker: cómo evitar cambiar los permisos de los volúmenes vinculados


Considere el siguiente archivo Dockerfile trivial:

FROM debian:testing
RUN  adduser --disabled-password --gecos '' docker
RUN  adduser --disabled-password --gecos '' bob 

En un directorio de trabajo sin nada más. Construir la imagen de docker:

docker build -t test .

Y luego ejecute un script bash en el contenedor, vinculando el directorio de trabajo a un nuevo sub-directorio en el directorio home de bob:

docker run --rm -it -v $(pwd):/home/bob/subdir test 

¿A quién pertenece el contenido de subdir en el contenedor? En el contenedor, ejecute:

cd /home/bob/subdir
ls -l

Ad vemos: {[21]]}

-rw-rw-r-- 1 docker docker 120 Oct 22 03:47 Dockerfile

Santo cielo! docker posee el contenido! De vuelta en la máquina host fuera de la contenedor, vemos que nuestro usuario original todavía posee el Dockerfile. Vamos a intentar arreglar la propiedad del directorio home de bob. En el contenedor, ejecute:

chown -R bob:bob /home/bob
ls -l 

Y vemos:

-rw-rw-r-- 1 bob bob 120 Oct 22 03:47 Dockerfile

Pero espera! fuera del contenedor, ahora ejecutamos ls -l

-rw-rw-r-- 1 1001 1001 120 Oct 21 20:47 Dockerfile

Ya no tenemos nuestro propio archivo. Terrible noticia!


Si solo hubiéramos agregado un usuario en el ejemplo anterior, todo habría ido mejor. Por alguna razón, Docker parece estar haciendo cualquier directorio personal propiedad del first usuario no root que encuentra (incluso si ese usuario es declarado en una imagen anterior). Del mismo modo, este primer usuario es el que corresponde a los mismos permisos de propiedad que el usuario de mi hogar.

Pregunta 1 ¿Es eso correcto? ¿Puede alguien señalarme a la documentación de esto, sólo estoy conjeturando basado en el experimento anterior.

Pregunta 2 : Tal vez esto es solo porque ambos tienen el mismo valor numérico en el kernel, y si probaba en un sistema donde mi usuario doméstico no era id 1000 entonces los permisos se cambiarían en todos los casos?

Pregunta 3: La verdadera pregunta es, por supuesto, '¿qué hago al respecto?'Si bob está conectado como bob en la máquina host dada, debería poder ejecutar el contenedor como bob y no tener permisos de archivo alterados bajo su cuenta host. Tal como está, en realidad necesita ejecutar el contenedor como usuario docker para evitar que su cuenta sea alterada.

Te oigo preguntar ¿Por qué tengo un archivo Dockerfile tan raro de todos modos?. A veces también me lo pregunto. Estoy escribiendo un contenedor para una aplicación web (RStudio-server) que permite a diferentes usuarios iniciar sesión, que simplemente utiliza los nombres de usuario y las credenciales de la máquina linux como los nombres de usuario válidos. Esto me trae la motivación quizás inusual de querer crear múltiples usuarios. Puedo evitar esto creando el usuario solo en tiempo de ejecución y todo está bien. Sin embargo, yo uso una base imagen que ha agregado un único usuario docker para que pueda usarse interactivamente sin ejecutarse como root (según las mejores prácticas). Esto arruina todo, ya que ese usuario se convierte en el primer usuario y termina poseyendo todo, por lo que los intentos de iniciar sesión como otros usuarios fallan (la aplicación no se puede iniciar porque carece de permisos de escritura). Hacer que el script de inicio se ejecute chown primero resuelve este problema, pero a costa de que los volúmenes vinculados cambien los permisos (obviamente, solo es un problema si estamos enlazando volumen).

Author: Jarrod Weaver, 2014-10-22

2 answers

¿Es eso correcto? ¿Puede alguien señalarme a la documentación de esto, sólo estoy conjeturando basado en el experimento anterior.

Tal vez esto es solo porque ambos tienen el mismo valor numérico en el núcleo, y si probé en un sistema donde mi usuario doméstico no era id 1000, entonces los permisos cambiarían en todos los casos.

Tenga una lectura de info coreutils 'chown invocation', que podría darle una mejor idea de cómo funcionan los permisos / propiedad de archivos.

Básicamente, sin embargo, cada archivo en su máquina tiene un conjunto de bits añadidos que definen sus permisos y propiedad. Cuando chown un archivo, solo está configurando estos bits.

Cuando chown un archivo para un usuario/grupo en particular usando el nombre de usuario o el nombre de grupo, chown buscará en /etc/passwd el nombre de usuario y /etc/group para que el grupo intente asignar el nombre a un ID. Si el nombre de usuario / grupo no existe en esos archivos, chown fallará.

root@dc3070f25a13:/test# touch test
root@dc3070f25a13:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 root root    0 Oct 22 18:15 test
root@dc3070f25a13:/test# chown test:test test
chown: invalid user: 'test:test'

Sin embargo, puede chown un archivo usando IDs para lo que quiera (dentro de algunos límites superiores de enteros positivos, por supuesto), si hay un usuario / grupo que existe con esos ID en su máquina o no.

root@dc3070f25a13:/test# chown 5000:5000 test
root@dc3070f25a13:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 5000 5000    0 Oct 22 18:15 test

Los bits UID y GID se establecen en el propio archivo, por lo que cuando monte esos archivos dentro de su contenedor docker, el archivo tiene el mismo UID propietario / grupo que en el host, pero ahora se asigna a /etc/passwd en el contenedor, que probablemente será un usuario diferente a menos que sea propiedad de root (UID 0).

La verdadera pregunta es, por supuesto, '¿qué hago al respecto?'Si bob está conectado como bob en la máquina host dada, debería poder ejecutar el contenedor como bob y no tener permisos de archivo alterados bajo su cuenta host. Tal como está, en realidad necesita ejecutar el contenedor como docker de usuario para evitar que su cuenta sea alterada.

Parece que, con su configuración actual, deberá asegurarse de que sus UIDs > nombres de usuario en {[6] } en su host coincidan con sus UIDs > nombres de usuario en sus contenedores /etc/passwd si desea interactuar con su directorio de usuario montado como el mismo usuario que ha iniciado sesión en el host.

Puede crear un usuario con un id de usuario específico con useradd -u xxxx. Buuuut, eso parece una solución desordenada...

Es posible que tenga que idear una solución que no monte un directorio principal de usuarios host.

 23
Author: Chris McKinnel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-22 21:03:07

He encontrado dos opciones:

CHOWN todas las cosas (después de hacer su trabajo)

He hecho docker run -v `pwd`/shared:/shared image, y el contenedor ha creado archivos dentro de pwd/shared que son como propiedad del proceso docker. Sin embargo, /shared todavía me pertenece. Así que dentro del proceso docker, lo hago

chown -R `stat -c "%u:%g" /shared` /shared

stat -c "%u:%g" /shared devuelve 1000:1000 en mi caso, siendo el uid:gid de mi usuario. A pesar de que no hay ningún usuario 1000 dentro del docker conatainer, el id está allí (y stat /shared solo dice "desconocido" si pregunta para el nombre de usuario).

De todos modos, chown cede obedientemente la propiedad del contenido de /shared a 1000:1000 (que, en lo que a él respecta, no existe, pero fuera del contenedor, soy yo). Así que ahora soy el dueño de todos los archivos. El contenedor todavía puede modificar cosas si quiere, porque desde su perspectiva, es root.

Y todo está bien con el mundo.

docker run -u así que todos los archivos creados tendrán automáticamente el propietario de los derechos

Otra forma de hacer esto es la -u marca en docker run.

docker run -v `pwd`/shared:/shared -u `stat -c "%u:%g" /shared` ubuntu bash

De esta manera, el usuario de docker dentro del contenedor es youruid:yourgid.

Sin embargo: esto significa renunciar a su autoridad raíz dentro del contenedor (apt-get install, etc.). A menos que cree un usuario con ese nuevo uid y lo agregue al grupo root.

 42
Author: Jared Forsyth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-30 20:35:01