Перейти к содержанию
Бэкенд и системы

8 вопросов по теме «DevOps: CI/CD и GitOps» на собеседовании

В этом материале — 8 вопросов из русской колоды RecallDeck по теме «DevOps: CI/CD и GitOps». Сначала сформулируйте короткий ответ сами, затем откройте подробный разбор и проверьте примеры, ограничения и отказные случаи.

7 мин чтения8 подробных ответовПроверено 24 августа 2026
Главная мысль

Стройте ответ вокруг владения состоянием, лимитов, отказа и восстановления. Определение становится инженерным ответом только в конкретном production-сценарии.

Вопросы и ответы

8 подробных ответов

01

Спроектируйте CI/CD-пайплайн для организации с ~50 микросервисами. Пройдитесь по стадиям и компромиссам.

Короткий ответ: Один общий шаблон пайплайна на все сервисы; сборка один раз → неизменяемый артефакт (образ с digest), который продвигается через окружения без пересборки; тесты ярусами от быстрых к дорогим; в прод — canary с автооткатом. Оценивают не схему, а то, как вы аргументируете компромиссы.

Подробно:

PR: lint + unit (< 5 мин, гейт мержа)
        │ merge в main

build ──► immutable-артефакт (image digest) ──► registry

integration (контрактные тесты, моки соседей)

staging: e2e + smoke ──► промоушен ТОГО ЖЕ артефакта

prod: canary 5% ──► метрики ok ──► 100% (иначе автооткат)
  1. Build once, promote everywhere — пересборка под каждое окружение означает: тестировали один бинарь, выкатили другой. Продвигается digest, а не тег latest.
  2. Ярусы тестов — быстрый гейт на PR, дорогие e2e после мержа: иначе очередь на мерж растёт до часов.
  3. Общий шаблон — 50 сервисов × свой YAML = дрейф и зоопарк; параметризованный shared template обновляется централизованно.
  4. Секреты — OIDC-федерация в облачный IAM, короткоживущие токены вместо статических ключей в CI.

⚠️ Частая ошибка: перечислить стадии без компромиссов. Интервьюер слушает про «скорость vs безопасность»: какие тесты где режем, что блокирует мерж, а что — только выкатку.

02

Trunk-based development или GitFlow: какая модель делает возможным continuous deployment и почему?

Короткий ответ: Continuous deployment реален только при trunk-based + фиче-флаги: маленькие батчи, ветки живут часы, main всегда выкатываем. GitFlow с долгоживущими develop/release-ветками — большие батчи и merge-ад; его место — коробочный софт с версиями.

Подробно:

Trunk-based GitFlow
Ветки main + ветки < 1–2 дней develop, release/, hotfix/ — долгоживущие
Размер батча маленький, интеграция ежедневно большой, интеграция в конце релиза
Deploy vs release разделены фиче-флагами склеены: релиз = мерж release-ветки
Подходит для SaaS, continuous deployment коробочный софт, несколько поддерживаемых версий
  1. Флаги разделяют deploy и release — код едет в прод выключенным; включение — это конфиг, а не выкатка. Это снимает страх мержить незавершённое в main.
  2. Аргумент — размер батча, а не вкус: чем дольше живёт ветка, тем больше конфликтов, длиннее lead time и страшнее откат — DORA-метрики ровно об этом.

⚠️ Частая ошибка: отвечать «кому что удобнее». Это не вопрос вкуса: долгие ветки → большие батчи → длинный lead time — аргумент измеримый.

03

Canary-выкатка: как автоматизировать решение «промоутить или откатывать»?

Короткий ответ: Автоматический canary analysis: на каждом шаге раскатки сравниваем canary с baseline того же размера (не со всем флотом!) по SLI-метрикам — error rate, перцентили латентности — в окне 5–10 минут; выход за порог → автооткат без человека. Так работают Argo Rollouts и Flagger.

Подробно:

