Можно ли запустить остановленный контейнер из другого контейнера

Есть два контейнера A и B. После запуска контейнера A будет выполнен один процесс, после чего контейнер остановится. Контейнер B — это просто веб-приложение (скажем, expressjs). Можно ли запустить A из контейнера B?


person tony.0919    schedule 13.09.2016    source источник


Ответы (3)


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

docker run -v /var/run/docker.sock:/var/run/docker.sock --name containerB myimage ...

Теперь, если у вас есть клиент docker, доступный внутри контейнера, вы сможете управлять демоном docker на своем хосте и использовать его для создания контейнера A.

Прежде чем попробовать этот подход, вы должны знать о соображениях безопасности: доступ к докеру аналогичен root доступу к хосту, что означает, что если ваше веб-приложение имеет удаленную компрометацию, вы только что передали ключи от вашего хоста злоумышленникам. . Более подробно это описано в этой статье.

person larsks    schedule 13.09.2016
comment
Я последовал этому совету. Затем я вручную скопировал docker и docker-compose в контейнер. docker-compose нормально работает внутри контейнера. Однако мне нужно скопировать /usr/lib/x86_64-linux-gnu/libltdl.so.7.3.1 с моего хоста в контейнер, а затем внутри контейнера я создаю символическую ссылку на ln -sf /usr/lib/x86_64-linux-gnu/libltdl.so.7.3.1 /usr/lib/x86_64-linux-gnu/libltdl.so.7. Внутри контейнера: ldd /usr/bin/docker все библиотеки теперь разрешены, и я могу запускать docker и docker-cocmpose внутри контейнера. - person eigenfield; 08.01.2018
comment
У меня установлен клиент Docker в моем контейнере, и я открываю сокет Docker хост-системы, но когда я пытаюсь запустить контейнер из контейнера, я получаю отказ в разрешении при попытке подключиться к сокету демона Docker. Я сделал usermod -a -G docker $user при сборке контейнера. $user не существует вне контейнера. Любой совет? Я спрашиваю здесь, а не добавляю новый вопрос, потому что считаю, что это может быть действительным или даже необходимым дополнением к этому ответу. - person Raketenolli; 18.09.2020
comment
Кажется, проблема была в том, что gid контейнера и хост-докера были разными. groupmod -g <host gid> docker в Dockerfile исправляет это. - person Raketenolli; 18.09.2020

Это возможно путем установки докер-сокета.

Контейнер A
Он выводит время на стандартный вывод (и его журналы) и завершает работу.

docker run --name contA ubuntu date

Контейнер B
Хитрость заключается в том, чтобы смонтировать сокет Docker хоста, а затем установить клиент Docker в контейнере. Затем он будет взаимодействовать с демоном так же, как если бы вы использовали докер с хоста. После установки докера он просто перезапускает контейнер A каждые 5 секунд.

docker run --name contB -v /var/run/docker.sock:/var/run/docker.sock ubuntu bash -c "
apt-get update && apt-get install -y curl &&
curl -sSL https://get.docker.com/ | sh && 
watch --interval 5 docker restart contA"

Вы можете видеть, что вызывается contA, просматривая его журналы.

docker logs contA

Тем не менее, Docker действительно предназначен для долго работающих сервисов. В вопросах Docker github есть некоторые разговоры об указании недолговечных сервисов «задания» для таких вещей, как техническое обслуживание, задания cron и т. Д., Но ничего не решено, а тем более закодировано. Так что лучше построить свою систему так, чтобы контейнеры были в рабочем состоянии.

person Bernard    schedule 13.09.2016
comment
Я не сразу опубликовал свой ответ, поэтому @larsks появился первым. Я все равно оставлю его здесь, так как в нем есть код, который может оказаться полезным. - person Bernard; 13.09.2016
comment
Оно работает. Я не уверен, стоит ли устанавливать докер внутри докера, это был бы другой вопрос. Поскольку @larsks появился первым, я просто отмечаю это. - person tony.0919; 15.09.2016
comment
Это работает, но код мне не очень понятен. Я озадачен использованием get.docker.com. В любом случае, нужно установить docker-ce внутри контейнера докеров ( apt-get install docker-ce ), а затем использовать перезапуск контейнера docker для перезапуска другого контейнера докеров. - person Somum; 29.11.2017

docker-compose.yml (кредиты larsks)

# ...
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock
# ...

Dockerfile (кредиты Аарона V)

# ...

ENV DOCKERVERSION=19.03.12
RUN curl -fsSLO https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKERVERSION}.tgz \
  && tar xzvf docker-${DOCKERVERSION}.tgz --strip 1 -C /usr/local/bin docker/docker \
  && rm docker-${DOCKERVERSION}.tgz

# ...

Node.js index.js (благодаря Арпану Абхишеку, Маулику Пармару и Анишсане)

# ...

const { exec } = require("child_process");

# ...

        exec('docker container ls -a --format "table {{.ID}}\t{{.Names}}" | grep <PART_OF_YOUR_CONTAINER_NAME> | cut -d" " -f1 | cut -f1 | xargs -I{} docker container restart -t 0 {}', (error, stdout, stderr) => {
            if (error) {
                console.log(`error: ${error.message}`);
                return;
            }
            if (stderr) {
                console.log(`stderr: ${stderr}`);
                return;
            }
            console.log(`stdout: ${stdout}`);
        });

# ...
  • Убедитесь, что ваше приложение как минимум защищено паролем. Любое разоблачение docker.sock — это вопрос безопасности.
  • Здесь вы можете найти другие версии клиента Docker: https://download.docker.com/linux/static/stable/x86_64/
  • Замените <PART_OF_YOUR_CONTAINER_NAME> на часть имени вашего контейнера.
person qräbnö    schedule 06.08.2020