2016-04-21 8 views
21

Docker tipo di sempre ha un comando USER per eseguire un processo come utente specifico, ma in generale molte cose devono essere eseguite come ROOT.Docker utilizzando gosu vs USER

Ho visto molte immagini che utilizzano uno ENTRYPOINT con gosu per deselezionare il processo da eseguire.

Sono ancora un po 'confuso sulla necessità di gosu. L'UTENTE non dovrebbe essere sufficiente?

So che un po 'è cambiato in termini di sicurezza con Docker 1.10, ma non sono ancora chiaro sul modo consigliato di eseguire un processo in un container.

Qualcuno può spiegare quando utilizzare gosu rispetto a USER?

Grazie

EDIT:

Il Docker best practice guide non è molto chiara: Si dice che se il processo può essere eseguito senza privilegi, usare USER, se avete bisogno di sudo, si potrebbe desiderare di utilizzare gosu. Ciò è fonte di confusione perché è possibile installare tutti i tipi di cose come ROOT nello Dockerfile, quindi creare un utente e assegnargli i privilegi appropriati, quindi passare a quell'utente ed eseguire lo CMD come tale utente. Allora perché dovremmo aver bisogno di sudo o gosu allora?

risposta

18

I file Dockerfiles servono a creare immagini. Vedo gosu più utile come parte dell'inizializzazione di un contenitore quando non puoi più cambiare gli utenti tra i comandi di esecuzione nel tuo Dockerfile.

Dopo aver creato l'immagine, qualcosa come gosu consente di rilasciare i permessi di root alla fine del tuo entrypoint all'interno di un contenitore. All'inizio potrebbe essere necessario l'accesso come root per fare alcuni passi di inizializzazione (correzione dei permessi del volume montato su host, uid, ecc.). Quindi, una volta inizializzato, si esegue il servizio finale senza privilegi di root e come pid 1 per gestire i segnali in modo pulito.


Edit: Ecco un semplice esempio di utilizzo di gosu in un'immagine per docker e Jenkins: https://github.com/bmitch3020/jenkins-docker

L'entrypoint.sh guarda in alto il GID del file /var/lib/docker.sock e aggiorna il gid dell'utente docker all'interno del contenitore in modo che corrisponda. Ciò consente all'immagine di essere trasferita su altri host di docker in cui il gid sull'host può essere diverso. La modifica del gruppo richiede l'accesso root all'interno del contenitore. Se avessi usato USER jenkins nel file docker, sarei rimasto bloccato con il gid del gruppo docker come definito nell'immagine che non funzionerebbe se non corrisponde a quello dell'host di docker su cui è in esecuzione.Ma l'accesso root può essere interrotto quando si esegue l'app che è dove gosu entra.

Alla fine dello script, la chiamata exec impedisce alla shell di eseguire il fork di gosu e sostituisce invece pid 1 con quel processo. Gosu a sua volta fa lo stesso, passando l'uid e quindi eseguendo il processo jenkins in modo che subentra come pid 1. Ciò consente di gestire correttamente i segnali che altrimenti verrebbero ignorati da una shell come pid 1.

+0

ok, ora comincia a dare un senso – MrE

3

Sto usando gosu e entrypoint.sh perché voglio che l'utente nel contenitore abbia lo stesso UID dell'utente che ha creato il contenitore.

Docker Volumes and Permissions.

Lo scopo del contenitore che sto creando è per lo sviluppo. Ho bisogno di costruire per Linux, ma voglio ancora tutta la connivenza degli strumenti di modifica (OS X) locali, ecc. Mantenendo gli UID uguali all'interno e all'esterno del contenitore, mantiene la proprietà dei file molto più sana e previene alcuni errori (l'utente del contenitore non può modificare i file nel volume montato, ecc.)

+0

Non sono sicuro di seguire qui: 'gosu' corre nel contenitore; Funziona come ROOT che impersona un altro utente. Questo utente doveva essere definito nell'immagine. Quindi, come è correlato all'utente che ha "creato" l'immagine? Posso vedere che se crei lo stesso utente di un utente locale, e poi usi gosu per essere eseguito come questo utente, questo eviterà conflitti con un volume locale montato, ma solo perché l'utente ha lo stesso nome. – MrE

+1

@MrE: l'utente non deve essere definito nell'immagine. Può essere creato con 'useradd' all'interno del contenitore all'avvio. Quando username, uid e gid vengono passati come variabili di ambiente nel contenitore, possono essere impostati in modo che corrispondano ai valori sull'host. –

0

Il vantaggio dell'uso di gosu è anche la gestione dei segnali. È possibile trap ad esempio SIGHUP per ricaricare il processo come normalmente si otterrebbe tramite systemctl reload <process> o simile.