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

Задача противоречит принципам изоляции докера, но иногда такое решение оправдано (ИМХО).

1)Консольные команды из одного docker контейнера в другой.

Тут всё просто, достаточно прокинуть сокет докера и установить docker в контейнер.

Прокинуть сокет можно установив флаг для docker run

docker run {xxx} -v /var/run/docker.sock:/var/run/docker.sock

или добавив volume в docker-compose.yml

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

после этого сокет docker'a становится доступным внутри контейнера. Устанавливаем в контейнере клиент докера и готово.

2)Запуск команд на хосте из docker контейнера.

Для передачи команды, я решил использовать именованный канал (pipe).

Последовательность действий следующая:

Создаем именованы канал.

mkfifo docker_executor_host

И прокидываем эту папку как volume в docker контейнер.

docker run {xxx} -v {путь}/pipe:{путь}/pipe

или

volumes:
- {путь}/pipe:{путь}/pipe

Добавляем «потребителя», который будет отслеживать изменения, и запускать команды на хосте.

tail-f docker_executor_host | sh &

& В конце заставляет его работать в фоновом режиме.

Второй способ сохранить запущенные процессы после прекращения работы терминала — команда nohup. Вывод команды перенаправляется в файл nohup.out.

Так-же существуют программы, которые позволяют запускать несколько сессий одновременно. Наиболее популярные из них — Screen и Tmux.

Чтобы добавить команду в очередь на исполнение используйте

echo {команда} > docker_executor_host

Таким образом мы можем получить доступ к хост машине из docker контейнера.

Хочу подчеркнуть, что нужно быть крайне аккуратным с использованием этих инструкций, так как они могут предоставить доступ ко всей хост системе и это может быть опасно в случае компрометации «управляющего» контейнера.

Ссылки на источники: