Как создать контейнер linux, который наследует корневую файловую систему хостов, возможно, с помощью zfs?

396
hak8or

Какие

Надеюсь, вопрос в названии имеет смысл. Я хочу создать копию операционной системы хоста с минимальными издержками (поэтому без виртуальной машины), которая будет работать в контейнере Linux.

Я думаю о том, чтобы как-то использовать zfs для создания снимка rootfs хостов, а затем как-то передать это в lxc. Таким образом, любые изменения в контейнере ограничиваются контейнером с помощью функции копирования при записи ZFS, и любые будущие изменения корневых файлов хостов не распространяются на контейнер.

Есть ли потенциальные проблемы, которые я должен принять во внимание, такие как рекурсивные каталоги, вызывающие хаос или что-то еще?

Зачем

Это объясняется тем, что я могу быстро использовать хост в качестве шаблона и играть, например, с установкой новых инструментов сборки, которые загрязняют rootfs, не беспокоясь о том, как это повлияет на хост, и не тратя много места на диске, копируя хосты. корневой файловой системы. Кроме того, я потратил приличное количество времени на настройку хоста так, как мне нравится, и я не хочу тратить несколько дней на то, чтобы снова создать шаблон процесса (хотя я должен был бы написать все это - хорошая идея Автоматизация это еще лучше). Так как это будет в контейнере Linux, я могу иметь несколько запущенных экземпляров одновременно.

3

1 ответ на вопрос

3
Deltik

Я разработал ручную процедуру, которая может сделать это.

Предпосылки

Эти процедуры делают следующие предположения:

  • Ваша оболочка есть /bin/bash.
  • Вы корень.
  • Вы развернули операционную систему в пуле ZFS, rpoolа также хотите, чтобы контейнер LXD находился в том же пуле ZFS ( rpool).
  • Rootfs вашего хоста установлен в rpool/ROOT/osнабор данных ZFS.
  • Вы сделали снимок вашего rootfs и назвали его rpool/ROOT/os@20180516T091126CDT.
  • Вы используете пакет Snappy с LXD.
  • У вас есть lxc storageимя, rpoolиспользуя zfsдрайвер в источнике rpool/lxd.
  • Вы хотите создать непривилегированный контейнер с именем demo.

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

инструкции

  1. Создайте контейнер LXC, используя образ, аналогичный операционной системе вашего хоста:

    root@node51 [~]# lxc launch images:ubuntu/18.04 demo -s rpool Creating demo Starting demo 
  2. Остановить контейнер:

    root@node51 [~]# lxc stop demo 
  3. Смонтируйте том хранения LXC, чтобы мы могли извлечь из него некоторые метаданные:

    root@node51 [~]# zfs mount rpool/lxd/containers/demo 
  4. Скопируйте метаданные куда-нибудь (например /tmp/demo/):

    root@node51 [~]# rsync -avHXShPs --exclude rootfs/ /var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo/ /tmp/demo/ sending incremental file list created directory /tmp/demo ./ backup.yaml 2.05K 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=4/6) metadata.yaml 529 100% 516.60kB/s 0:00:00 (xfr#2, to-chk=3/6) templates/ templates/hostname.tpl 21 100% 20.51kB/s 0:00:00 (xfr#3, to-chk=1/6) templates/hosts.tpl 140 100% 136.72kB/s 0:00:00 (xfr#4, to-chk=0/6)  sent 3.12K bytes received 135 bytes 6.50K bytes/sec total size is 2.74K speedup is 0.84 
  5. Удалите набор данных ZFS, созданный LXC:

    root@node51 [~]# zfs destroy rpool/lxd/containers/demo 
  6. Клонируйте набор данных ZFS с тем же именем, которое ожидает LXC:

    root@node51 [~]# zfs clone rpool/ROOT/os@20180516T091126CDT rpool/lxd/containers/demo 
  7. Установите точку монтирования в исходную точку монтирования:

    root@node51 [~]# zfs set mountpoint=/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo rpool/lxd/containers/demo 
  8. Создайте каталог rootfs для новых данных контейнера:

    root@node51 [~]# mkdir -v /var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo/rootfs/ mkdir: created directory '/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo/rootfs/' 
  9. Расширьте функциональность глобализации вашей оболочки, чтобы гарантировать, что в будущем будут mvприняты все данные файловой системы:

    root@node51 [~]# shopt -s extglob ; shopt -s dotglob 
  10. Немного сократите предстоящие команды, cdвойдя в набор данных контейнера:

    root@node51 [~]# cd /var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo/ root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# 
  11. Переместите все данные контейнера в rootfs/папку:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# mv !(rootfs) rootfs/ 
  12. Создайте несколько папок, которые необходимы для загрузки контейнера:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# mkdir rootfs/ 
  13. Переместите метаданные из резервной копии ранее в набор данных контейнера:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# mv /tmp/demo/* . 
  14. Удалите пустой временный каталог из резервной копии метаданных:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# rm -rfv /tmp/demo removed directory '/tmp/demo' 
  15. Вернитесь в свой предыдущий каталог, чтобы вы могли размонтировать набор данных контейнера:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# cd - /root 
  16. Размонтируйте набор данных контейнера, чтобы LXC мог взять его на себя:

    root@node51 [~]# zfs umount rpool/lxd/containers/demo 
  17. Чтобы при следующем запуске LXC преобразовать файлы контейнера в непривилегированные, запустите

    lxc config edit demo 

    и измените строку, которая читает

    volatile.last_state.idmap: '[{"Isuid":true,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]' 

    в

    volatile.last_state.idmap: '[{"Isuid":true,"Isgid":true,"Hostid":1,"Nsid":0,"Maprange":1000000000}]' 
  18. Запустите контейнер.
    Это займет некоторое время, потому что каждый файл в rootfs контейнера преобразуется в непривилегированный. Нет индикатора прогресса.

    root@node51 [~]# lxc start demo 
  19. Введите контейнер:

    root@node51 [~]# lxc exec demo -- bash 

    Отсюда вы можете настроить сеть, последовательность запуска systemd и / или другие вещи, необходимые для запуска и запуска этого клона LXC-контейнера вашего хоста.

Похожие вопросы