Ответы пользователя по тегу Linux
  • В чём преимущества и недостатки установок через apt и snap?

    Sergey_Evsyukov
    @Sergey_Evsyukov
    Бот
    В свое время тоже вставал перед выбором deb или snap. Изучил этот вопрос максимально, на сколько это было возможным. Чтобы сделать правильный выбор, нужно понимать, как это работает.

    Начну по старшенству - с deb. В традиционном мире deb наша операционная система Linux обладает списком источников софта, которые называются репозиториями. Есть официальные, которые хранятся тут: /etc/apt/sources.list и не официальные, которые хранятся тут: /etc/apt/sources.list.d/.
    Устанавливая софт через GUI или CLI, установщик вначале скачивает с репозиториев списки доступного в нём софта. Софт, как сложный программный продукт, традиционно разбивается на логические части, идущие в различных пакетах, для этого требуется обработать зависимости с помощью ресурсов вашего ПК, этот процесс называется full dependency resolution. Установщик deb пакетов скачивает их с репозитория в каталог типа /var/cache/apt/archives/, распаковывает их содержимое по тем абсолютным путям, что идут в пакете deb. После команд типа apt clean пакеты в /var/cache/apt/archives/ будут удалены, так как они выполнили свою задачу и больше не нужны.
    В deb программу дробят на различные пакеты, выделяя библиотеки/плагины/фреймворки в отдельные пакеты, чтобы делить их с другими программами. Классический пример, программа А идёт в пакете a.deb и зависит от пакета openssl.deb и программа B из пакета b.deb, зависит так же от openssl.deb. Получается, что программа А и В делят между собой (share) общую библиотеку из openssl.deb, т.е. зависят от одного и того же пакета openssl.deb.

    В мире snap понятия зависимости не существует. И один snap пакет с программой не зависит от другого snap пакета. Программа внутри snap сжата со всем необходимым ей с помощью squashfs. Пакет скачивается с хранилища в виде snap package в каталог /var/lib/snapd/snaps/ и никуда и никогда не распаковывается. Пакет с программой монтируется в каталог /snap/[name]/[version]/. Snap программу упаковывают вместе с тем, что ей необходимо для работы. Например, внутри пакета a.snap есть файлы программы А и openssl и внутри пакета В есть файлы программы В и openssl.

    Когда придумывали формат snap, хотели прежде всего отказаться от full dependency resolution. Скорее всего каждый встречал ситуацию, когда разрешение зависимостей заканчивалось ошибкой. Нужно было пробовать решить ситуацию командами типа sudo apt-get install -f. Можно было попробовать переустановить пакет с установкой дефолтных настроек. Это всё является не надёжностью в мире серверов и десктопа, а в мире мобильных устройств, для которых готовили формат snap - смертельно. Например, как на маломощном устройстве решить ситуацию при вероятной проблеме? Тем более full dependency resolution довольно таки затратная операция для CPU. Нужна была надёжность в лице атомарности:
    1. Скачал snap пакет.
    2. Не затратно для CPU примонтировал пакет, без full dependency resolution, без распаковки.
    3. Получил новую версию программы.
    4. Если новая версия программа будет вызывать проблемы, то можно легко откатиться к старой версии, перемонтировав на старую версию пакета.

    Скорее всего возник вопрос, больше ли места нужно использовании snap пакетов? Да, больше. Это плата за версионность и надежность. Без технологии share, snap пакеты используют больше места. Для поддержки механизма отката и возможности вернуться к старой работоспособной версии, в системе хранится несколько версий snap пакета программы.

    Все программы внутри snap пакета изолированы от операционной системы и друг от друга профилем мандатного доступа AppArmor. В терминах snap технологии - это интерфейсы (interface). Интерфейс - это когда plug соединён со slot. Хотите из программы звук? Просите при упаковке программы через snapcraft.yaml, чтобы plug pulseaudio соединили с одноимённым slot pulseaudio в системе (пакет ubuntu-core). До этого момента все slot предоставляла операционная система через snap пакет ubuntu-core. То есть все программы, стыковались (connect) только со слотами системы и получали требуемое. Разработчики реализовали интерфейс connect и стало возможно snap А соединить со snap Б. На примере фреймворка KDE можно увидеть, как разработчики использовали данное решение. Первые пробы упаковки KCalc выдавали snap пакеты по 70 мб из-за kde-frameworks-5 внутри, но стоило воспользоваться интерфейсом connect и вынести kde-frameworks-5 в отдельный snap пакет, то KCalc похудел до 300 кб. Связь между snap пакетами описывается в snapcraft.yaml, который добавляется в пакет при упаковке. Snap позволяет в операционной системе обладать несколькими версиями библиотек и просить коннект к нужной при необходимости.

    Теперь рассмотрим различия в работе программ, установленных из deb и snap пакетов. Большинство Linux систем - это discretionary access control (DAC). Вы установили программу А и при запуске её бинарника, в памяти он становится понятием - процесс. При запуске программы от своего имени процесс будет обладать теми правами, которыми обладает наша учётная запись. Если мы можем зайти в папку /share/folder_x/ и прочесть файл secret.txt, то и программа А сможет это сделать. В традиционном мире Linux мы надеемся на порядочность программистов, пишущих софт, и на внимательность сопровождающих пакета, которые пытаются не допустить злоупотреблений, например, отправляя к себе наши файлы.
    Мир snap - это mandatory access control (MAC). При упаковке программы в декларативном виде описывают многие вещи в файле snapcraft.yaml, в том числе к каким интерфейсам должна подключаться программа. Эти желания будут развёрнуты в правила системы мандатного доступа AppArmor и проанализировать их можно по адресу /var/lib/snapd/apparmor/profiles/.
    MAC строже чем DAC. Программа находится в изоляции и может только то что ей разрешено профилем. Запущенная snap программа А не сможет зайти в /share/folder_x/ и прочесть файл secret.txt при всём её желании. После установки программы в виде snap пакета, любой её бинарник не сможет что-либо считать, кроме как из пути /snap/[name]/[version]/.
    К плюсам snap можно отнести то, что при любых изменениях в операционной системе, можно быть уверенным, что программа "не поломается" из-за изменений в библиотеках/фреймворках. Установил раз - работает всегда. Нет проблем при установке и обновлении софта. Всегда свежий софт от разработчика, без промежуточных звеньев в лице сопровождающего. Нет никаких привязок версии софта к версии системы, библиотек, фреймворков и т.д.

    DEB:
    - Программу с её библиотеками представляют в виде множества пакетов, которые зависят друг от друга.
    - Deb пакеты скачивают, распаковывают содержимое, выполняя рихтовочные control скрипты.
    - Программа из пакета deb ничем не ограничена и получает доступ ко всему к чему у вас есть права.
    - В мире deb сложнее осуществляется версионность. Откат к старой версии может быть технически невозможен, ибо в репозитории может отсутствовать старый пакет к этому времени. Процедура понижения версии (downgrade) непроста и редко используется в практике. Атомарность не гарантируется. Все стараются, чтобы при обновлении всё прошло гладко, но не всегда система может быть переведена из одного рабочего состояния в другое.

    SNAP:
    - В snap пакете обычно идёт программа со всем необходимым ей. Иногда тяжёлые фреймворки выносят в отдельный snap и делают к нему connect.
    - Snap пакет скачивают и монтируют в каталог, ничего никуда не распаковывается. Внутри сжатого пакета snap нет каких-либо скриптов, которые вызываются кем бы то нибыло.
    - Программа в snap пакете работает в изоляции. Получает нужное через интерфейсы и не получает какой-либо доступ, даже если у вас есть на это права.
    - Snap пакеты поддерживают атомарность и версионность. Вы можете откатывать софт к версии ранее и пакет или ставится полностью или не ставится совсем, если есть какие-то технические проблемы.
    Ответ написан
    Комментировать