Введение
Сервис отчётов должен читать конфигурацию и записывать документы, однако его монтирование конфигурации разрешает и запись. Вы обслуживаете сервис и сокращаете ненужный доступ, сохраняя создание отчётов.
Сначала создайте обычный отчёт, затем защитите входное монтирование и пересоздайте только контейнер отчётов. Достаточно базовых навыков терминала; Docker, синтаксис монтирований и редактирование объясняются перед использованием.
Создание обычного отчёта
На этом шаге выполните обычную бизнес-задачу сервиса до изменения прав. Harbor Books использует небольшой сервис, суммирующий заказы и создающий документ. Все клиенты и числа — синтетические учебные данные.
Используйте терминал Maintenance: это роль обслуживания Linux-хоста с доступом к управлению Docker. Docker запускает процессы приложения в контейнерах: каждый видит свою файловую систему и список процессов, но использует общее ядро хоста. Контейнер — не отдельная VM. Управляйте только report-renderer и файлами в /home/labex/project/report-desk.
Терминал открывается в этом каталоге. pwd выводит текущий каталог:
pwd
Ожидается /home/labex/project/report-desk. Если вы переходили в другой каталог, вернитесь через cd /home/labex/project/report-desk.
Приложение слушает порт 8090. Порт обозначает сервис; здесь localhost — хост обслуживания, порт которого Docker перенаправляет в контейнер. curl отправляет HTTP-запрос, -X POST выбирает запрос действия, а -fsS показывает ошибки, сохраняя краткий успешный вывод. Запросите исходный документ:
curl -fsS -X POST http://localhost:8090/render/baseline
{"saved": "/output/baseline.json", "total": 37, "uid": 0}
Сервис прочитал входные данные и сохранил настоящий файл. cat показывает содержимое; хост видит /output контейнера как локальный каталог output:
cat output/baseline.json
Найдите Report for Harbor Books: 37 orders. Остальные поля фиксируют входные данные и экземпляр сервиса. Откройте Document Desk и обновите страницу: под Stored documents появится baseline.json. Страница перечисляет реальные файлы, но не подтверждает безопасность прав.
Защита описания входного монтирования
На этом шаге сопоставьте входные и выходные пути, продемонстрируйте ненужную запись и измените описание запуска. Bind-монтирование соединяет каталог хоста с путём внутри контейнера. Без явного ограничения оно доступно для записи.
cat launch.sh показывает подготовленный Bash-скрипт запуска:
cat launch.sh
Обратная косая черта продолжает команду на следующей строке. sudo управляет Docker с правами администратора хоста, но не определяет пользователя приложения. docker run -d запускает контейнер в фоне, --name задаёт имя, --user 0:0 выбирает идентификаторы пользователя и группы, а -p 8090:8090 перенаправляет порт хоста в порт контейнера. Последний аргумент — подготовленный образ c12-renderer:1.
Поля каждого --mount разделены запятыми: type=bind подключает путь хоста, src задаёт этот путь, dst — путь контейнера.
| Каталог хоста | Каталог контейнера | Нужный доступ |
|---|---|---|
report-desk/config |
/config |
Чтение пакета и шаблона |
report-desk/output |
/output |
Запись готовых документов |
В конфигурации есть probe.txt, одноразовый образец без бизнес-данных. docker exec выполняет команду внутри указанного работающего контейнера. touch обновляет метку времени образца; это намеренная демонстрация ненужного доступа приложения:
sudo docker exec report-renderer touch /config/probe.txt
Отсутствие вывода означает успех. Так вы проверяете запись в монтирование, не повреждая пакет и шаблон. Изменение описания запуска на хосте влияет на следующий созданный Docker контейнер; редактирование файла внутри текущего контейнера не меняет режим его монтирования.
Используйте терминальный редактор nano:
nano launch.sh
Перемещайтесь стрелками. В строке с dst=/config добавьте ,readonly сразу после /config, перед пробелом и обратной косой чертой. Сохраните запись в /output. Сохраните файл через Ctrl+O, Enter, выйдите через Ctrl+X. Строка конфигурации должна стать такой:
--mount type=bind,src=/home/labex/project/report-desk/config,dst=/config,readonly \
Снова выполните cat launch.sh, проверяя пропущенные запятые и обратные косые черты. Ошибки исправляются повторным открытием nano launch.sh. Работающий контейнер пока использует старое монтирование; следующий шаг заменит его.
Применение и проверка границы монтирования
На этом шаге замените только контейнер отчётов и докажите совместимость запрета записи во входные данные с работающим выводом. Изменение скрипта запуска не обновляет существующий контейнер.
docker rm -f останавливает и удаляет названный контейнер. Каталоги хоста, подключённые bind-монтированием, сохраняются. bash launch.sh выполняет изменённое описание:
sudo docker rm -f report-renderer
bash launch.sh
Вторая команда выводит новый ID контейнера. Дайте сервису немного времени на запуск. При ошибке синтаксиса или монтирования исправьте строку через nano launch.sh, удалите новый report-renderer той же командой удаления и снова запустите скрипт. Не удаляйте каталоги данных хоста.
docker inspect читает фактические настройки. --format выбирает поле; сохраните одинарные кавычки, чтобы оболочка передала фигурные скобки без изменений:
sudo docker inspect report-renderer --format '{{json .Mounts}}'
Найдите "Destination":"/config" с "RW":false, а /output — с "RW":true. RW означает чтение/запись. Подтвердите реальную границу тем же одноразовым образцом:
sudo docker exec report-renderer touch /config/probe.txt
touch: /config/probe.txt: Read-only file system
Ненулевой код завершения ожидаем. Терминал остаётся доступен; переходите к следующей команде. Ошибка соединения или отсутствующий контейнер — другая проблема: нужно исправить или повторно запустить скрипт.
Запросите новый документ у пересозданного сервиса:
curl -fsS -X POST http://localhost:8090/render/final
{"saved": "/output/final.json", "total": 37, "uid": 0}
cat output/final.json
В документе по-прежнему есть Report for Harbor Books: 37 orders. Обновите Document Desk, чтобы увидеть final.json. Сервис читает входные данные и записывает выходные, а монтирование конфигурации запрещает запись. Пока он работает как root; следующая независимая лабораторная рассматривает это отдельное разрешение.
Резюме
Вы создали настоящий отчёт, сопоставили пути хоста и контейнера, сделали входное монтирование доступным только для чтения и пересоздали сервис. Фактические параметры монтирования и отказ записи подтвердили защиту, а новый отчёт — сохранение нормального вывода.



