Как войти внутрь Docker контейнера и выполнить команду
Что проверяют
Знаете ли вы разницу между exec и attach и умеете ли диагностировать Java-приложение в контейнере, где часто нет даже shell. Следом спрашивают, как снять дамп потоков или кучи из работающего контейнера.
Как отвечать
Базовые команды:
- найти контейнер:
docker psпоказывает запущенные,docker ps -aвсе, включая остановленные; - зайти интерактивно:
docker exec -it app sh. Флаг-iдержит открытым stdin,-tвыделяет терминал. В Alpine и многих slim-образахbashнет, поэтомуshнадёжнее; - выполнить одну команду: без shell,
docker exec app envилиdocker exec app cat /app/config/application.yml; - полезные флаги:
-uдля пользователя,-wдля рабочего каталога,-eдля переменной окружения; - Compose и Kubernetes:
docker compose exec app shиkubectl exec -it <pod> -- sh.
docker exec работает только с запущенным контейнером: новый процесс стартует рядом с основным. Если контейнер падает на старте, смотрите docker logs app, а сам образ изучайте через docker run --rm -it --entrypoint sh <image>.
Для Java покажите диагностику: docker exec app jcmd <pid> Thread.print для дампа потоков и jcmd <pid> GC.heap_dump /tmp/heap.hprof для кучи, потом docker cp app:/tmp/heap.hprof .. PID процесса покажет jcmd без аргументов. Две ловушки: в JRE-образах jcmd нет, он входит в JDK, и запускать его нужно от того же пользователя, что и JVM. Если shell нет совсем, как в distroless, помогает отладочный контейнер с общим пространством процессов: docker run --pid=container:app ....
Где спотыкаются
Путают exec с attach. attach подключается к основному процессу, и Ctrl+C пошлёт сигнал JVM и остановит контейнер. Отключиться без остановки можно сочетанием Ctrl+P, Ctrl+Q.
Правят файлы внутри контейнера, как на обычном сервере. После пересоздания контейнера правки пропадут, менять нужно образ или конфигурацию.
Считают, что bash есть везде, и теряются, увидев ошибку executable file not found.