Docker e –userns-remap, come gestire le autorizzazioni del volume per condividere i dati tra host e container?

Nella finestra mobile, i file creati all’interno dei contenitori tendono ad avere una proprietà imprevedibile mentre li ispezionano dall’host. Il proprietario dei file su un volume è root (uid 0) per impostazione predefinita, ma non appena gli account utente non root sono coinvolti nel contenitore e scrivono nel file system, i proprietari diventano più o meno casuali dal punto di vista dell’host.

È un problema quando è necessario accedere ai dati del volume dall’host utilizzando lo stesso account utente che sta chiamando i comandi della finestra mobile.

Soluzioni alternative tipiche sono

  • forzare gli uID degli utenti al momento della creazione in Dockerfiles (non portatile)
  • passare l’UID dell’utente host al comando di docker run della docker run come variabile di ambiente e quindi eseguire alcuni comandi chown sui volumi in uno script di un puntatore.

Entrambe queste soluzioni possono dare un certo controllo sulle autorizzazioni effettive al di fuori del contenitore.

Mi aspettavo che gli spazi dei nomi degli utenti fossero la soluzione definitiva a questo problema. Ho eseguito alcuni test con la versione 1.10 recentemente rilasciata e –userns-remap impostata sul mio account desktop. Tuttavia, non sono sicuro che possa semplificare la gestione dei file sui volumi montati, temo che potrebbe effettivamente essere l’opposto.

Supponiamo che avvii questo contenitore di base

 docker run -ti -v /data debian:jessie /bin/bash echo 'hello' > /data/test.txt exit 

E poi ispezionare il contenuto dall’host:

 ls -lh /var/lib/docker/100000.100000/volumes//_data/ -rw-r--r-- 1 100000 100000 6 Feb 8 19:43 test.txt 

Questo numero “100000” è un sub-UID del mio utente host, ma dal momento che non corrisponde all’UID del mio utente, non posso ancora modificare test.txt senza privilegi. Questo sub-utente non sembra avere alcuna affinità con il mio vero utente normale al di fuori della finestra mobile. Non è mappato indietro.

Le soluzioni alternative menzionate in precedenza in questo post che consistevano nell’allineamento degli UID tra l’host e il contenitore non funzionano più a causa del UID->sub-UID che si verifica nello spazio dei nomi.

Quindi, c’è un modo per eseguire la finestra mobile con lo spazio dei nomi utente abilitato (per una maggiore sicurezza), mentre è ancora ansible per l’utente host che esegue la finestra mobile di possedere i file generati sui volumi?

Se è ansible predisporre preventivamente utenti e gruppi, è ansible assegnare UID e GID in modo specifico in modo che gli utenti host corrispondano agli utenti con nomi assegnati all’interno dei contenitori.

Ecco un esempio (Ubuntu 14.04, Docker 1.10):

  1. Crea alcuni utenti con ID numerici fissi:

     useradd -u 5000 ns1 groupadd -g 500000 ns1-root groupadd -g 501000 ns1-user1 useradd -u 500000 -g ns1-root ns1-root useradd -u 501000 -g ns1-user1 ns1-user1 -m 
  2. Modifica manualmente gli intervalli ID subordinati generati automaticamente nei /etc/subuid e /etc/subgid :

     ns1:500000:65536 

    (nota che non ci sono record per ns1-root e ns1-user1 causa dei limiti MAX_UID e MAX_GID in /etc/login.defs )

  3. Abilita namespace utente in /etc/default/docker :

     DOCKER_OPTS="--userns-remap=ns1" 

    Riavvia il service docker restart daemon, assicurarsi che la directory /var/lib/docker/500000.500000 sia stata creata.

    Ora, all’interno dei contenitori hai root e user1 , e sull’host – ns1-root e ns1-user1 , con gli ID corrispondenti

    AGGIORNAMENTO: per garantire che gli utenti non root abbiano ID fissi in contenitori (ad es. Utente1 1000: 1000), crearli esplicitamente durante la creazione dell’immagine.

Test di guida:

  1. Preparare una directory di volume

     mkdir /vol1 chown ns1-root:ns1-root /vol1 
  2. Provalo da un contenitore

     docker run --rm -ti -v /vol1:/vol1 busybox sh echo "Hello from container" > /vol1/file exit 
  3. Prova dall’host

     passwd ns1-root login ns1-root cat /vol1/file echo "can write" >> /vol1/file 

Non portatile e sembra un trucco, ma funziona.

È ansible evitare i problemi di authorization utilizzando il comando docker cp .

La proprietà è impostata all’utente e al gruppo principale nella destinazione. Ad esempio, i file copiati in un contenitore vengono creati con UID:GID dell’utente root. I file copiati sul computer locale vengono creati con l’ UID:GID dell’utente che ha richiamato il comando docker cp .

Ecco il tuo esempio passato a usare docker cp :

 $ docker run -ti -v /data debian:jessie /bin/bash [email protected]:/# echo 'hello' > /data/test.txt [email protected]:/# exit exit $ docker volume ls DRIVER VOLUME NAME local f073d0e001fb8a95ad8d919a5680e72b21a457f62a40d671b63c62ae0827bf93 $ sudo ls -l /var/lib/docker/100000.100000/volumes/f073d0e001fb8a95ad8d919a5680e72b21a457f62a40d671b63c62ae0827bf93/_data total 4 -rw-r--r-- 1 100000 100000 6 Oct 6 10:34 test.txt $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e33bb735a70f debian:jessie "/bin/bash" About a minute ago Exited (0) About a minute ago determined_hypatia $ docker cp determined_hypatia:/data/test.txt . $ ls -l test.txt -rw-r--r-- 1 don don 6 Oct 6 10:34 test.txt $ cat test.txt hello $ 

Tuttavia, se si desidera solo leggere i file da un contenitore, non è necessario il volume denominato. Questo esempio utilizza un contenitore denominato anziché un volume denominato:

 $ docker run -ti --name sandbox1 debian:jessie /bin/bash [email protected]:/# echo 'howdy' > /tmp/test.txt [email protected]3:/# exit exit $ docker cp sandbox1:/tmp/test.txt . $ ls -l test.txt -rw-r--r-- 1 don don 6 Oct 6 10:52 test.txt $ cat test.txt howdy $ 

Trovo i volumi con nome utili quando voglio copiare i file in un contenitore, come descritto in questa domanda .