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


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

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

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.


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

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


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


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.

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

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

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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.