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

Обычно Docker-контейнеры запускаются с использованием пользователя root. Я хотел бы использовать другого пользователя, что без проблем с использованием директивы USER docker. Но этот пользователь должен иметь возможность использовать 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

Ответ 1

Только что получил. Как отметил Режан, мне пришлось добавить пользователя в группу 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

Ответ 2

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

Вот версия TL; DR:

RUN apt-get update
RUN apt-get install 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, но я подозреваю, что другие аналогичные базы контейнеров также будут работать.

Ответ 3

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

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

Ответ 4

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

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

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

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

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

Ответ 5

Для тех, у кого есть эта проблема с уже работающим контейнером, и они не обязательно хотят перестраивать, следующая команда подключается к работающему контейнеру с привилегиями 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 container_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

Ответ 6

Если у вас есть контейнер, работающий от имени пользователя 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

Ответ 7

Вот как я настраиваю пользователя без полномочий 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, которая позволяет любым файлам в подкаталогах переопределять эти встроенные обновления.

Ответ 8

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

USER root
RUN sudo apt-get update

Если у вас еще нет пользователя root, вам не повезло.