Wie verwende ich sudo in einem Docker-Container?

259

Normalerweise werden Docker-Container mit dem Benutzer root ausgeführt . Ich möchte einen anderen Benutzer verwenden, was mit der USER-Direktive von Docker kein Problem darstellt. Dieser Benutzer sollte jedoch in der Lage sein, sudo im Container zu verwenden. Dieser Befehl fehlt.

Hier ist eine einfache Docker-Datei für diesen Zweck:

FROM ubuntu:12.04

RUN useradd docker && echo "docker:docker" | chpasswd
RUN mkdir -p /home/docker && chown -R docker:docker /home/docker

USER docker
CMD /bin/bash

Wenn ich diesen Container ausführe, werde ich mit dem Benutzer 'docker' angemeldet. Wenn ich versuche, sudo zu verwenden, wird der Befehl nicht gefunden. Also habe ich versucht, das sudo- Paket mit in meiner Docker-Datei zu installieren

RUN apt-get install sudo

Dies führt dazu, dass das Paket sudo nicht gefunden werden kann

drubb
quelle
Geben Sie dem Benutzer einfach eine Sudo-Gruppe. askubuntu.com/questions/7477/…
Regan

Antworten:

242

Ich habe es gerade verstanden. Wie Regan betonte, musste ich den Benutzer zur Sudoers-Gruppe hinzufügen. Der Hauptgrund war jedoch, dass ich vergessen hatte, den Repositorys-Cache zu aktualisieren, sodass apt-get das sudo-Paket nicht finden konnte. Es funktioniert jetzt. Hier ist der vollständige Code:

FROM ubuntu:12.04

RUN apt-get update && \
      apt-get -y install sudo

RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo

USER docker
CMD /bin/bash
drubb
quelle
8
funktioniert nicht in Centos. Der adduserBefehl spuckt die Verwendungshilfe füruseradd
Emad
Für CentOS können Sie einen Benutzer und eine Gruppe hinzufügen, dann eine Shard-Datei unter erstellen /etc/sudoers.d/und die Berechtigungen für 440diese Datei festlegen . Dann hätte der Benutzer unter CentOS, 6 und höher, Sudo-Zugriff. 5 Sie müssen die #includedir /etc/sudoers.dDirektive in/etc/sudoers
FilBot3
Funktioniert bei mir nicht Ich habe folgende Fehler: E: Sperrdatei / var / lib / apt / lists / lock - open konnte nicht geöffnet werden (13: Berechtigung verweigert) E: Verzeichnis / var / lib / apt / lists /
Marosinho konnte nicht gesperrt werden
1
Dies scheint nicht für Ubuntu 18.04 Docker Image zu funktionieren
Viggy
100

Wenn weder sudo noch apt-get im Container verfügbar sind, können Sie mit dem Befehl auch als Root-Benutzer in den laufenden Container springen

docker exec -u root -t -i container_id /bin/bash
Tomáš Záluský
quelle
Dies ist eine viel bessere Lösung für das, was das OP wahrscheinlich erreichen möchte, obwohl die akzeptierte Antwort die angeforderte Lösung ergibt. Zumindest ist es die Antwort, nach der ich gesucht habe!
spikyjt
79

Die anderen Antworten haben bei mir nicht funktioniert. Ich suchte weiter und fand einen Blog-Beitrag , in dem beschrieben wurde, wie ein Team in einem Docker-Container ohne Root ausgeführt wurde.

Hier ist die TL; DR-Version:

RUN apt-get update \
 && apt-get install -y sudo

RUN adduser --disabled-password --gecos '' docker
RUN adduser docker sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

USER docker

# this is where I was running into problems with the other approaches
RUN sudo apt-get update 

Ich habe dafür verwendet FROM node:9.3, aber ich vermute, dass andere ähnliche Containerbasen auch funktionieren würden.

