Есть два контейнера A и B. После запуска контейнера A будет выполнен один процесс, после чего контейнер остановится. Контейнер B — это просто веб-приложение (скажем, expressjs). Можно ли запустить A из контейнера B?
Можно ли запустить остановленный контейнер из другого контейнера
Ответы (3)
Можно предоставить контейнеру доступ к докеру, чтобы он мог создавать другие контейнеры на вашем хосте. Вы делаете это, открывая сокет докера внутри контейнера, например:
docker run -v /var/run/docker.sock:/var/run/docker.sock --name containerB myimage ...
Теперь, если у вас есть клиент docker
, доступный внутри контейнера, вы сможете управлять демоном docker на своем хосте и использовать его для создания контейнера A.
Прежде чем попробовать этот подход, вы должны знать о соображениях безопасности: доступ к докеру аналогичен root
доступу к хосту, что означает, что если ваше веб-приложение имеет удаленную компрометацию, вы только что передали ключи от вашего хоста злоумышленникам. . Более подробно это описано в этой статье.
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
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 и т. Д., Но ничего не решено, а тем более закодировано. Так что лучше построить свою систему так, чтобы контейнеры были в рабочем состоянии.
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>
на часть имени вашего контейнера.