Компания Oracle представила три новых открытых проекта, связанных с изолированными контейнерами: smith, crashcart и railcar. Примечательно, что первое приложение написано на языке Go, а два остальных на Rust. Код поставляется под двойной лицензией: UPL (Universal Permissive License) и Apache 2.0.
Smith позволяет собирать контейнеры в формате OCI (Open Container Image) и нацелен на сопровождение процесса сборки компактных окружений, включающих только компоненты, необходимые для работы запускаемого в контейнере приложения. Работа над Smith началась два года назад как попытка решения проблем со стабильностью и безопасностью процессов сборки контейнеров, с которыми инженеры Oracle столкнулись при построении облачных сервисов при помощи Docker.
Среди проблем, которые попытались решить разработчики Smith выделяются (проблемы были актуальны два года назад при принятии решения о создании Smith и сейчас многие из них уже решены в Docker):
- Раздутый размер образов из-за включения большой порции лишних компонентов;
- Недостаточное внимание вопросам обеспечения безопасности, из-за чего в Docker периодически всплывали уязвимости, позволяющие повысить свои привилегии при получении контроля за запускаемым в контейнере приложением;
- Отсутствие контроля за версиями зависимостей и средств для определения необходимости обновления содержимого, что приводило к появлению уязвимостей из-за необновлённых вовремя компонентов;
- Отсутствие средств для создания многослойных контейнеров, дающих возможность обойтись без полной пересборки образа при запуске новой версии приложения;
- Отсутствие средств для запуска каждого контейнера в отдельном собственном пространстве имён идентификаторов пользователя (user namespace);
- Отсутствие поддержки Overlayfs для запуска нескольких разных контейнеров из одного образа;
- Отсутствие репозитория для распространения образов по узлам.
В Smith воплощена идея микроконтейнеров, как способа формирования содержимого, обеспечивающего минимальный размер, более высокую стабильность и безопасность. Микроконтейнер содержит только один исполняемый файл и связанные с ним зависимости (без shell и init-процесса), выполнятся с корневой ФС в режиме только для чтения (запись доступна только в отдельно монтируемые разделы), все файлы в контейнере принадлежат одному пользователю (не применяется разделение на группы и пользователей).
Обеспечена поддержка повторяемых сборок при которых образы, собранные в разное время над одним и тем же набором пакетов, совпадают бит в бит. В микроконтейнерах также принято соглашение о размещении всех временных файлов, таких как pid-файлы, в каталоге /run, всех логов и данных в каталоге /write, привязанных к контейнеру файлов конфигурации в каталоге /read (не изменяемый из контейнера но доступный для configmap в kubernetes или внешнего монтирования на запись).
Smith осуществляет сборку в стандартном формате OCI, который может быть загружен в репозитории Docker и запущен с его помощью. Предусмотрена как возможность сборки на базе набора rpm-пакетов и репозиториев yum, так и функция минимизации существующих oci-образов для системы Docker. В процессе сборки smith отслеживает цепочку зависимостей и автоматически включает в образ библиотеки, только действительно используемые исполняемым файлом. По сравнению с другими системами сборки контейнеров одного приложения, smith позволяет формировать контейнеры до 10 раз меньшего размера.
Инструментарий для сборки дополняют две утилиты:
- Crashcart - позволяет по мере возникновения необходимости загружать в работающий контейнер дополнительные исполняемые файлы и библиотеки в процессе отладки микроконтейнеров и диагностики проблем, связанных отсутствием в контейнере компонентов, вызываемых в процессе работы приложения. В том числе при помощи crashcart можно запустить в контейнере /bin/bash для исполнении команды "docker exec";
- Railcar - реализация runtime-компонентов для запуска контейнеров, определённых в спецификации oci-runtime, написанная на языке Rust и позиционируемая в качестве альтернативы containerd/runc. Язык Rust выбран так как он предоставляет возможности низкоуровневого доступа в сочетании со средствами безопасной работы с памятью, позволяющими избежать многих уязвимостей. В предлагаемом в Docker по умолчанию runtime runc, написанном на языке Go, для настройки пространств имён приходится применять обвязку на языке Си (в Go мешает сборщик мусора и отсутствие средств низкоуровневого управления потоками), которая запускается до старта основного runtime на языке Go и не использует средства безопасного программирования. Из плюсов Railcar по сравнению с runc также отмечается очень быстрый запуск контейнера (контейнер запускается за 10ms, при том, что runc только 150ms тратит на ожидание блокировок).
|