трафик: 1% ──► 5% ──► 25% ──► 100%
         │      │       │
         ▼      ▼       ▼
   анализ окна на каждом шаге:
   canary vs BASELINE (свежие поды СТАРОЙ версии,
   столько же реплик):
     • error rate ≤ baseline + порог
     • p99 latency ≤ baseline × 1.05
   fail любого шага ──► автооткат + алерт
  1. Baseline того же размера — сравнивать один canary-под с 50 прогретыми старыми нечестно: другой прогрев кэшей и коннекшн-пулов. Поэтому Flagger/Argo поднимают свежий baseline из старой версии.
  2. Метрики = SLI, не CPU: пользователю безразлична утилизация, важны ошибки и латентность; плюс бизнес-метрика, если есть (конверсия чекаута).
  3. Автооткат — весь смысл: canary без автоматического решения — просто медленная выкатка, за которой кто-то обязан следить глазами.

⚠️ Частая ошибка: остановиться на определении «пускаем 5% трафика». Вопрос — про анализ: что с чем сравниваем, по каким порогам и кто нажимает откат.

04

Что такое GitOps и почему pull-модель (ArgoCD/Flux) лучше, чем push из CI в кластер?

Короткий ответ: GitOps: git — единственный источник желаемого состояния, а агент внутри кластера непрерывно приводит фактическое состояние к нему. Pull лучше push по двум причинам: креды кластера не покидают кластер, и есть непрерывная реконсиляция — дрейф детектируется и чинится, а не только в момент деплоя.

Подробно:

Push (CI → кластер) Pull (ArgoCD/Flux)
Креды admin-kubeconfig лежит в CI агент внутри, наружу ничего не выдаём
Дрейф ручной kubectl edit никто не заметит detect + self-heal автоматически
Аудит логи CI-запусков git log — полная история «кто что менял»
Откат перезапуск старого пайплайна git revert
Масштаб каждый пайплайн знает про кластер app-of-apps, новые кластеры декларативно
  1. CI собирает, CD реконсилирует — пайплайн публикует образ и коммитит новый tag в конфиг-репозиторий; дальше агент делает всё сам.
  2. Отдельный конфиг-репозиторий — код и манифесты живут врозь: иначе каждый bump образа триггерит CI самого приложения.

⚠️ Частая ошибка: «GitOps = хранить YAML в гите». Без непрерывной реконсиляции и self-heal это просто конфиги в репозитории.

05

Как вы обращаетесь с секретами в CI-пайплайнах и в GitOps-репозиториях?

Короткий ответ: Плейнтекстом в git — никогда, даже в приватном репо: история, форки и бэкапы живут вечно. В CI — OIDC-федерация в облачный IAM: короткоживущий токен на джобу вместо хранимых ключей. В GitOps-репо — SOPS/sealed-secrets (в гите шифротекст) или external-secrets (в гите только ссылка на Vault/Secrets Manager).

Подробно:

Слой Решение Почему
CI → облако OIDC federation (runner → IAM role) нет хранимых ключей; токен живёт минуты — нечего красть и ротировать
CI-переменные masked/protected vars — лишь минимум статический секрет, виден мейнтейнерам, утекает в логи (base64 обходит маску)
GitOps-репо SOPS / sealed-secrets шифротекст можно коммитить; расшифровка — только ключом в кластере
Ссылка вместо значения external-secrets operator git хранит указатель, значение в Vault; ротация не трогает git
  1. Ротация — часть ответа: где секрет рождается, кто и как его меняет, что перевыкатывается после смены. Без этого «мы шифруем» — не ответ.
  2. Утёкший секрет скомпрометирован навсегда — git history не чистится «удалением файла»; только ревокация и выпуск нового.

⚠️ Частая ошибка: «у нас masked variables в GitLab» как весь ответ — это долгоживущий статический секрет, который никто не ротирует.

06

CI-сборка идёт 40 минут. Как будете ускорять?

Короткий ответ: Сначала профилировать — разбить время по стадиям и найти, где оно сидит, а не покупать раннеры. Дальше по убыванию выгоды: параллельный DAG вместо цепочки, кэш слоёв Docker (зависимости до исходников), общий remote-кэш, шардирование тестов, affected-only в монорепо. Железо — последним.

