Только для чтения контейнеры

Тема дорожной карты · Docker & Containers

Запуск контейнера с docker run --read-only делает корневую файловую систему (ФС) неизменяемой и защищает от модификации файлов в рантайме. Это важный шаг к обеспечению безопасности и стабильности приложений, запущенных в контейнерах. Для путей, куда легитимно нужно писать (кеши, сокеты, логи), добавляйте --tmpfs /tmp или именованные volumes. Это позволяет изолировать приложение от изменений в корневой ФС и предотвращает случайные или намеренные изменения конфигурации или данных приложения.

Частые ошибки при работе с только для чтения контейнерами включают следующее: многие образы пишут в /var/run, /tmp или специфичные для приложения каталоги и без writable-mount упадут; некоторые пакетные менеджеры требуют записи во время entrypoint. Эти ошибки могут привести к непредсказуемому поведению приложения или его отказу. Продвинутая схема использования только для чтения контейнеров включает применение --read-only вместе с --cap-drop=ALL, профилем seccomp и непривилегированным USER. Это обеспечивает более высокий уровень изоляции и безопасности.

Как это работает

Только для чтения контейнеры имеют несколько слоёв безопасности: контент образа (включая CVE в базовых, коде, зависимостях), процесс сборки (недоверенные RUN, утечка секретов), runtime (root внутри, capabilities, seccomp, AppArmor/SELinux), хост (обновления ядра, экспозиция daemon-сокета). Hardening начинается с минимального базового образа (например, distroless, alpine, scratch), запуска не-root (USER 10000:10000), сброса capabilities (--cap-drop ALL --cap-add NET_BIND_SERVICE). Эти меры обеспечивают базовую безопасность и изоляцию приложения от системы.

Когда применять

Применяйте security-baseline с первого дня — ретрофит болезненный. Сканируйте образы каждый CI через Trivy или Grype, валите билды на CRITICAL CVE. read-only корневая ФС везде, где приложение позволяет. Никогда не монтируйте Docker daemon socket в контейнер, кроме явно изолированного CI-раннера. Для multi-нагрузки нагрузок — sandbox ещё глубже (gVisor, Kata Containers); ванильных namespaces мало.

Типичные ошибки

Ловушки Только для чтения контейнеры: всё под root внутри контейнера ("контейнер же изолирован" — до kernel-CVE или docker.sock); игнор CVE "у нас этот эндпойнт не открыт" (defence-in-depth — чините всё равно); --privileged, чтобы какая-то библиотека заработала (это kernel-level root); API-ключи через ENV (живут в history). Аудит образов раз в квартал, даже если код приложения не меняется.

Связанные понятия

Полезные ресурсы