M. Scott Ford
quelle
Ich benutze ubuntu:bionic-20180724.1. Ich habe diesen Ansatz verwendet, aber nach dem oben Gesagten kann ich kein anderes Paket installieren. Ich habe eine Zeile an das Obige angehängt Dockerfile, um ein Paket mit zu installieren : RUN apt-get install -y tree. Es gab mir jedoch diese Fehlermeldung:Step xxxx/xxxx : RUN apt-get install -y tree ---> Running in j5e6gsvwfafa Reading package lists... E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied) E: Unable to lock directory /var/lib/apt/lists/
Edesz
1
@ WR Ich denke, Sie müssen diese Zeile ändern, um zu lesen RUN sudo apt-get install -y tree. Nachdem Sie das USERauf etwas anderes als gesetzt haben root, müssen Sie es sudofür alle Befehle verwenden, für die rootBerechtigungen erforderlich sind .
M. Scott Ford
Ah danke! Hab das verpasst. Ich dachte nicht, dass sudoes in einer Docker-Datei erlaubt ist.
Edesz
Perfekt, genau das, was ich brauchte.
Arin Ekandem
25

Für alle, die dieses Problem mit einem bereits laufenden Container haben und nicht unbedingt neu erstellen möchten, stellt der folgende Befehl eine Verbindung zu einem laufenden Container mit Root-Rechten her:

docker exec -ti -u root container_name bash

Sie können eine Verbindung auch über die ID und nicht über den Namen herstellen, indem Sie Folgendes suchen:

docker ps -l

So speichern Sie Ihre Änderungen, damit sie beim nächsten Start des Containers (oder des Docker-Compose-Clusters) noch vorhanden sind:

docker commit container_id image_name

So starten Sie einen Container, der nicht ausgeführt wird, und stellen eine Verbindung als root her:

docker run -ti -u root --entrypoint=/bin/bash image_id_or_name -s

So kopieren Sie aus einem laufenden Container:

docker cp <containerId>:/file/path/within/container /host/path/target

So exportieren Sie eine Kopie des Bildes:

docker save container | gzip > /dir/file.tar.gz

Welche Sie in einer anderen Docker-Installation wiederherstellen können, indem Sie:

gzcat /dir/file.tar.gz | docker load

Es ist viel schneller, benötigt aber mehr Platz, um nicht zu komprimieren.

docker save container | dir/file.tar

Und:

cat dir/file.tar | docker load
Chris
quelle
17

Wenn Sie eine Verbindung zum Container herstellen und etwas
mit apt-get installieren möchten,
antworten Sie zuerst wie oben von unserem Bruder "Tomáš Záluský".

docker exec -u root -t -i container_id /bin/bash

dann versuche es

RUN apt-get update oder apt-get 'alles was du willst'

es hat bei mir funktioniert hoffentlich ist es für alle nützlich

Ismail
quelle
5

Wenn auf SUDO oder apt-get im Container nicht zugegriffen werden kann, können Sie die folgende Option zum Ausführen des Containers verwenden.

docker exec -u root -it f83b5c5bf413 ash

" f83b5c5bf413" ist meine Container-ID und hier ist ein Arbeitsbeispiel von meinem Terminal:

Geben Sie hier die Bildbeschreibung ein

Yogi Ghorecha
quelle
3

So richte ich einen Nicht-Root-Benutzer mit dem Basis-Image ein ubuntu:18.04:

RUN \
    groupadd -g 999 foo && useradd -u 999 -g foo -G sudo -m -s /bin/bash foo && \
    sed -i /etc/sudoers -re 's/^%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
    sed -i /etc/sudoers -re 's/^root.*/root ALL=(ALL:ALL) NOPASSWD: ALL/g' && \
    sed -i /etc/sudoers -re 's/^#includedir.*/## **Removed the include directive** ##"/g' && \
    echo "foo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
    echo "Customized the sudoers file for passwordless access to the foo user!" && \
    echo "foo user:";  su - foo -c id

