Debian.pro

Про Debian


Docker persistent containers. Или используем docker почти как chroot.

«Если нельзя, но очень хочется — то можно». В голове крутилась эта фраза после того, как я очередному человеку с заболеванием «докер головного мозга» вынужден был «пошутить» в духе «чувак, тебе здесь проще весь корень контейнера смонтировать как volume», а я сидел и думал, что не такая уж это и шутка, если её в десятый раз за 2 месяца произнести пришлось.

И действительно, желание запихать всё в докер стало совсем уж неадекватным — самоцелью ставится не идеология контейнеров, а «нам нужно, чтобы было обязательно в докере». Первые признаки болезни — «нет, мне не нужен dockerfile», «как это делать docker commit после каждого действия Х???», «не, мне просто сделай так, чтобы было в докере, но после ребута запускалось так же». Ах да, если вы UDP-приложение пытаетесь в докере запустить — скорее всего, вы тоже заболеваете. Ну да неважно, это моё брюзжание.

Если в гугл втупую придти с запросом «docker persistent containers» — нас справедливо пошлют нахрен. Ну или посоветуют использовать volume (в принципе, можно и с ними, но без них удобнее) — вот только нам их будут советовать использовать «for keeping persistent data in containers». Не то, но продолжить мысль можно.

В целом, пока у меня крутилась фраза из песенки, оставшейся в восьмом классе школы (хрен там угадали, кстати — d.a. b.o.m.b., а не вот это невнятное нечто), мысль крутилась в районе области опции -v. Эта опция позволяет смонтировать каталог с docker-хоста (железки) внутрь контейнера при запуске. Играться будем с chroot-каталогом, созданным при помощи deboostrap, например:

root@server:~# mkdir -p /chroot/jessie/
root@server:~# debootstrap jessie /tmp/jessie/

На этом месте я подумал очевидную мысль — давайте сделаем -v /chroot/jessie/:/

root@server:~# docker run -v /chroot/jessie/:/ --privileged --rm some-image sleep 3600
docker: Error response from daemon: invalid bind mount spec "/chroot/jessie/:/": invalid volume specification: '/chroot/jessie/:/': invalid mount config for type "bind": invalid specification: destination can't be '/'.

Здесь мысль была — «ха! ты кого лечить пытаешься? Тебе не / мешается, а наверняка /proc, /dev/ и /sys». Ну чтож:

root@server:~# docker run -v /chroot/jessie/bin:/bin -v /chroot/jessie/boot:/boot -v /chroot/jessie/etc:/etc -v /chroot/jessie/home:/home -v /chroot/jessie/lib:/lib -v /chroot/jessie/lib64:/lib64 -v /chroot/jessie/media:/media -v /chroot/jessie/mnt:/mnt -v /chroot/jessie/opt:/opt -v /chroot/jessie/root:/root -v /chroot/jessie/run:/run -v /chroot/jessie/sbin:/sbin -v /chroot/jessie/srv:/srv -v /chroot/jessie/tmp:/tmp -v /chroot/jessie/usr:/usr -v /chroot/jessie/var:/var --privileged --rm some-image sleep 3600

Получилось немного страшненько, но заработало. А чего б ему не заработать, если мы все каталоги смонтировали внутри контейнера? Можно разве что написать покороче:

root@server:~# docker run $(for dir in $(ls -1 /chroot/jessie/ | egrep -v "^(proc|sys|dev)$" ); do echo -n " -v /chroot/jessie/${dir}:/${dir} "; done) --privileged --rm haas-bugs sleep 3600

Понятное дело, что sleep 3600 стоит заменить на путь до какого-то реального демона, которого мы хотим запустить в контейнере (вангую — supervisor, только поставить его не забудьте). А так в общем-то всё — придумывайте, как этот контейнер будете запускать (я больной ублюдок — запускаю systemd-unit-ом) и пользуйтесь. Всякие docker exec будут работать уже ожидаемым образом:

root@server:~# /usr/bin/docker exec -i -t 004f57e2e56c /bin/bash
root@004f57e2e56c:/# ps ax
    PID TTY      STAT   TIME COMMAND
      1 ?        Ss     0:00 sleep 3600
     24 pts/0    Ss     0:00 /bin/bash
     39 pts/0    R+     0:00 ps ax

И да, вместо some-image выбирайте любой самый маленький image. Лучше чтобы в нём вообще ничего не было (правда, я с ходу не понял, как запуллить scratch).

ЗЫ — если вам хочется сказать «слушай, но это же неправильно», то я вам могу ответить, что вы докер тоже неправильно используете, скорее всего ;) А так в целом удобно. Альтернатива — machinectl (с тех пор, как systemd в chroot работать отказывается), она ещё хреновее. А запустить какое-нибудь гомно дома — самое то.
Кстати, потом поиграю в КО и расскажу, как такое упаковать в обычный image.


Комментариев пока нет.

Написать комментарий