1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/kt10-rocker

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

ROCKER

ROCKER — это реализация «онлайн-распаковки» и процесса «песочницы», предназначенная для использования в системах интернета вещей (IoT), основанных на Linux, с ограниченными ресурсами. Цель проекта — повысить эффективность использования ресурсов и безопасность системы, а также избежать дополнительных потерь производительности.

С помощью сжатия файлов приложений и других подходящих файлов в формат squashfs можно добиться экономии дискового пространства более чем на 60%, что очень важно для систем IoT с ограниченными ресурсами. При этом, поскольку ядро Linux изначально поддерживает динамическое распаковывание по требованию, по сравнению с обычным режимом работы приложений не возникает дополнительных затрат памяти.

Безопасность функций песочницы обеспечивается базовыми средствами Linux, такими как пространства имён Linux namespaces, контрольные группы cgroups, оверлейная файловая система overlayfs, а также язык программирования Rust и многочисленные тестовые примеры. Автор благодарит Линуса Торвальдса, создателя Linux, и команду Rust за эти замечательные базовые инструменты.


1.1. Основные особенности и характеристики

— Более высокая производительность и эффективность использования ресурсов по сравнению с Docker, запуск контейнеров не требует дополнительных образов; — клиентская библиотека разработана на чистом C, без каких-либо зависимостей, кроме libc; — серверная часть (библиотека) разработана на языке Rust, обеспечивая стабильность, сравнимую с C/C++, и высокую эффективность выполнения и использования памяти; — использование инструментальной цепочки crosstool-ng обеспечивает хорошую устойчивость и надёжность; — единый стиль кода, чистота и элегантность; — акцент на документации и тестировании; — дополнительные особенности, рекомендуется изучить исходный код для более глубокого понимания.


1.2. Руководство пользователя

1.2.1. Структура кода (кратко)

Весь проект разделён на две части: клиентскую и серверную. Клиентская часть представлена библиотекой, которая используется вызывающей стороной.

..
├── core/                     # [Rust 代码] 服务端核心逻辑实现
├── rocker_server/            # [Rust 代码] CS server 端实现
├── librocker_client/         # [C    代码] CS client 库实现
├── librocker_client_wrapper/ # [Rust 代码] 通过 ffi 封装的 librocker_client 库, 用于测试
├── tests/                    # [Rust 代码] 测试用例
├── README.md                 # 项目主文档
└── tools/

1.2.2. Конфигурация среды и компиляция

  • Требования к среде:

  • Компиляция: Теоретически проект может быть скомпилирован и запущен на любой архитектуре, поддерживаемой crosstool-ng и Rust. Для платформ, отличных от x86(_x64), по умолчанию используется статическая компоновка библиотек musl или uclibc для упрощения зависимости от среды выполнения.

Пример для TARGET=armv7-linux-musleabihf:

# Компиляция и установка, путь установки находится в корневом каталоге проекта install_dir
make TARGET=armv7-linux-musleabihf release

# Функциональное тестирование
make TARGET=armv7-linux-musleabihf test

# Тестирование производительности
make TARGET=armv7-linux-musleabihf bench

1.2.3. Библиотека клиента

Пример вызова:

// Определяется вызывающей стороной, будет выполняться в ROCKER
void *your_args = NULL;
int start_your_APP(void *args){};

// Инициализация пустого RockerRequest
RockerRequest req = ROCKER_request_new();

// Назначение значений для RockerRequest
req.app_id = 1000;
req.uid = 1000;
req.gid = 1000;
req.app_pkg_path = "/tmp/your_APP.squashfs";
req.app_exec_dir = "/var/your_APP/execdir";
req.app_data_dir = "/var/your_APP/datadir";
req.app_overlay_dirs = { "/usr", "/var", "/etc", "/home", "/root" };

// Попытка запуска приложения в ROCKER
RockerResult res = ROCKER_enter_rocker(&req, start_my_APP, my_args);

if (ROCKER_ERR_success != res.err_no) {
    // Обработка ошибок
}

// Завершение работы приложения, очистка среды
kill(res.guard_pid, SIGKILL);

// Более надёжный метод очистки
RockerResult res2 = ROCKER_get_guardname(res.guard_pid);
if (ROCKER_ERR_success == res2.err_no && \
        0 == strcmp(res.guard_name, res2.guard.name)) {
    kill(res.guard_pid, SIGKILL);
}

Подробности см. в librocker_client. Среда, в которой будет запущено приложение, описывается в разделе 1.3.1.3.

(7) PID of guard\App

После запуска приложения RockerClient возвращает AppMaster PID и другую связанную информацию о Guard и приложении, чтобы AppMaster мог осуществлять последующее управление. На этом RockerClient завершает свою работу во время однократного запуска приложения и больше не участвует в последующих этапах.

(8) stop all; (10) kill

У AppMaster есть два способа остановить приложение: один — это самостоятельное управление согласно обычной логике, а другой — автоматическое завершение через kill RockerGuard.