Was passiert mit dem obigen Code:

  • Der Benutzer und die Gruppe foowerden erstellt.
  • Der Benutzer foowird sowohl zur Gruppe fooals auch zur sudoGruppe hinzugefügt .
  • Das uidund gidwird auf den Wert von gesetzt 999.
  • Das Home-Verzeichnis ist auf eingestellt /home/foo.
  • Die Shell ist auf eingestellt /bin/bash.
  • Der sedBefehl führt Inline - Aktualisierungen der /etc/sudoersDatei zu ermöglichen foound rootan den Zugangs passwordless Benutzer - sudoGruppe.
  • Der sedBefehl deaktiviert die #includedirAnweisung, mit der Dateien in Unterverzeichnissen diese Inline-Aktualisierungen überschreiben können.
Seth Bergman
quelle
2

Wenn Sie einen Container als root ausführen, der ein Skript ausführt (das Sie nicht ändern können), das Zugriff auf den sudoBefehl benötigt, können Sie einfach ein neues sudoSkript in Ihrem erstellen $PATH, das den übergebenen Befehl aufruft.

zB In Ihrer Docker-Datei:

RUN if type sudo 2>/dev/null; then \ 
     echo "The sudo command already exists... Skipping."; \
    else \
     echo -e "#!/bin/sh\n\${@}" > /usr/sbin/sudo; \
     chmod +x /usr/sbin/sudo; \
    fi
XtraSimplicity
quelle
1
Abhängig von den verwendeten Docker-Images (in meinem Fall Ubuntu: 18.04) müssen Sie möglicherweise die -eaus dem entfernen echo. Andernfalls ist es in der Datei selbst vorhanden, wodurch es nicht mehr funktionsfähig ist.
stiller_leser
Gute Idee, aber dies funktioniert nicht, wenn der ursprüngliche Befehl sudo-Optionen verwendet, wie z sudo -E ls. Es wird versucht, auszuführen -E ls.
wisbucky
2

Dies funktioniert möglicherweise nicht für alle Bilder, aber einige Bilder enthalten bereits einen Root-Benutzer, z. B. im jupyterhub / singleuser-Bild. Mit diesem Bild ist es einfach:

USER root
RUN sudo apt-get update
Alex Kaszynski
quelle
1

Verwenden Sie Alias.

alias sudo=''

Einfach aber effizient. Vergessen Sie nicht, es an ~ / .bash_aliases anzuhängen, damit es funktioniert, nachdem Sie eine neue Shell geöffnet haben.

nano ~/.bash_aliases
alias sudo=''
#(Ctrl+X)

Da der Benutzer in Docker das Standard- Root- Verzeichnis ist, ist das Ignorieren des Befehls sudo der einfachste Weg.

Dogkiller87
quelle
0

Im Gegensatz zu akzeptierten Antworten verwende ich usermodstattdessen.

Angenommen, Sie sind bereits als Root im Docker angemeldet und "ruit "ist der neue Nicht-Root-Benutzername, den ich hinzufügen möchte. Führen Sie einfach die folgenden Befehle aus:

apt update && apt install sudo
adduser fruit
usermod -aG sudo fruit

Denken Sie daran, das Bild nach dem Update zu speichern. Verwenden Sie docker psdiese Option, um die <CONTAINER ID> und <IMAGE> des aktuellen Dockers abzurufen, und führen Sie sie dann aus docker commit -m "added sudo user" <CONTAINER ID> <IMAGE>, um das Docker-Image zu speichern.

Dann testen mit:

su fruit
sudo whoami

Oder testen Sie durch direktes Anmelden (stellen Sie sicher, dass das Bild zuerst gespeichert wird) als Nicht-Root-Benutzer, wenn Sie Docker starten:

docker run -it --user fruit <IMAGE>
sudo whoami

Sie können den sudo -kZeitstempel für die Kennwortabfrage zurücksetzen:

sudo whoami # No password prompt
sudo -k # Invalidates the user's cached credentials
sudo whoami # This will prompt for password
Obst
quelle