Jak korzystać z sudo w pojemniku dokowanym?

259

Zwykle kontenery dokerów są uruchamiane przy użyciu katalogu głównego użytkownika . Chciałbym użyć innego użytkownika, co nie stanowi problemu przy użyciu dyrektywy USER dokera. Ale ten użytkownik powinien mieć możliwość korzystania z sudo wewnątrz kontenera. Brakuje tego polecenia.

Oto prosty plik Docker do tego celu:

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

Po uruchomieniu tego kontenera loguję się przy użyciu „dokera” użytkownika. Gdy próbuję użyć sudo, nie można znaleźć polecenia. Próbowałem więc zainstalować pakiet sudo w moim pliku Docker

RUN apt-get install sudo

Powoduje to, że nie można znaleźć pakietu sudo

drubb
źródło
Po prostu daj grupie sudo użytkownikowi. askubuntu.com/questions/7477/…
Regan

Odpowiedzi:

242

Właśnie to mam. Jak zauważyła regan, musiałem dodać użytkownika do grupy sudoers. Ale głównym powodem było to, że zapomniałem zaktualizować pamięć podręczną repozytoriów, więc apt-get nie mógł znaleźć pakietu sudo. Już działa. Oto gotowy kod:

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
źródło
8
nie działa w centach. adduserkomenda wypluwa wykorzystanie pomocy dlauseradd
Emad
W przypadku systemu CentOS można dodać użytkownika i grupę, a następnie utworzyć plik niezależnego fragmentu /etc/sudoers.d/i ustawić uprawnienia do 440tego pliku. Wtedy użytkownik miałby dostęp do sudo w CentOS, 6 i nowszych. 5 będziesz musiał dodać #includedir /etc/sudoers.ddyrektywę do/etc/sudoers
FilBot3
Nie działa dla mnie. Mam te błędy: E: Nie można otworzyć pliku blokady / var / lib / apt / list / lock - open (13: Odmowa
dostępu
1
Wydaje się, że nie działa to w przypadku obrazu
dokera
100

Gdy ani sudo, ani apt-get nie są dostępne w kontenerze, możesz również wskoczyć do uruchomionego kontenera jako użytkownik root, używając polecenia

docker exec -u root -t -i container_id /bin/bash
Tomáš Záluský
źródło
Jest to znacznie lepsze rozwiązanie tego, co prawdopodobnie chce osiągnąć PO, mimo że zaakceptowana odpowiedź daje żądane rozwiązanie. Przynajmniej to była odpowiedź, której szukałem!
spikyjt
79

Inne odpowiedzi nie działały dla mnie. Ciągle szukałem i znalazłem post na blogu, który opisywał, jak zespół uruchamiał użytkownika innego niż root wewnątrz kontenera dokowanego.

Oto wersja TL; DR:

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 

Używałem FROM node:9.3tego, ale podejrzewam, że inne podobne podstawy kontenerów również by działały.

M. Scott Ford
źródło
Używam ubuntu:bionic-20180724.1. Użyłem tego podejścia, ale po powyższym nie pozwala mi to na zainstalowanie innego pakietu. I dołączana jedną linię z powyższym Dockerfile, aby zainstalować pakiet z: RUN apt-get install -y tree. Dał mi jednak następujący komunikat o błędzie: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 Myślę, że musisz zmienić ten wiersz, aby przeczytać RUN sudo apt-get install -y tree. Po ustawieniu na USERcoś innego niż root, będziesz musiał używać sudowszystkich poleceń wymagających rootuprawnień.
M. Scott Ford
Ach, dzięki! Przegapiłem to. Nie sądziłem, że sudojest dozwolony w Dockerfile.
edesz
Idealnie, właśnie tego potrzebowałem.
Arin Ekandem
25

Dla każdego, kto ma ten problem z już działającym kontenerem i niekoniecznie chce go odbudować, następujące polecenie łączy się z działającym kontenerem z uprawnieniami roota:

docker exec -ti -u root container_name bash

Możesz także połączyć się przy użyciu jego identyfikatora, a nie nazwy, znajdując go za pomocą:

docker ps -l

Aby zapisać zmiany, aby pozostały tam przy następnym uruchomieniu kontenera (lub klastra tworzenia dokerów):

docker commit container_id image_name

Aby uruchomić kontener, który nie jest uruchomiony i połączyć się jako root:

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

Aby skopiować z działającego kontenera:

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

Aby wyeksportować kopię obrazu:

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

Które możesz przywrócić do innej instalacji Dockera za pomocą:

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

Jest znacznie szybszy, ale nie zajmuje więcej miejsca na kompresję, używając:

docker save container | dir/file.tar

I:

cat dir/file.tar | docker load
Chris
źródło
17

jeśli chcesz połączyć się z kontenerem i zainstalować coś
za pomocą apt-get
najpierw, jak wyżej, odpowiedz od naszego brata „Tomáš Záluský”

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

następnie spróbuj

URUCHOM aktualizację apt-get lub apt-get „cokolwiek chcesz”

działało ze mną, mam nadzieję, że będzie przydatne dla wszystkich

Ismail
źródło
5

Jeśli SUDO lub apt-get nie jest dostępny w kontenerze, możesz użyć opcji poniżej w uruchomionym kontenerze.

docker exec -u root -it f83b5c5bf413 ash

f83b5c5bf413” to mój identyfikator kontenera, a tutaj działa przykład z mojego terminala:

wprowadź opis zdjęcia tutaj

Jogin Ghorecha
źródło
3

Oto jak skonfigurować użytkownika innego niż root przy użyciu podstawowego obrazu 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

Co dzieje się z powyższym kodem:

  • Użytkownik i grupa foozostaną utworzone.
  • Użytkownik foozostanie dodany zarówno do, jak fooi do sudogrupy.
  • Wartość uidi gidjest ustawiona na wartość 999.
  • Katalog domowy jest ustawiony na /home/foo.
  • Powłoka jest ustawiona na /bin/bash.
  • sedKomenda robi inline aktualizacje do /etc/sudoerspliku, aby umożliwić fooi rootużytkowników bez podawania haseł dostępu do sudogrupy.
  • sedKomenda wyłącza #includedirdyrektywy, który pozwoliłby żadnych plików w podkatalogach, aby zastąpić te aktualizacje wbudowanych.
Seth Bergman
źródło
2

Jeśli masz kontener działający jako root, który uruchamia skrypt (którego nie możesz zmienić), który potrzebuje dostępu do sudopolecenia, możesz po prostu utworzyć nowy sudoskrypt w swoim, $PATHktóry wywołuje przekazane polecenie.

np. w twoim pliku Docker:

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
źródło
1
W zależności od używanych obrazów dokera (w moim przypadku Ubuntu: 18.04) może być konieczne usunięcie -ez echo. W przeciwnym razie będzie on obecny w samym pliku, czyniąc go niedziałającym.
stiller_leser
Świetny pomysł, ale to nie zadziała, jeśli oryginalne polecenie używa opcji sudo, takich jak sudo -E ls. Spróbuje wykonać -E ls.
wisbucky
2

To może nie działać dla wszystkich obrazów, ale niektóre obrazy zawierają już użytkownika root, na przykład w obrazie jupyterhub / singleuser. Z tym obrazem jest to po prostu:

USER root
RUN sudo apt-get update
Alex Kaszyński
źródło
1

Użyj aliasu.

alias sudo=''

Prosty i wydajny. Nie zapomnij dołączyć go do .bashrc, aby nadal działał po ponownym otwarciu powłoki.

nano ~/.bashrc
alias sudo=''

Ponieważ użytkownik jest domyślnym rootem w Dockerze, „zignoruj” polecenie sudo jest najprostszym sposobem.

Dogkiller87
źródło
0

W przeciwieństwie do zaakceptowanej odpowiedzi , usermodzamiast niej używam .

Załóżmy, że jesteś zalogowany jako root w oknie dokowanym, a „fruit” to nowa nazwa użytkownika innego niż root, którą chcę dodać, po prostu uruchom następujące polecenia:

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

Pamiętaj, aby zapisać obraz po aktualizacji. Użyj, docker psaby uzyskać bieżące uruchomione okno dokowane <CONTAINER ID> i <IMAGE>, a następnie uruchom, docker commit -m "added sudo user" <CONTAINER ID> <IMAGE>aby zapisać obraz dokera.

Następnie przetestuj za pomocą:

su fruit
sudo whoami

Lub przetestuj przez bezpośrednie logowanie (najpierw zapisz obraz) jako użytkownik inny niż root podczas uruchamiania dokera:

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

Możesz użyć sudo -kdo zresetowania sygnatury czasowej hasła:

sudo whoami # No password prompt
sudo -k # Invalidates the user's cached credentials
sudo whoami # This will prompt for password
Owoc
źródło