Как использовать sudo внутри док-контейнера?


259

Обычно контейнеры Docker запускаются с использованием пользователя root . Я бы хотел использовать другого пользователя, что без проблем, если использовать директиву USER докера. Но этот пользователь должен иметь возможность использовать sudo внутри контейнера. Эта команда отсутствует.

Вот простой Dockerfile для этой цели:

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

Запустив этот контейнер, я вошел в систему с пользователем 'docker'. Когда я пытаюсь использовать sudo, команда не найдена. Поэтому я попытался установить пакет sudo внутри моего Dockerfile, используя

RUN apt-get install sudo

Это приводит к невозможности найти пакет sudo


Просто предоставьте группу sudo пользователю. askubuntu.com/questions/7477/…
Regan

Ответы:


242

Просто получил это. Как заметил Реган, мне пришлось добавить пользователя в группу sudoers. Но главной причиной было то, что я забыл обновить кеш репозиториев, поэтому apt-get не смог найти пакет sudo. Теперь работает. Вот законченный код:

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
не работает в сентосах. adduserкоманда выплевывает использование помощи дляuseradd
Emad

Для CentOS вы можете добавить пользователя и группу, затем создать файл сегмента /etc/sudoers.d/и установить для него права 440доступа. Тогда пользователь будет иметь доступ к sudo под CentOS, 6 и выше. 5 вы должны будете добавить #includedir /etc/sudoers.dдирективу/etc/sudoers
FilBot3

Не работает для меня У меня есть эти ошибки: E: Не удалось открыть файл блокировки / var / lib / apt / lists / lock - открыть (13: Отказано в
доступе

1
Похоже, это не работает для образа докера Ubuntu 18.04
viggy

100

Если в контейнере нет ни sudo, ни apt-get, вы также можете перейти в запущенный контейнер от имени пользователя root с помощью команды

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

Это гораздо лучшее решение для того, чего, вероятно, хочет достичь ФП, хотя принятый ответ дает запрошенное решение. По крайней мере, это ответ, который я искал!
spikyjt

80

Другие ответы не сработали для меня. Я продолжил поиск и нашел сообщение в блоге, в котором рассказывалось о том, как команда работает без полномочий root внутри контейнера докера.

Вот версия 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 

Я использовал FROM node:9.3для этого, но я подозреваю, что другие аналогичные базы контейнеров также будут работать.


Я использую ubuntu:bionic-20180724.1. Я использовал этот подход, но после вышесказанного он не позволяет мне устанавливать другой пакет. Я приложил одну строку выше Dockerfile, чтобы установить пакет с: RUN apt-get install -y tree. Тем не менее, он дал мне это сообщение об ошибке: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 Я думаю, тебе нужно изменить эту строку, чтобы читать RUN sudo apt-get install -y tree. После установки значения, USERотличного от root, вам нужно будет использовать sudoлюбые команды, требующие rootпривилегий.
М. Скотт Форд

Ах, спасибо! Пропустил это. Я не думал, что sudoбыло разрешено в Dockerfile.
edesz

Отлично, как раз то, что мне было нужно.
Арин Экандем

25

Для тех, у кого есть эта проблема с уже запущенным контейнером, и они не обязательно хотят перестраивать, следующая команда подключается к работающему контейнеру с привилегиями root:

docker exec -ti -u root container_name bash

Вы также можете подключиться, используя его идентификатор, а не имя, найдя его с помощью:

docker ps -l

Чтобы сохранить изменения, чтобы они оставались при следующем запуске контейнера (или кластера docker-compose):

docker commit container_id image_name

Чтобы запустить контейнер, который не запущен и подключиться от имени пользователя root:

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

Чтобы скопировать из запущенного контейнера:

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

Чтобы экспортировать копию изображения:

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

Который вы можете восстановить в другую установку Docker, используя:

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

Это намного быстрее, но занимает больше места, чтобы не сжимать, используя:

docker save container | dir/file.tar

И:

cat dir/file.tar | docker load

17

если вы хотите подключиться к контейнеру и установить что-то
с помощью apt-get
первым, как указано выше, ответ нашего брата "Tomáš Záluský"

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

затем попробуйте

ЗАПУСТИТЕ apt-get update или apt-get 'все, что вы хотите'

это работало со мной, надеюсь, это полезно для всех


5

Если SUDO или apt-get недоступны внутри Контейнера, вы можете использовать опцию ниже в запущенном контейнере.

docker exec -u root -it f83b5c5bf413 ash

« f83b5c5bf413» - это мой идентификатор контейнера, и вот рабочий пример с моего терминала:

введите описание изображения здесь


3

Вот как я настраиваю пользователя без полномочий root с базовым образом 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

Что происходит с приведенным выше кодом:

  • Пользователь и группа fooсозданы.
  • Пользователь fooдобавляется в обоих fooи sudoгруппы.
  • Значение uidи gidустановлено в значение 999.
  • Домашний каталог установлен в /home/foo.
  • Оболочка установлена ​​в /bin/bash.
  • sedКоманда выполняет встроенные обновления в /etc/sudoersфайл , чтобы fooи rootпользователей Беспарольного доступа к sudoгруппе.
  • Команда sedотключает #includedirдирективу, которая позволяет любым файлам в подкаталогах переопределять эти встроенные обновления.

2

Если у вас есть контейнер, работающий от имени пользователя root и запускающий сценарий (который вы не можете изменить), которому нужен доступ к sudoкоманде, вы можете просто создать новый sudoсценарий, $PATHкоторый вызывает переданную команду.

Например, в вашем Dockerfile:

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
В зависимости от используемых вами образов докеров (в моем случае Ubuntu: 18.04) вам может потребоваться удалить -eиз echo. В противном случае он будет присутствовать в самом файле, что делает его неработоспособным.
stiller_leser

Хорошая идея, но это не сработает, если исходная команда использует параметры sudo, такие как sudo -E ls. Он попытается выполнить -E ls.
Висбуки

2

Это может работать не для всех изображений, но некоторые изображения уже содержат пользователя root, например, в образе jupyterhub / singleuser. С этим изображением это просто:

USER root
RUN sudo apt-get update

1

Используйте Псевдоним.

alias sudo=''

Просто, но эффективно. Не забудьте добавить его в ~ / .bash_aliases, чтобы он работал после открытия новой оболочки.

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

Поскольку в Docker пользователь является пользователем root по умолчанию , «игнорирование» команды sudo - самый простой способ.


0

В отличие от принятого ответа , я использую usermodвместо этого.

Предположим, вы уже вошли в систему как root в docker, и «fruit» - это новое имя пользователя без полномочий root, которое я хочу добавить, просто запустите следующие команды:

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

Не забудьте сохранить изображение после обновления. Используйте, docker psчтобы получить текущие данные докера <CONTAINER ID> и <IMAGE>, а затем запустить, docker commit -m "added sudo user" <CONTAINER ID> <IMAGE>чтобы сохранить образ докера.

Затем проверьте с помощью:

su fruit
sudo whoami

Или протестируйте с помощью прямого входа (сначала сохраните образ) как пользователь без полномочий root при запуске Docker:

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

Вы можете использовать sudo -kдля сброса метки времени подсказки пароля:

sudo whoami # No password prompt
sudo -k # Invalidates the user's cached credentials
sudo whoami # This will prompt for password
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.