Как запустить Docker-хост внутри Docker-контейнера?

У меня есть контейнер Jenkins, работающий внутри Docker, и я хочу использовать этот контейнер Jenkins для запуска других контейнеров Docker при выполнении интеграционных тестов и т. Д.

Итак, мой план состоял в том, чтобы установить Docker в контейнер, но, похоже, это не так хорошо для меня. Мой Dockerfile выглядит примерно так:

FROM jenkins
MAINTAINER xxxx

# Switch user to root so that we can install apps
USER root

RUN apt-get update 

# Install latest version of Docker
RUN apt-get install -y apt-transport-https
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
RUN sh -c "echo deb https://get.docker.com/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
RUN apt-get update
RUN apt-get install -y lxc-docker

# Switch user back to Jenkins
USER jenkins

Образ jenkins основан на Debian Jessie. Когда я запускаю терминал bash внутри контейнера на основе сгенерированного изображения и делаю, например:

docker images

Я получаю следующее сообщение об ошибке:

FATA[0000] Get http:///var/run/docker.sock/v1.16/images/json: dial unix /var/run/docker.sock: no such file or directory. Are you trying to connect to a TLS-enabled daemon without TLS?

Подозреваю, что это могло быть из-за того, что служба докеров не запущена. Но моя следующая проблема возникает, когда я пытаюсь запустить службу:

service docker start

Это дает мне следующую ошибку:

mount: permission denied

Я отследил ошибку в /etc/init.d/docker в этой строке:

mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup

Итак, мои вопросы:

  1. Как мне запустить хост Docker внутри контейнера? Или этого следует избегать?
  2. Что мне нужно сделать, если я использую Mac и boot2docker?
  3. Возможно, мне следует вместо этого связать Docker на хост-машине, как описано здесь?

Обновление: я пробовал контейнер как пользователь root и jenkins. sudo не устанавливается.


person Johan    schedule 27.01.2015    source источник


Ответы (2)


1.- Первый контейнер, который вы запускаете (тот, который вы запускаете, другой внутри) должен запускаться с флагом --privileged=true.

2.- Думаю, что нет.

3.- Используя привилегированный флаг, вам не нужно монтировать сокет докера как том.

Проверьте этот проект, чтобы увидеть пример всего этого.

person Javier Cortejoso    schedule 27.01.2015
comment
Это работает, если я запускаю свой контейнер Jenkins от имени пользователя root и не включаю CMD [wrapdocker] в конец файла Dockerfile. Мне нужно запустить wrapdocker вручную после запуска контейнера. Причина этого, вероятно, в том, что изображение Jenkins устанавливает EntryPoint, которое, похоже, не работает (контейнер не запускается), если я добавлю CMD [wrapdocker]. Итак, даже если вы ответили на мой вопрос, он все еще работает не так, как я хочу, но я полагаю, что лучше создать еще один вопрос для этой проблемы. - person Johan; 27.01.2015

Более простая альтернатива - смонтировать докер-сокет и создать родственные контейнеры. Для этого установите на свой образ докер и запустите что-то вроде:

docker run -it -v /var/run/docker.sock:/var/run/docker.sock myimage

Теперь в контейнере вы должны иметь возможность запускать команды докеров, как если бы вы были на хосте. Преимущество этого метода в том, что вам не нужно --privileged и вы можете использовать кеш от хоста. Недостатком является то, что вы можете видеть все запущенные контейнеры, а не только те, которые созданы из контейнера.

person Adrian Mouat    schedule 27.01.2015
comment
это отлично работает на ubuntu, но для debian: jessie вам понадобится пакет libsqlite3-0 - иначе ldd $(which docker) показывает libsqlite3.so.0 => not found - person Vincent De Smet; 16.07.2015
comment
Как это будет работать в OSX, где у вас нет /var/run/docker.sock для fwd? - person dgorissen; 20.01.2017
comment
@dgorissen Docker для Mac запускает небольшую виртуальную машину Linux для запуска Docker. У этой виртуальной машины действительно есть /var/run/docker.sock. - person Adrian Mouat; 22.01.2017
comment
@AdrianMouat, спасибо, я действительно нашел сокет в /private/var/run/docker.sock, предположим, что это правильный - person dgorissen; 23.01.2017
comment
@AdrianMouat После того, как вы немного поцарапали голову, выясняется, что вы правы и правильный путь - /var/run/docker.sock, который используется совместно с виртуальной машиной. Меня сбило с толку тот факт, что его нет на хосте, но есть /private/var/run/docker.sock. Однако последнее не работает. Для других, которые сталкиваются с такой же путаницей, эта страница из документации докеров наконец помогла мне (раздел пространства имен): docs.docker.com/docker-for-mac/osxfs - person dgorissen; 02.02.2017