Оба метода имеют свои преимущества и недостатки:

  • Первый метод позволяет AppMaster более точно контролировать процесс, но очистка среды должна быть обеспечена самостоятельно (см. описание шага 9 ниже);
  • Второй метод использует механизм автоматической очистки ядра через kill RockerGuard, что упрощает логику реализации AppMaster и обеспечивает полную очистку среды, но AppMaster не может настраивать этот процесс очистки.

(9) exit self

RockerGuard автоматически завершает работу, когда все остальные процессы в rocker-виртуальной песочнице завершаются. Если AppMaster пропускает какой-либо процесс, ресурсы этого rocker никогда не будут освобождены.

(11) send SIGCHLD

Когда RockerGuard завершает работу, RockerMaster получает сигнал SIGCHLD и может выполнять некоторые соответствующие внутренние логические операции.

(12) rocker's [PID 1] exited

Ядро обнаруживает выход процесса с номером 1 в определённом пространстве имён pid.

(13) broadcast SIGKILL(auto, very clean); (14) umount overlay; (15) destroy useless loop device

Ядро автоматически очищает все ресурсы (включая производные ресурсы), включая рекурсивное создание.

1.3.2.2. Поддиаграмма {#1}

_

(0) clone(MNT|PID)

RockerMaster создаёт экземпляр RockerGuard с помощью интерфейса clone с флагами CLONE_MNT и CLONE_PID, как описано в man clone(2).

(1) create loop device

RockerGuard вызывает ioctl для получения доступного устройства loop, как указано в man loop(4).

(2) bind App.sqfs to loop; (3) mount loop to exec-path

Приложение упаковывается в формат squashfs и привязывается к новому устройству loop. RockerGuard монтирует устройство loop в путь выполнения, указанный AppMaster.

Создание App.sqfs и процесс привязки и монтирования аналогичны следующей командной строке:


#Упаковать файлы приложения в squashfs, сначала установить инструмент squashfs-tools
mksquashfs ./AppDir ./App.sqfs

#Привязать squashfs к устройству loop
losetup /dev/loop8 ./App.sqfs

#Смонтировать в указанный каталог
mount ./App.sqfs /mnt/AppExecDir

(4) build overlay {#1}

RockerGuard создаёт слой изоляции overlay чтения-записи, подробности описаны в разделе 1.3.1.2.

(5) remount /proc

Перемонтировать /proc, чтобы информация о pid в новом пространстве имён pid отображалась нормально.

(6) unshare(USER)

По завершении вышеуказанных работ RockerGuard переходит в новое пользовательское пространство имён user_namespace через вызов интерфейса unshare. После этого все операции в rocker выполняются в ограниченном пользовательском пространстве имён, как описано в man unshare(2).

(7) done

Подготовка RockerGuard завершена, и уведомление отправляется RockerMaster.

(8) set uid_map

RockerMaster устанавливает uid_map (требуется CAP_SETUID) и gid_map (требуется CAP_SETGID) для RockerGuard. Перед установкой gid_map необходимо записать «deny» в файл /proc/[RockerGuard PID]/setgroups, как описано в user_namespaces(7).

1.3.2.3. Поддиаграмма {#1} {#1}

_

(0) get all visiable top-dir except /proc,/sys,/dev,/run

Пройтись по всем верхним каталогам и исключить динамические каталоги, такие как /proc, /sys, /dev и /run.

(1) top-dir act as 'lowerdir', and finally merged to themself

Все видимые верхние каталоги объединяются в независимые пространства имён mnt_namespace с наложением слоя изоляции overlay, так что каждое приложение имеет независимую читаемую и записываемую виртуальную файловую систему, как описано в документации ядра по overlayfs.

Например, если приложение с идентификатором 1000 монтирует /usr, то предполагается, что его upperdir и workdir — /private/1000/upperdir и /private/1000/workdir соответственно. Процесс монтирования overlay аналогичен следующей командной строке:

mount -t overlay overlay /usr \
    -o lowerdir=/usr,upperdir=/private/1000/upperdir,workdir=/private/1000/workdir

1.3.2.4. Поддиаграмма {#2}

_

(0) rocker created

После подготовки новой среды rocker RockerGuard уведомляет RockerClient.

(1) fork out a child process, (2) setns(USER|MNT|PID)

RockerClient создаёт дочерний процесс, который входит в новую среду rocker через системный интерфейс setns.

(3) run App in child's brother process

В дочернем процессе, созданном на шаге (1), создаётся ещё один дочерний процесс для запуска переднего плана приложения.

Этот новый дочерний процесс фактически является братом дочернего процесса, созданного на шаге (1). Он реализуется через клонирование с флагом CLONE_PARENT, и его родительский процесс совпадает с родительским процессом дочернего процесса на шаге (1). Таким образом, AppMaster может получать сигналы SIGCHLD при завершении процесса приложения, как описано в clone(2).

(4) PID of guard\App

RockerClient отправляет AppMaster информацию о PID RockerGuard и приложения.

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Я создаю `Embed-Docker` на Rust! Развернуть Свернуть
MIT
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/kt10-rocker.git
git@api.gitlife.ru:oschina-mirror/kt10-rocker.git
oschina-mirror
kt10-rocker
kt10-rocker
master