Подробно:

  1. Измерить — тайминги стадий уже есть в CI: обычно 80% времени сидит в 1–2 местах (тесты или docker build).
  2. DAG вместо цепочки — lint, unit и сборка образов независимы → параллельно; критический путь короче.
  3. Порядок слоёв в DockerfileCOPY манифеста зависимостей и install ДО COPY . .: правка кода не инвалидирует слой с зависимостями.
  4. Remote-кэш — эфемерные раннеры без общего кэша собирают мир с нуля каждый раз: buildx cache, кэш пакетных менеджеров.
  5. Шардирование тестов — сплит по историческим таймингам на N параллельных джобов.
  6. Affected-only — в монорепо собирать только затронутые пакеты (nx / turborepo / bazel).
  7. Раннеры мощнее — последними — платить железом до профилирования значит маскировать проблему.

⚠️ Частая ошибка: начинать с «купим раннеры побольше». Если 30 из 40 минут — последовательные e2e, железо даст минуты, а параллелизация и кэш — десятки.

07

Как миграции базы данных вписываются в zero-downtime выкатки и откаты?

Короткий ответ: Паттерн expand/contract: сначала аддитивная миграция (новая колонка/таблица), затем код, совместимый с обеими схемами, бэкфилл — и только потом contract (удаление старого) отдельным шагом. Схема и код меняются разными деплоями, каждый шаг обратно совместим на одну версию — иначе мгновенный откат кода невозможен.

Подробно:

T0  expand: ADD COLUMN new (nullable/default) — только схема
T1  деплой v2: пишет в обе колонки, читает new → fallback old
T2  бэкфилл старых строк батчами (не одним UPDATE!)
T3  деплой v3: читает и пишет только new
T4  contract: DROP COLUMN old — когда откат к v2 уже не нужен

инвариант: в любой точке версии кода N и N−1
работают с текущей схемой одновременно
  1. Почему не lock-step — «миграция + код одной выкаткой» ломается дважды: во время раскатки старые поды уже видят новую схему, а откат кода требует отката схемы — то есть потери данных.
  2. Rename — это тоже expand/contract — add → dual-write → backfill → drop; прямой RENAME COLUMN убивает работающую версию.
  3. Бэкфилл отдельно от миграции — гигантский UPDATE при деплое держит блокировки и кладёт прод; батчами, в фоне.

⚠️ Частая ошибка: класть DROP/RENAME в ту же выкатку, что и код. Пять скучных шагов — зато откат остаётся кнопкой, а не восстановлением из бэкапа.

08

Плохой релиз доехал до прода, хотя все тесты были зелёные. Что вы меняете в системе?

Короткий ответ: Признать, что тесты не ловят всё, и достроить контур ПОСЛЕ деплоя: smoke-тесты и SLI-гейты в проде, canary с автооткатом, ревизия паритета staging ↔ prod, фиче-флаги для рискованных путей. И blameless-разбор самого пайплайна: сломалась система доставки, а не инженер.

Подробно:

  1. Post-deploy verification — smoke-тесты и проверка SLI сразу после выкатки как шаг пайплайна; «выкатили и смотрим дашборд глазами» — это не гейт.
  2. Canary + автооткат — плохой релиз получает 5% трафика и откатывается за минуты: ограниченный blast radius вместо «всё или ничего».
  3. Паритет staging/prod — зелёные тесты на непохожем окружении ничего не доказывают: данные, конфиги, версии зависимостей, нагрузка.
  4. Фиче-флаги — рискованный путь выключается конфигом за секунды, без новой выкатки.
  5. Blameless postmortem пайплайна — вопрос «какой гейт должен был это поймать и почему его нет», а не «кто виноват».

⚠️ Частая ошибка: ответить «добавим больше тестов». Тесты живут до прода; класс багов, которые проявляются только в проде (данные, нагрузка, конфиг), ловится только контуром после деплоя.

Источники

Источники и редакционная политика

Материалы RecallDeck сопоставлены с официальной документацией и открытыми публикациями компаний, когда первичный источник доступен. Мы не связаны с упомянутыми работодателями, не публикуем конфиденциальные задания и не продаём места в подборках. Формат найма может меняться — уточняйте его у рекрутера.

От чтения к воспроизведению

Отрепетируйте полный цикл интервью.

RecallDeck возвращает сложные темы по расписанию и помогает удерживать в памяти язык, SQL, архитектуру и поведенческие истории.

Начать подготовку

Продолжить подготовку

Библиотека собеседований RecallDeck

Подробные русские ответы, разборы этапов найма и планы подготовки для российского IT-рынка.

RSS