Вопросы по CI/CD на собеседовании
CI/CD проверяют на практике доставки: как устроен пайплайн, чем плох раннер на общей машине, что делать с миграцией схемы при постепенной выкатке и почему откат кода не всегда возвращает систему в прежнее состояние.
Что спрашивают
- +Пайплайн: стадии и раннеры, кэш и артефакты, воспроизводимость через lock-файлы и дайджесты
- +Артефакты: свой реестр и зеркала, политика хранения, сборка образов без демона
- +Деплой: rolling, blue-green и канарейка, миграции по схеме expand-contract, план отката
- +GitOps: pull-модель и дрейф, Helm против Kustomize, секреты в репозитории
Из чего состоит тема
Так тема разложена в тренажёре: движок ведёт прогресс по каждой подтеме отдельно и возвращает те, где вы ошибаетесь.
- GitOps, Helm, Kustomize7
- Артефакты и реестры7
- Стратегии деплоя7
- Git на практике6
- Пайплайны и раннеры6
Разборы подтем
Конспект по каждой: что это, как отвечать вслух, на чём валятся, плюс вопросы для самопроверки.
- Git на практике: rebase, merge, транк6 вопросов
- Пайплайны CI: раннеры, кэш, артефакты6 вопросов
- Реестры образов и хранение артефактов7 вопросов
- Стратегии деплоя: rolling, blue-green, канарейка7 вопросов
- GitOps: ArgoCD, Helm, Kustomize7 вопросов
Примеры вопросов с разбором
- Реестр разросся до терабайтов: каждая сборка каждой ветки кладёт образ. Как навести порядок?A)Хранить только последний образ каждого репозиторияB)Собирать образы лишь для main, ветки проверять без сборкиC)Перевести реестр на сжатие слоёв и включить дедупликациюD)Политика хранения: релизы держим долго, сборки веток — дни
показать ответ и разбор
+D)Политика хранения: релизы держим долго, сборки веток — дни// разбор: Разумная политика различает типы артефактов: релизные теги и всё, что крутится в проде, хранятся долго и не удаляются автоматически; сборки веток и pull request живут дни, потом уходят по расписанию. Правила задают в самом реестре, а не скриптом на коленке, и обязательно исключают дайджесты, на которые ссылаются работающие деплойменты — иначе автоуборка снесёт образ живого сервиса.
- Раннер настроен исполнителем shell на общей машине. Чем это грозит?A)Сборки тащат состояние друг друга: мусор, версии, права, гонкиB)Такой раннер не умеет забирать артефакты между стадиямиC)Он поддерживает лишь один язык сборки одновременноD)Логи сборки не попадут в интерфейс CI, только в системный журнал
показать ответ и разбор
+A)Сборки тащат состояние друг друга: мусор, версии, права, гонки// разбор: Shell-исполнитель запускает команды прямо на хосте: глобально установленные пакеты, кэши в домашнем каталоге, файлы от прошлых сборок и параллельные джобы, дерущиеся за одни и те же пути. Отсюда «зелено на одной машине, красно на другой» и утечки секретов между проектами. Изоляцию даёт исполнитель на контейнерах или в кластере: чистое окружение на каждую сборку.
- Выкатка идёт rolling update, в релизе есть миграция с переименованием колонки. Что сломается?A)Миграция не применится: схему во время выкатки заблокирует оркестраторB)Ничего: старые поды переживут смену схемы без обращений к колонкеC)Старые поды продолжают работать со старой схемой и начнут падатьD)Новые поды не стартуют, пока все старые не завершатся
показать ответ и разбор
+C)Старые поды продолжают работать со старой схемой и начнут падать// разбор: При постепенной выкатке обе версии кода какое-то время работают с одной базой. Переименование ломает старые поды сразу. Потому миграции ведут по схеме expand-contract: сначала добавляем новую колонку и пишем в обе, выкатываем код, который читает новую, и только следующим релизом убираем старую. Каждый шаг совместим с соседней версией кода.
- Команда релизится несколько раз в день. Почему при этом уходят от долгих фича-веток к транку?A)Долгие ветки не проверить в CI до слиянияB)Короткие ветки дают меньше конфликтов, а незрелое прячут за флагамиC)Транк экономит место в репозитории и ускоряет клонированиеD)Долгие ветки мешают ставить теги и вести семантическое версионирование
показать ответ и разбор
+B)Короткие ветки дают меньше конфликтов, а незрелое прячут за флагами// разбор: Чем дольше ветка живёт отдельно, тем больше расхождение и больнее слияние: конфликты, «а у нас всё работало», поздняя интеграция. Транк-подход требует, чтобы в main постоянно было пригодное к релизу состояние: мелкие вливания по нескольку раз в день, а недоделанное скрыто фича-флагами. Релиз перестаёт быть событием и превращается в рутину.
- Helm или Kustomize: чем они принципиально отличаются?A)Helm работает с кластером напрямую, Kustomize только генерирует файлыB)Helm шаблонизирует манифесты со значениями, Kustomize патчит базовыеC)Helm нужен для приложений, Kustomize — для кластерных объектовD)Helm хранит состояние в git, Kustomize — в самом кластере
показать ответ и разбор
+B)Helm шаблонизирует манифесты со значениями, Kustomize патчит базовые// разбор: Helm — пакетный менеджер: чарт с шаблонами, values на окружение, версии релизов и откат средствами самого инструмента. Kustomize — наложение: есть база манифестов и оверлеи, которые патчат нужные поля для dev, stage и прода, без языка шаблонов. Helm удобен для чужих компонентов, Kustomize — для своих однотипных сервисов; в GitOps часто используют оба вместе.
- Сборка образов идёт в контейнере CI. Чем плох проброс сокета демона внутрь джобы?A)Джоба получает управление демоном хостаB)Сборка станет медленнее из-за двойной виртуализацииC)Собранный образ не попадёт в кэш слоёв раннераD)Демон не умеет собирать образ из контейнера без привилегий
показать ответ и разбор
+A)Джоба получает управление демоном хоста// разбор: Сокет — это полный API демона без аутентификации: чужой код в джобе запускает контейнер с монтированием корня ноды, читает образы и секреты других сборок, ставит своё. По сути это root на раннере. Альтернативы: сборщики без демона (kaniko, buildah), удалённый BuildKit с ограниченным доступом или выделенные одноразовые раннеры, которые уничтожаются после джобы.
- Сборка проходит локально, но падает в CI на другой версии зависимости. Как сделать её воспроизводимой?A)Ставить зависимости в CI из кэша прошлой удачной сборкиB)Зафиксировать lock-файл и базовый образ по дайджестуC)Разрешить сборке доступ в интернет только через проксиD)Собирать под одним пользователем с теми же правами
показать ответ и разбор
+B)Зафиксировать lock-файл и базовый образ по дайджесту// разбор: Воспроизводимость — это когда вход зафиксирован полностью: lock-файл с точными версиями и хэшами пакетов, базовый образ по дайджесту, а не по плавающему тегу, пины тулчейна. Кэш и сеть влияют на скорость, а не на состав. Проверка простая: две сборки одного коммита с разницей в неделю должны дать одинаковый результат.
- Релиз откатили командой отката, поды вернулись к прошлой версии, а ошибки остались. Почему так бывает?A)Откат вернул образ, но не убрал старые поды из балансировкиB)Кэш образов на нодах отдал новую версию под старым тегомC)Прошлая ревизия удалена из истории, откатились на позапрошлуюD)Данные уже записаны в новом формате: код откатился, состояние — нет
показать ответ и разбор
+D)Данные уже записаны в новом формате: код откатился, состояние — нет// разбор: Откат управляет только кодом. Всё, что релиз успел изменить снаружи, остаётся: миграции схемы, записи в новом формате, сообщения в очередях, ключи в кэше, вызванные внешние API. Потому план отката пишут вместе с релизом: обратно совместимые миграции, версионирование форматов сообщений, флаги для быстрого выключения фичи без выкатки.
- Ключ доступа случайно закоммитили и удалили следующим коммитом. Что делать?A)Достаточно удаления: в рабочем дереве ключа больше нетB)Сделать force-push после удаления файла — история подчистится самаC)Считать ключ скомпрометированным и отозвать, потом чистить историюD)Закрыть репозиторий от внешних: во внутреннем это не считается утечкой
показать ответ и разбор
+C)Считать ключ скомпрометированным и отозвать, потом чистить историю// разбор: Коммит с ключом остаётся объектом в истории, в клонах у коллег, в кэшах CI и зеркалах, а публичный репозиторий за минуты обходят сканеры. Порядок такой: сначала отозвать и перевыпустить ключ, потом переписать историю (filter-repo или BFG) и попросить всех перевыпустить клоны. Обратный порядок бесполезен: пока ключ жив, он уже утёк.
это 9 из 33
Ещё 24 вопросов по теме — в тренажёре, с движком повторения
Прочитать разбор и ответить самому — разные навыки. В Сеньорчике вопросы идут сессиями, а движок возвращает подтемы, где вы ошибаетесь, пока они не начнут отскакивать. Бесплатно, лимит по энергии.
Частые вопросы
Чем канареечный выкат отличается от blue-green?
Blue-green поднимает вторую полную копию и переключает трафик разом: откат мгновенный, но нужен двойной запас ёмкости. Канарейка отдаёт новой версии малую долю трафика и растит её по метрикам: дешевле по ресурсам, зато требует зрелого мониторинга.
Что спрашивают про миграции базы при выкатке?
Главное это понимание, что при постепенной выкатке обе версии кода работают с одной схемой. Отсюда схема expand-contract: сначала добавили и пишем в оба места, потом переключили чтение, и только следующим релизом убрали старое.