Gymterview
middle

Зачем и как использовать read-only файловую систему в контейнерах?

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

Аналогия: read-only ФС – как стеклянная витрина в музее. Экспонаты (файлы приложения) можно смотреть, но нельзя трогать. Если атакующий проникнет в контейнер, он не сможет ничего изменить или подложить.

В Docker

Пример
# Запуск с read-only ФС
docker run --read-only \
    --tmpfs /tmp:rw,noexec,nosuid,size=100m \
    --tmpfs /var/cache:rw,noexec,nosuid \
    my-java-app

Флаги tmpfs:

Флаг Назначение
rw Разрешить запись (только в tmpfs)
noexec Запретить выполнение файлов из этой директории
nosuid Игнорировать setuid-бит
size=100m Ограничение размера

В Kubernetes

Полный манифест с read-only ФС и необходимыми volume
apiVersion: v1
kind: Pod
metadata:
  name: banking-service
spec:
  containers:
  - name: app
    image: registry.bank.local/banking-service:1.0.0
    securityContext:
      readOnlyRootFilesystem: true
    volumeMounts:
    # Java нуждается в /tmp для временных файлов
    - name: tmp-volume
      mountPath: /tmp
    # Логи приложения
    - name: logs-volume
      mountPath: /app/logs
    # Spring Boot может создавать temporary файлы
    - name: spring-tmp
      mountPath: /app/BOOT-INF/tmp
  volumes:
  - name: tmp-volume
    emptyDir:
      medium: Memory    # Хранить в RAM (как tmpfs)
      sizeLimit: 100Mi
  - name: logs-volume
    emptyDir:
      sizeLimit: 500Mi
  - name: spring-tmp
    emptyDir:
      medium: Memory
      sizeLimit: 50Mi

Типичные директории, требующие записи для Java-приложений

Директория Зачем нужна Рекомендация
/tmp Временные файлы JVM, Tomcat emptyDir с medium: Memory
/app/logs Логи приложения emptyDir или PVC
/var/cache Кэш HTTP-клиентов emptyDir
/home/appuser/.java Preferences API emptyDir

Dockerfile с учётом read-only ФС

Пример
FROM eclipse-temurin:21-jre-alpine

RUN addgroup -S app && adduser -S app -G app && \
    mkdir -p /app /tmp && \
    chown -R app:app /app /tmp

WORKDIR /app
COPY --chown=app:app target/service.jar /app/app.jar

USER app

# Указать Java использовать /tmp для временных файлов
ENTRYPOINT ["java", "-Djava.io.tmpdir=/tmp", "-jar", "/app/app.jar"]

Вывод

Read-only файловая система – простая, но мощная мера защиты. Она гарантирует иммутабельность контейнера: то, что было собрано на этапе build, нельзя изменить в runtime. Для Java-приложений необходимо явно монтировать writable-директории (/tmp, /app/logs) через emptyDir или tmpfs.

На собеседовании: упомяните readOnlyRootFilesystem: true и объясните, что Java-приложению нужен writable /tmp (для JVM и Tomcat). Покажите знание флагов noexec и nosuid для tmpfs – это демонстрирует глубокое понимание.