Використовувати Docker у щоденній рутині та чітко пояснити, як він працює — це дві різні навички.
Ви можете мати багаторічний досвід роботи з цим інструментом і вміти запускати контейнери навіть посеред ночі. А потім на співбесіді вас запитують: «Чому тут спрацював кеш?». І тепер вам треба не запускати команду, а пояснювати логіку її роботи.
Тому ми підготували матеріал, який допоможе систематизувати знання і впевнено відповідати на запитання інтерв’юера.
Docker рідко стає темою окремої співбесіди. Найчастіше цей інструмент обговорюють під час технічного інтерв'ю на позиції DevOps-інженера, Backend-розробника або Platform-інженера. Зазвичай перевірку знань із ним поділяють на три рівні:
Перш ніж перейти до запитань, варто врахувати одну важливу особливість. Попри різноманітність, більшість запитань стосується двох ключових тем:
Якщо ви добре розумієте ці принципи, жодне із запитань не застане вас зненацька.
Це своєрідний бліц, який має на меті перевірити ваші знання ключових понять та функцій Docker.
Образ (image) — це незмінний шаблон, який містить застосунок, залежності та все необхідне для його запуску.
Контейнер (container) — це запущений екземпляр цього образу з окремим шаром для запису. Один образ може використовуватися для створення багатьох контейнерів, а зміни в кожному з контейнерів ізольовані й не впливають на сам образ.
Мета запитання — перевірити, чи розумієте ви, що образ є незмінним, а всі зміни в контейнері тимчасові.
VM віртуалізує обладнання та запускає власну операційну систему з окремим ядром.
Контейнер віртуалізує операційну систему: він працює як ізольований процес і використовує спільне ядро хост-системи.
Зазвичай контейнери запускають за лічені секунди, займають менше місця та споживають менше ресурсів. Проте за таку швидкість доводиться платити нижчим рівнем ізоляції порівняно з віртуальними машинами, оскільки вони використовують спільне ядро.
Dockerfile — це текстовий файл з інструкціями, за якими Docker створює образ. У ньому покроково описано весь процес: який базовий образ використати, які команди виконати, які файли скопіювати та яку команду запускати після створення контейнера.
Його головна перевага — відтворюваність. Це дозволяє будь-кому зібрати однаковий образ незалежно від середовища.
Кожна інструкція в Dockerfile створює окремий шар (layer), а всі шари разом формують Docker-образ. Переглянути їх можна за допомогою команди docker history.
Docker кешує кожен шар окремо. Якщо інструкція та пов'язані з нею файли не змінилися, під час наступної збірки цей шар не створюватиметься повторно — Docker просто використає кеш.
Наприклад, якщо змінити лише файл app.py, а requirements.txt залишиться без змін, то під час повторної збірки всі попередні шари будуть взяті з кешу.
У цьому випадку Docker повторно виконає лише останній крок — копіювання app.py. Саме тому порядок інструкцій у Dockerfile має значення: що рідше змінюється, то вище варто розміщувати такі кроки. Це допомагає максимально використовувати кеш і прискорювати збірку.
Обидві команди використовуються для копіювання файлів у Docker-образ, але між ними є важлива різниця.
COPY виконує лише одне завдання — копіює локальні файли та каталоги. ADD має ширші можливості: він може завантажувати файли за URL-адресою та автоматично розпаковувати локальні TAR-архіви.
Часто рекомендують використовувати COPY, оскільки ця команда передбачувана. До ADD варто звертатися лише тоді, коли потрібне автоматичне розпакування архіву або його інші специфічні можливості.
Потрібно освіжити знання команд Docker? У блозі ITEDU, знайдете детальний розбір найпоширеніших команд і приклади їх використання.
Команда docker run виконує не одну, а одразу три дії:
Якщо щось піде не так, важливо розуміти, на якому саме етапі виникла проблема: під час завантаження образу, створення контейнера чи його запуску.
Для перегляду контейнерів використовують команду docker ps, а щоб побачити також зупинені контейнери — docker ps -a. Список усіх локальних образів можна отримати за допомогою docker images.
Для очищення зайвих ресурсів застосовують docker system prune, а параметр -a додатково видаляє всі образи, які вже не є актуальними.
Зупинені контейнери та непотрібні образи з часом накопичуються й займають дисковий простір, тому періодичне «прибирання» — одна з базових практик роботи з Docker.
Команда docker stop спочатку надсилає процесу сигнал SIGTERM. Це дає йому час на коректне завершення роботи. Якщо процес не зупиняється протягом стандартних 10 секунд, Docker примусово завершує його за допомогою SIGKILL.
Команда docker kill одразу надсилає SIGKILL, не залишаючи процесу часу на коректне завершення.
Тож docker stop дає застосунку можливість коректно завершити роботу, тоді як docker kill миттєво припиняє його виконання.
Якщо перший блок перевіряє знання термінів, то цей — глибину розуміння, чому саме в Docker використовують ті чи інші підходи.
Усі дані, записані всередині контейнера, автоматично зберігаються лише в його шарі для запису. Після видалення контейнера вони також зникають.
Щоб дані зберігалися незалежно від життєвого циклу контейнера, використовують:
Найчастіше для постійного зберігання даних застосовують саме томи.
Після встановлення Docker створює три стандартні мережі:
Якщо під час запуску контейнера мережу не вказано, Docker автоматично підключить його до bridge.
EXPOSE лише повідомляє Docker, який порт прослуховує контейнер. Реальний доступ до нього відкриває команда -p (--publish), що зіставляє порт контейнера з портом хост-системи.
Docker Compose — це інструмент, який дозволяє описати багатоконтейнерний застосунок в одному YAML-файлі. У ньому визначають сервіси, мережі, томи та інші параметри. Запуск усього застосунку виконується однією командою — docker compose up.
Docker Compose використовують, коли застосунок складається з кількох контейнерів (наприклад, API, бази даних і Redis) або потрібно швидко розгорнути однакове середовище для розробки.
Тег latest не означає «нова версія». Це тег, який Docker використовує автоматично, якщо ви не вказали інший.
Його головний недолік у тому, що вміст образу може змінюватися з часом. Через це одна й та сама команда docker pull, виконана в різні дні, може завантажити різні версії образу.
Саме тому в робочих проєктах рекомендують використовувати конкретні теги версій (або дайджести), а latest залишити для локальної розробки чи тестування.
Це можна зробити кількома способами:
Навіть кілька таких оптимізацій можуть суттєво зменшити розмір образу та прискорити його збірку.
RUN виконує команди під час збірки образу, наприклад встановлює пакети або залежності.
CMD і ENTRYPOINT визначають, яка команда буде виконана після запуску контейнера. Різниця між ними полягає в тому, що ENTRYPOINT задає основну команду, а CMD — аргументи, які використовуються під час запуску контейнера, але за потреби їх можна легко перевизначити.
Конфігурацію контейнера зазвичай передають через змінні середовища (-e, env_file) або змонтовані конфігураційні файли. Завдяки цьому один і той самий образ можна використовувати в різних середовищах, змінюючи лише налаштування.
Чутливі дані (паролі, токени, ключі доступу) не можна зберігати в Dockerfile або всередині образу, оскільки їх можна отримати з його шарів. Для цього використовують механізми керування секретами, наприклад Docker Secrets або спеціалізовані сховища секретів.
На цьому етапі техлід перевіряє, як ви дієте в умовах, наближених до реальної роботи. Вам можуть запропонувати вирішити типову проблему, пов’язану з Docker.
Перш за все варто знайти, що саме займає найбільше місця. Для цього використовують команду docker history <image>, яка показує розмір кожного шару образу. Часто найбільше місця займає базовий образ або встановлені залежності.
Після цього варто:
Багатоетапна збірка може дозволити зменшити розмір образу з умовних 1,27 ГБ до 15,5 МБ, адже інструменти для збірки не потраплять до фінального образу. Крім того, правильний порядок інструкцій і файл .dockerignore допомагають не лише зменшити розмір образу, а й значно прискорити його збірку.
Насамперед перевіряється стан контейнера та його журнали за допомогою команд docker ps -a і docker logs <container>.
Зазвичай проблема навіть не в помилці, контейнер просто завершив виконання свого головного процесу (PID 1), а разом із ним зупинився і сам.
Якщо контейнер мав працювати постійно, перевірте CMD або ENTRYPOINT. Основний процес не повинен завершуватися одразу чи працювати у фоновому режимі.
Якщо контейнер завершився з ненульовим кодом виходу, причину збою можна знайти в журналах.
Найімовірніша причина — кеш збірки Docker. Якщо відповідний шар не змінився, Docker повторно використовує його замість того, щоб створювати заново. У результаті контейнер може запускатися зі старою версією коду.
Треба переглянути, чи інструкція COPY не була взята з кешу (CACHED), а зміни дійсно потрапили до нового образу. За потреби варто перебудувати образ без використання кешу.
Окрім цього важливо перевірити, що запускається саме щойно зібраний образ, а не його стара версія.
Код виходу 137 означає, що контейнер було примусово завершено сигналом SIGKILL. Це відбувається через нестачу пам'яті (Out of Memory, OOM), коли система зупиняє контейнер, який перевищив доступний ліміт.
Перевірити це можна за допомогою команди docker inspect <container>.
Якщо результат містить OOMKilled=true, причина підтверджена.
У такому разі потрібно або збільшити ліміт пам'яті, абознайти й усунути причину її надмірного споживання, наприклад витік.
Дані зникли, тому що вони зберігалися у файловій системі контейнера, яка видаляється разом із ним. Це стандартна поведінка Docker, а не помилка.
Щоб дані зберігалися після видалення контейнера, потрібно використовувати томи (volumes) або bind mounts, які зберігають інформацію поза контейнером.
Не забуваймо про основний принцип Docker: файлова система контейнера є тимчасовою, тому важливі дані слід зберігати поза нею.
Причина ховається в одній із трьох ситуацій:
Для уникнення таких проблем, варто використовувати конкретні теги або дайджести, регулярно оновлювати образи в реєстрі та стежити, щоб збірка не залежала від локального середовища.
Теорія — важлива, але успішне проходження технічної співбесіди з Docker залежить не лише від знання команд. Інтерв’юери цінують, коли ви можете підкріпити свої відповіді реальним досвідом і пояснити, як застосовували ці знання на проєктах.
Перед співбесідою радимо повернутися до цієї статті — вона допоможе за 10 хв. освіжити ключові теми.
Якщо хочете глибше розібратися в Docker і зрозуміти принципи його роботи, запрошуємо на практикум з адміністрування Docker від ITEDU.
Бажаємо успіхів!
Анастасія Хітрова
NETFORCE Jobs — перша в Україні платформа з пошуку роботи для DevOps-інженерів.
Кандидати використовують ШІ для написання резюме. Читайте 5 порад, як застосувати штучний інтелект так, щоб виділитися та отримати офер.
Дізнайтеся, що таке мета скіли, чим вони відрізняються від хард і софт скілів, та як розвивати здатність до навчання, щоб залишатися затребуваним фахівцем.
Огляд 8 форматів ІТ-співбесід — від панельних до баррейзингу. Пояснюємо, що саме оцінює роботодавець та як кандидату до них підготуватися.