Как использовать rsync для установки владельца удаленных файлов на userid внутри контейнера rootless Podman/Docker?

Вопрос или проблема

rsync поддерживает --chown, но вам нужно что-то вроде podman unshare, чтобы правильно работать с subuid. Как я могу их объединить (на удаленном хосте) ?

Я разобрался в этом, и так как я не нашел ничего подобного при поиске, решил сам ответить на этот вопрос для будущих искателей.

Суммирую:

rsync --rsync-path="podman unshare rsync" -zav --delete-during --chown 33:33 /src remote-server:/dst

Объяснение: --rsync-path, изначально предназначенный для указания местоположения исполняемого файла rsync, может выполнять произвольные команды (и часто используется для выполнения sudo на удаленном сервере). Запуская rsync ‘внутри’ podman unshare, предоставленный аргумент для --chown интерпретируется в сопоставленном пространстве имен пользователя, так что вместо установки файлов с идентификаторами хоста 33:33, это происходит в сопоставленном пространстве имен, в результате чего файлы принадлежат пользователю с высоким идентификатором на хосте (1345216:1345216, например, для меня) и указанному пользователю 33:33 внутри контейнера:

$ sudo ls -alsh /mnt/data
total 648K
4.0K drwxrwx---.   17   1345216   1345216 4.0K Mar 10 16:12 .
4.0K drwxrwx---.    7   root      root    4.0K Mar 10 17:19 ..
 16K drwxrwx---.  456   1345216   1345216  12K Mar 11 08:35 stuff

$ podman run --rm -it -v /mnt/data:/data:ro alpine ls -alsh /data
total 644K   
   4.0K drwxrwx---   17 33       33          4.0K Mar 10 15:12 .
      0 dr-xr-xr-x    1 root     root          40 Mar 12 14:14 ..
  16.0K drwxrwx---  456 33       33         12.0K Mar 11 07:35 stuff

Кроме того, у меня была дополнительная трудность: пользователь, которому должны принадлежать файлы, был не моим пользователем, а другим, которому не было разрешено удаленное подключение, поэтому вот команда выше с дополнительными командами, необходимыми для ‘передачи’ файлов пользователю внутри пространства имен другого пользователя:

rsync --rsync-path="cd /tmp && sudo --user=target-user podman unshare rsync" -zav --delete-during --chown 33:33 /src remote-server:/dst

Дополнительные параметры здесь сводятся к добавлению sudo --user=target-user ..., но так как rsync запускается в домашней директории пользователя, инициирующего подключение, дополнительно нужен cd, чтобы избежать ошибки rsync, связанной с невозможностью чтения . после sudo.

Надеюсь, кому-то это будет полезно в будущем.

Ответ или решение

Использование rsync для установки владельца файлов на удалённом сервере на определённый userid внутри контейнера Podman или Docker с режимом без root (rootless) требует понимания как работы с user namespace, так и надлежащей интеграции с инструментами контейнеризации. Давайте подробнее разберём, как это можно реализовать, учитывая контекст предоставленной задачи.

Теория

Инструмент rsync является мощным средством для синхронизации файлов между различными системами. Одной из его ключевых функций является способность изменять владельца файлов при копировании, что достигается с помощью флага --chown. Обычно, назначение владельца файлов требует прав суперпользователя, однако в контексте контейнеров с rootless режимом, это делается в рамках изолированного пространства (namespace) пользователями.

Rootless режим в Podman или Docker позволяет запускать контейнеры без привилегий суперпользователя, используя подмену идентификаторов пользователей (User Namespace Remapping). Это означает, что внутри контейнера стандартный пользователь, например с UID 0 (который обыкновенно ассоциируется с root), может быть сопоставлен с обычным пользователем с высоким UID на хосте. Это сопоставление осуществляется через суб-идентификаторы (subuid, subgid).

Пример

Допустим, вы хотите синхронизировать файлы из директории /src на локальном сервере в директорию /dst на удалённом сервере, и хотите, чтобы файлы имели определённый uid и gid внутри контейнера, которые в маппинге упоминаются как 33:33. Используя podman unshare, можно выполнить rsync в контексте user namespace, где предоставленные аргументы --chown будут интерпретированы правильно.

Команда, реализующая эту задачу, выглядит следующим образом:

rsync --rsync-path="podman unshare rsync" -zav --delete-during --chown 33:33 /src remote-server:/dst

Применение

  1. –rsync-path: Этот параметр rsync позволяет указать путь к его исполняемому файлу на удалённом сервере. Однако его можно использовать и для выполнения более сложных сценариев, включая запуск команд в контексте специфических пространств пользователей. Когда передаётся podman unshare rsync, мы принуждаем запуск rsync в контексте User Namespace, управляемого Podman.

  2. –chown: Параметр --chown 33:33 указывает rsync изменить владельца и группу синхронизируемых файлов на указанные UID и GID внутри user namespace. Внешне на уровне хостов они будут отображаться как высокие идентификаторы (например, 1345216:1345216), но внутри контейнера эти идентификаторы соответствуют ожидаемым 33:33.

  3. sudo –user: Если возникает необходимость выполнять rsync от имени другого пользователя, который не имеет доступа к удалённому серверу напрямую, можно использовать sudo для изменения пользователя в команде:

rsync --rsync-path="cd /tmp && sudo --user=target-user podman unshare rsync" -zav --delete-during --chown 33:33 /src remote-server:/dst

Здесь важно отметить использование cd /tmp, чтобы избежать ошибок доступа, поскольку по умолчанию rsync стартует в домашней директории пользователя.

Заключение

Этот сценарий подчёркивает важность учёта всех деталей при работе с контейнеризацией и синхронизацией данных. В мире DevOps и контейнеризации знание, как правильно сопоставлять и управлять пользовательскими пространствами с помощью инструментов вроде Podman и Docker, может значимо повысить эффективность работы и безопасность окружающей инфраструктуры. Прямое взаимодействие с rootless контейнерами через подобные механизмы не только способствует безопасности, убирая необходимость в superuser прав, но также добавляет гибкости в управлении распределёнными приложениями и их зависимостями.

Оцените материал
Добавить комментарий

Капча загружается...