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).
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.
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
.
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