Hacker News Digest

13 сентября 2025 г. в 14:37 • labs.iximiuz.com • ⭐ 160 • 💬 27

OriginalHN

#docker

How Container Filesystem Works: Building a Docker-Like Container from Scratch

Как работает файловая система контейнеров: создание Docker-подобного контейнера с нуля

Одна из суперспособностей контейнеров — их изолированное представление файловой системы. Изнутри контейнера она может выглядеть как полноценный дистрибутив Linux, часто отличающийся от хостового. Запустите docker run nginx, и Nginx окажется в своём привычном пользовательском пространстве Debian независимо от того, какую версию Linux использует хост. Но как создаётся эта иллюзия?

В этой статье мы соберём небольшой, но реалистичный Docker-подобный контейнер, используя только стандартные инструменты Linux: unshare, mount и pivot_root. Без магии рантайма и (почти) без упрощений. По пути вы узнаете, почему пространство имён монтирования — это основа изоляции контейнеров, в то время как другие пространства имён, такие как PID, cgroup, UTS и даже сетевое, играют скорее вспомогательную роль.

К концу — особенно если совместить это с руководством по сетям контейнеров — вы сможете запускать полнофункциональные Docker-подобные контейнеры, используя только стандартные команды Linux. Это конечная цель каждого aspiring container guru.

Предварительные требования

  • Базовое знакомство с Docker (или Podman и подобными) контейнерами
  • Основные знания Linux (скрипты shell, общее понимание пространств имён)
  • Фундаментальные принципы файловых систем (единая иерархия каталогов, таблица монтирования, bind mount и т.д.)

Визуализация конечного результата

На диаграмме ниже показано, как выглядит изоляция файловой системы при создании Docker нового контейнера. Нормально, если рисунок кажется сложным. С помощью практических упражнений в этом руководстве мы построим комплексную ментальную модель работы контейнеров, так что когда мы вернёмся к диаграмме в заключительном разделе, она будет выглядеть гораздо понятнее.

Кликните для увеличения

Что именно изолирует Mount Namespace?

Проведём быстрый эксперимент. В Терминале 1 запустим новую сессию shell в собственном пространстве имён монтирования:

sudo unshare --mount bash

Теперь в Терминале 2 создадим файл где-нибудь в файловой системе хоста:

echo "Hello from host's mount namespace" | sudo tee /opt/marker.txt

Удивительно или нет, но при попытке найти этот файл в новом пространстве имён монтирования с помощью Терминала 1 он окажется там:

cat /opt/marker.txt

Так что же мы изолировали с помощью unshare --mount? 🤔

Ответ — таблицу монтирования. Вот как это проверить. Из Терминала 1 смонтируем что-нибудь:

sudo mount --bind /tmp /mnt

💡 Эта команда использует bind mount для простоты, но подойдёт и обычное монтирование (блочного устройства).

Теперь, если вывести содержимое папки /mnt в Терминале 1, должны отобразиться файлы из /tmp:

ls -l /mnt

Но в то же время папка /mnt осталась пустой в пространстве имён монтирования хоста. Если запустить ту же команду ls из Терминала 2, файлов не будет:

ls -lah /mnt

Наконец, «представления» файловой системы начали расходиться между пространствами имён. Однако мы смогли достичь этого только создав новую точку монтирования.

Пространства имён монтирования, визуализировано

Из man страницы mount namespace:

Пространства имён монтирования обеспечивают изоляцию списка монтирований, видимых процессами в каждом экземпляре пространства имён. Таким образом, процессы в каждом из экземпляров пространства имён монтирования будут видеть distinct single directory hierarchies.

Сравните таблицы монтирования, запустив findmnt из Терминала 1 и Терминала 2:

Пространство имён хоста
Новое пространство имён