На чём строится изоляция докера
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Архитектура изоляции в Docker: на чём она строится
Изоляция в Docker — это не единая технология, а многоуровневая комбинация механизмов операционной системы Linux (или Windows), которые совместно создают "лёгкие" контейнеры. В отличие от виртуальных машин с аппаратной виртуализацией, контейнеры делят ядро хоста, что делает их значительно более эффективными по ресурсам и скорости запуска.
Ключевые технологии-основы
1. Пространства имён (Linux Namespaces)
Это фундаментальный механизм ядра Linux для изоляции и виртуализации системных ресурсов. Каждый контейнер получает свой собственный набор пространств имён, что создаёт иллюзию выделенной ОС. Основные типы:
- PID (Process): Изолирует дерево процессов. Процессы в контейнере видят только свои PID, начинающиеся с 1 (
initпроцесса контейнера). На хосте они имеют обычные PID. - Network (
net): Предоставляет контейнеру собственный стек сетевых интерфейсов, таблицы маршрутизации, правилаiptables/nftables. Это основа для сетевых драйверов Docker (bridge,host,overlay). - Mount (
mnt): Изолирует точки монтирования файловой системы. Контейнер видит собственный корень (/) и не имеет доступа к смонтированным на хосте файлам, если это явно не разрешено. - UTS (Unix Time Sharing): Позволяет контейнеру иметь собственное имя хоста (
hostname) и домена (domainname), независимое от хостового. - IPC (Inter-Process Communication): Изолирует механизмы межпроцессного взаимодействия (очереди сообщений, сегменты разделяемой памяти, семафоры).
- User (
user): Отделяет таблицу идентификаторов пользователей и групп. Позволяет отображатьrootвнутри контейнера в непривилегированного пользователя на хосте (техника rootless containers), значительно повышая безопасность.
Эти пространства создаются при старте контейнера. Наглядно разницу PID namespace можно увидеть так:
# Запускаем контейнер с изолированным процессом sleep
docker run -d --name test-isolation alpine sleep 3600
# Смотрим процессы ВНУТРИ контейнера (его PID namespace)
docker exec test-isolation ps aux
# Будет виден процесс sleep с PID=1 (или близким к 1)
# Смотрим процессы СНАРУЖИ, на хосте (глобальный PID namespace)
ps aux | grep sleep
# Будет виден процесс с обычным, большим PID (например, 12345)
2. Группы управления ресурсами (Control Groups - cgroups)
Если пространства имён отделяют ресурсы, то cgroups их ограничивают и учливают. Это механизм ядра для ограничения, учёта и изоляции потребления ресурсов (CPU, память, диск I/O, сеть) группой процессов.
- Ограничение (
limiting): Задаёт жёсткие лимиты. Например, контейнер не сможет использовать более 512 МБ RAM. - Приоритезация (
prioritization): Распределяет ресурсы между контейнерами. Например, гарантирует 50% CPU time или устанавливает веса (cpu.shares). - Учёт (
accounting): Измеряет потребление ресурсов, что используется для мониторинга и биллинга. - Управление (
control): Позволяет заморозить (freeze), перезапустить или завершить группу процессов.
Пример файловой иерархии cgroup v2 для ограничения памяти контейнера:
# Docker автоматически создаёт cgroup для каждого контейнера
# Путь обычно: /sys/fs/cgroup/<подсистема>/docker/<container-id>/
# Чтение текущего использования памяти контейнера
cat /sys/fs/cgroup/memory/docker/<container-id>/memory.usage_in_bytes
# Установка лимита памяти (это делает Docker Engine через API runc)
echo "536870912" > /sys/fs/cgroup/memory/docker/<container-id>/memory.limit_in_bytes # 512 МБ
3. Объединённая файловая система (Union File System)
Она обеспечивает изоляцию на уровне файлов. Основные принципы:
- Слои (Layers): Каждая инструкция в
Dockerfile(RUN,COPY,ADD) создаёт неизменяемый слой. Контейнер — это тонкий записываемый слой поверх этих слоёв-образов. - Copy-on-Write (CoW): Все слои доступны только для чтения. При попытке модификации файла из нижнего слоя, система копирует его в верхний, записываемый слой контейнера. Это обеспечивает эффективное использование диска и быстрый запуск множества контейнеров от одного базового образа.
- Драйверы хранения: Docker использует плагинируемые драйверы (
overlay2(рекомендуемый),aufs,devicemapper,zfs), которые реализуют UnionFS на практике.
Сборка "пазла": как Docker это использует
Docker Engine выступает как высокоуровневый оркестратор этих низкоуровневых механизмов. Последовательность при запуске контейнера примерно такова:
- CLI передаёт команду
docker runDocker Daemon. - Daemon подготавливает образ (UnionFS слои) и запрашивает создание контейнера у runc (реализация OCI Runtime Specification).
runcвызывает системный вызовclone()(илиunshare()) с флагамиCLONE_NEWPID | CLONE_NEWNET | CLONE_NEWNS | ..., создавая новое пространство имён.- Процесс помещается в новую cgroup, где для него устанавливаются заданные лимиты ресурсов.
- Монтируется корневая файловая система контейнера с использованием драйвера UnionFS (
overlay2). - Запускается процесс-точка входа (например,
/bin/bash), который уже работает в полностью изолированном окружении.
Важные нюансы и эволюция
- Неполная изоляция: Контейнеры делят ядро хоста. Уязвимость в ядре может скомпрометировать все контейнеры, в отличие от ВМ. Критически важные приложения могут требовать дополнительной изоляции через Kata Containers, gVisor или аппаратные ВМ.
- Безопасность: Базовые пространства имён и cgroups — не silver bullet. Для усиления безопасности применяются профили Seccomp (фильтрация системных вызовов), AppArmor/SELinux (Мандатный контроль доступа), Capabilities (дробление привилегий root) и Rootless-режим.
- cgroups v2: Современные дистрибутивы переходят на cgroups v2, который предлагает единую иерархию, улучшенное управление ресурсами (особенно для CPU и I/O) и лучшую безопасность. Docker и Kubernetes уже полностью поддерживают v2.
Итог: Изоляция Docker строится на мощном фундаменте ядра Linux: пространствах имён для виртуализации представления о системе, cgroups для контроля ресурсов и UnionFS для эффективного управления файлами. Docker (через containerd и runc) грамотно оркестрирует эти механизмы, предоставляя простой API для создания переносимых, плотно упакованных и достаточно изолированных единиц развёртывания — контейнеров.