← Назад к вопросам

Что используется внутри Docker-контейнера

1.3 Junior🔥 101 комментариев
#Docker и контейнеризация

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

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Краткий ответ

Внутри Docker-контейнера используется изолированное пользовательское пространство (user space) операционной системы, включающее:

  • Процессы, запущенные от одного PID 1.
  • Файловая система, смонтированная из образа и, опционально, томов.
  • Сетевое пространство (интерфейсы, правила iptables, routing table).
  • Изолированные ресурсы (процессор, память, устройства), ограниченные cgroups.
  • Переменные окружения и аргументы, переданные при запуске.

Однако контейнер разделяет ядро (kernel) хост-системы с другими контейнерами и самой хост-ОС. Это ключевое отличие от виртуальной машины.

Детальное объяснение: архитектура и компоненты

Контейнер — это не виртуальная машина. Это изолированный процесс (или группа процессов) в операционной системе Linux. Его изоляция обеспечивается двумя основными технологиями ядра Linux: namespaces и cgroups.

1. Пространства имён (Linux Namespaces)

Namespaces обеспечивают изоляцию глобальных системных ресурсов, создавая для процессов внутри контейнера иллюзию, что они имеют собственную, уникальную копию этих ресурсов. Основные типы namespaces, используемые в Docker:

  • PID namespace: Изолирует дерево процессов. Процесс внутри контейнера видит только свои процессы и начинает нумерацию с PID 1 (обычно это ENTRYPOINT или CMD образа).
    # Внутри контейнера
    ps aux
    # Покажет только процессы контейнера
    
  • Mount namespace: Изолирует точки монтирования. Контейнер видит свою собственную файловую систему, собранную из слоёв образа.
  • Network namespace: Изолирует сетевые стеки (сетевые интерфейсы, IP-адреса, таблицы маршрутизации, порты). Каждый контейнер получает свой виртуальный сетевой интерфейс (например, eth0).
  • UTS namespace: Изолирует hostname и domain name. Контейнер может иметь своё собственное имя хоста, отличное от хостового.
  • IPC namespace: Изолирует ресурсы межпроцессного взаимодействия (POSIX message queues, shared memory).
  • User namespace: (опционально, требует настройки) Изолирует пространство UID/GID. Пользователь с UID 0 (root) внутри контейнера может быть отображён на непривилегированного пользователя на хосте, что повышает безопасность.

2. Группы управления (Control Groups - cgroups)

Cgroups ограничивают, учитывают и изолируют использование физических ресурсов группы процессов (контейнера).

  • Ограничение ресурсов: Можно установить лимиты на CPU, память (RAM и swap), дисковый I/O, сетевую пропускную способность.
  • Учёт ресурсов: Мониторинг потребления ресурсов контейнером.
  • Приоритизация: Задание относительных приоритетов (cpu.shares) для доступа к CPU.

Пример создания контейнера с ограничением памяти:

docker run -it --memory="512m" --cpus="1.5" ubuntu:latest /bin/bash

Эта команда запустит контейнер с лимитом в 512 МБ оперативной памяти и 1.5 ядра CPU.

3. Файловая система контейнера: Union File System и слои (Layers)

Файловая система внутри контейнера — это не монолит, а набор только для чтения (read-only) слоёв и одного верхнего слоя для записи (read-write layer).

  • Каждая инструкция в Dockerfile (RUN, COPY, ADD) создаёт новый слой.
  • Слои кэшируются и используются совместно разными образами и контейнерами, что экономит место и ускоряет сборку.
  • При запуске контейнера поверх слоёв образа создаётся тонкий слой для записи. Все изменения файловой системы (создание, модификация, удаление файлов) происходят в этом слое. При удалении контейнера этот слой также удаляется (если не используется том).

Посмотреть слои образа можно командой:

docker image history <image_name>

4. Сетевой стек

По умолчанию Docker создаёт для контейнера виртуальный сетевой интерфейс и подключает его к виртуальному мосту (docker0), выступая в роли сетевого шлюза. Доступны различные драйверы сетей:

  • bridge (дефолтный): Изолированная внутренняя сеть.
  • host: Контейнер использует сетевой стек хоста напрямую (теряется сетевая изоляция namespaces).
  • overlay: Для связи контейнеров на разных хостах (в Swarm/кластере).
  • macvlan: Назначение контейнеру реального MAC-адреса, чтобы он выглядел как физическое устройство в сети.
  • none: Полное отключение сети.

5. Процесс инициализации

Внутри контейнера должен работать хотя бы один процесс. По умолчанию это процесс, указанный в CMD или ENTRYPOINT Docker-образа. Важно: этот процесс должен работать на переднем плане (foreground). Если он завершится — завершится и весь контейнер. PID этого процесса внутри контейнера будет равен 1, и он берёт на себя некоторые специальные обязанности (например, перехват и обработка сигналов SIGTERM).

Итог и аналогия

Представьте многоквартирный дом (хост-сервер):

  • Ядро ОС — это фундамент, несущие стены и коммуникации дома. Единственные для всех.
  • Каждая квартира — это контейнер.
  • Namespaces — это стены и двери квартиры. Они изолируют жильцов друг от друга (вы не видите соседей за стеной и не пользуетесь их туалетом).
  • Cgroups — это счётчики и лимиты на воду, электричество, газ для каждой квартиры.
  • Файловые слои — это типовые планировки и ремонт. Чистовая отделка (слой для записи) у каждой квартиры своя, а черновая отделка, стены и перекрытия (слои образа) — общие.

Таким образом, внутри Docker-контейнера работает стандартное приложение (например, веб-сервер Nginx) со всеми его зависимостями (библиотеками, файлами конфигурации), но в условиях контролируемой изоляции, созданной средствами ядра Linux. Эта модель обеспечивает высокую плотность размещения, скорость запуска и переносимость приложений между средами.