Мінімальні образи (distroless, scratch, «скелетні» Alpine) - добра практика безпеки: менше пакетів - менше вразливостей і можливостей для зловмисника. Але в них немає sh, curl, ps, netstat - docker exec -it app sh не працює.
docker debug (входить у Docker Desktop і передплати Docker) підключає до запущеного контейнера окрему оболонку з набором інструментів, не змінюючи образ:
docker debug app
- бачить файлову систему й процеси контейнера;
- інструменти (vim, curl, htop, nslookup...) беруться з окремого образу інструментів і не потрапляють у контейнер застосунку;
- працює й для зупинених контейнерів і образів (
docker debug myapp:latest).
Способи без docker debug:
1. Контейнер-сусід у тих самих просторах імен:
docker run --rm -it \
--network container:app \
--pid container:app \
nicolaka/netshoot
Інструментальний контейнер бачить мережу й процеси контейнера app: ss -tlnp, curl localhost:8080, tcpdump, ps aux. Сам контейнер застосунку не змінюється.
2. Доступ до файлової системи:
docker cp app:/var/www/html/storage/logs/laravel.log ./
docker export app | tar -t | grep config # вміст файлової системи контейнера
3. nsenter з хоста (Linux, потрібні права root) - увійти в простори імен процесу контейнера й використовувати інструменти хоста.
4. Окрема налагоджувальна стадія в Dockerfile:
FROM gcr.io/distroless/... AS production
FROM production AS debug
COPY --from=busybox:musl /bin/busybox /busybox/
Для локального розслідування збирається --target debug, у продакшен іде production.
У Kubernetes аналог - тимчасові контейнери (kubectl debug), що підключаються до поди.
Що важливо:
- налагодження в продакшені - контрольована операція: доступ до хоста й Docker - це фактично root, тож дії мають логуватися й обмежуватися;
- не встановлювати інструменти в контейнер застосунку «на хвилинку» - контейнер змінено, і результат розслідування може бути спотворено;
- спершу зовнішні сигнали: логи (
docker logs), метрики,docker inspect- часто достатньо без входу в контейнер.