Вопросы на собеседовании DevOps: 40+ ситуаций из реальной работы
Команда KAI Lab · · 26 мин чтения
На собеседовании DevOps всё чаще спрашивают не определения, а ситуации: «прод лежит, твои действия», «под в CrashLoopBackOff», «диск кончился в три ночи». Интервьюер проверяет порядок мысли: что вы проверите первым, какие команды запустите, что сделаете безопасно прямо сейчас и что — потом.
Ниже 41 такая ситуация по девяти темам: Linux, сети, Docker, Kubernetes, CI/CD, Git, инфраструктура как код, мониторинг и инциденты. У каждой — что хочет услышать интервьюер и развёрнутый ответ под спойлером. Сначала попробуйте ответить сами. По Linux, Docker и Kubernetes есть отдельные подборки по 15 вопросов, ссылки — в начале разделов.
Как отвечать на вопросы-ситуации
- Уточните контекст. Что именно сломалось, у кого, с какого момента, что менялось перед этим.
- Идите от быстрого и безопасного к медленному. Сначала то, что ничего не ломает: статус, логи, метрики.
- Называйте команды и что ожидаете в выводе. «Посмотрю логи» — слабый ответ,
kubectl logs --previousи «ищу последнюю ошибку перед падением» — сильный. - Разделяйте «остановить кровотечение» и «найти причину». Откат сейчас, разбор потом.
- Заканчивайте профилактикой. Алерт, автоматизация, постмортем.
- Не знаете — скажите, как бы выяснили. Это ценится больше уверенной выдумки.
Linux
Подробная подборка — 15 вопросов по Linux.
1. На проде кончилось место, сервис пишет «No space left on device». Что делаешь?
Что хочет услышать интервьюер: безопасный порядок — вернуть сервис, не сломав его, найти источник и закрыть причину.
Ответ
df -h покажет, какой раздел заполнен, df -i — не кончились ли inode. Крупные каталоги ищу через du -xh --max-depth=1 / | sort -h и дальше вглубь. Если du насчитывает меньше, чем показывает df, место держат удалённые, но ещё открытые файлы: lsof +L1. Такой лог бесполезно удалять rm — он уже удалён. Место вернёт перезапуск процесса или обрезка через его дескриптор. Живой лог обрезаю truncate -s 0, а не удаляю. После — ротация логов и алерт на прогноз заполнения. Подробно — в статье закончилось место на диске.
2. Load average 20 на восьми ядрах, а процессор почти свободен. Что происходит?
Что хочет услышать интервьюер: в Linux load average считает не только процессы в очереди на CPU, но и ждущие ввода-вывода.
Ответ
По man proc три числа load average — среднее за 1, 5 и 15 минут числа процессов в состоянии R (готовы выполняться) и D (ждут дискового ввода-вывода). Высокая нагрузка при свободном CPU — почти всегда процессы в D: медленный или умирающий диск, зависший NFS. Проверяю vmstat 1 (столбцы b и wa), iostat -xz 1 (время ожидания и загрузка устройств), список процессов в состоянии D через ps -eo stat,pid,comm | awk '$1 ~ /^D/' и dmesg -T на ошибки дисков. Подробнее — в статье про load average.
3. После перезагрузки сервера сервис не поднялся. Твои шаги?
Что хочет услышать интервьюер: работа с systemd и журналом, а не «перезапущу ещё раз».
Ответ
systemctl status app — состояние и последние строки лога. journalctl -u app -b — всё с момента загрузки. systemctl is-enabled app — был ли сервис вообще включён в автозапуск. systemctl cat app — итоговый юнит с дополнениями. Частые причины: сервис стартует раньше сети или базы, нет After= и Wants=network-online.target; юнит правили без systemctl daemon-reload; неверный путь в ExecStart, права, переменные окружения, занятый порт. Подробнее — systemd-сервис не запускается.
4. Приложение не стартует: «Address already in use». Как найти, кто занял порт?
Что хочет услышать интервьюер: ss или lsof и понимание, что делать с найденным процессом.
Ответ
ss -ltnp 'sport = :8080' или lsof -iTCP:8080 -sTCP:LISTEN покажут PID и имя процесса. Дальше важно понять, кто им управляет: зависший старый экземпляр того же приложения, другой сервис с тем же портом в конфиге или контейнер с опубликованным портом. Процесс под systemd или Docker бессмысленно убивать kill -9: его перезапустят. Нужно остановить через тот менеджер, который его держит, или развести порты. Подробнее — порт занят в Linux.
5. Ночью процесс пропал, в логах приложения пусто. Где искать?
Что хочет услышать интервьюер: OOM killer и журнал ядра.
Ответ
Приложение не успевает ничего записать, если его убило ядро. Смотрю journalctl -k -b | grep -i -E 'out of memory|killed process' или dmesg -T | grep -i oom. Когда память кончается на всей машине или внутри cgroup с лимитом — у сервиса systemd с MemoryMax= или у контейнера, — OOM killer убивает процесс. Дальше выясняю, почему росла память: утечка, всплеск нагрузки, неверный лимит. Ставлю алерт на память и лимит, чтобы под удар попадал сам виновник, а не соседние сервисы.
Сети
6. У пользователей сайт не открывается, а у тебя открывается. С чего начнёшь?
Что хочет услышать интервьюер: сузить круг — кто, где и что именно видит, — а потом проверить DNS, TLS и маршрут.
Ответ
Сначала вопросы: какие пользователи (регион, провайдер, мобильные или нет), какая именно ошибка — таймаут, «сайт не найден», ошибка сертификата, 5xx. Дальше по слоям. DNS: dig +short site.kz @8.8.8.8 против @1.1.1.1 и против DNS провайдера — после смены записей с долгим TTL часть резолверов отдаёт старый адрес. TLS: цепочка сертификата, которая не проходит проверку у части клиентов. Маршрут: проверка из другой сети или региона. Конкретный адрес проверяю через curl -v https://site.kz --resolve site.kz:443:IP.
7. ping до сервера проходит, а curl к сервису висит. Что это значит?
Что хочет услышать интервьюер: ICMP и TCP-порт — разные вещи; разница между «висит» и «отказано».
Ответ
ping проверяет только, что хост отвечает на ICMP. Если соединение висит — пакеты на порт, скорее всего, молча отбрасывает фаервол. Если сразу «Connection refused» — порт никто не слушает. Проверяю снаружи nc -vz host 443, на сервере ss -ltn: слушает ли кто-то порт и на каком адресе — 127.0.0.1 снаружи недоступен. Дальше правила фаервола (nft list ruleset или iptables -S) и группы безопасности в облаке. curl -v показывает, где именно зависло: DNS, TCP или TLS.
8. После переезда сервис не может разрешить имя базы. Как проверить DNS?
Что хочет услышать интервьюер: разницу между dig и тем, как имена разрешает система.
Ответ
getent hosts db.internal разрешает имя так же, как большинство приложений: через NSS, с учётом /etc/hosts и порядка из /etc/nsswitch.conf. dig db.internal спрашивает DNS напрямую. Если dig работает, а getent нет — смотрю nsswitch.conf и /etc/hosts. Если не работает ничего — /etc/resolv.conf (какой сервер, какие search-домены), resolvectl status при systemd-resolved и прямой запрос к нужному серверу dig @10.0.0.2 db.internal. Отдельно помню про кэш DNS внутри самого приложения. Подробнее — DNS не резолвит в Linux.
9. После продления сертификата у части клиентов ошибка проверки, а в браузере всё нормально. Почему?
Что хочет услышать интервьюер: неполная цепочка сертификатов и проверка через openssl.
Ответ
Частая причина — сервер отдаёт только сертификат сайта без промежуточного. Браузеры часто достраивают цепочку сами — из кэша или скачивая промежуточный сертификат, — а curl, Java и многие мобильные клиенты нет. Проверяю openssl s_client -connect site.kz:443 -servername site.kz -showcerts < /dev/null: сколько сертификатов в цепочке и что в строке Verify return code. Лечится полной цепочкой в конфиге, например fullchain.pem в nginx. Заодно смотрю сроки: openssl x509 -noout -dates. Подробнее — истёк SSL-сертификат.
10. Запросы между двумя сервисами иногда висят по несколько секунд, а сами сервисы здоровы. Что проверишь?
Что хочет услышать интервьюер: разложить задержку по этапам и знать типовые сетевые причины.
Ответ
Сначала меряю, где уходит время: curl -o /dev/null -s -w '%{time_namelookup} %{time_connect} %{time_starttransfer}\n' URL. Долгий namelookup — DNS: задержка ровно в пять секунд часто означает, что один из резолверов не отвечает, а таймаут по умолчанию в resolv.conf — 5 секунд. Долгий connect — потери и повторные передачи (ss -ti), переполненная таблица conntrack (в dmesg будет nf_conntrack: table full, dropping packet). Долгий ответ после соединения — сам сервис или исчерпанный пул соединений. Если висят только большие ответы — проверяю MTU: ping -M do -s 1472 host.
Docker
Подробная подборка — 15 вопросов по Docker.
11. Контейнер падает сразу после старта. Как понять почему?
Что хочет услышать интервьюер: логи, код выхода, docker inspect и запуск с другой точкой входа.
Ответ
docker ps -a покажет статус и код выхода, docker logs app — логи, они сохраняются и у остановленного контейнера. docker inspect app --format '{{.State.ExitCode}} {{.State.OOMKilled}}' — код и не убило ли его за память. Коды читаю так: 1 — ошибка приложения, 126 и 127 — команду нельзя выполнить или она не найдена, 137 — SIGKILL (часто OOM), 143 — SIGTERM. Чтобы заглянуть внутрь, запускаю docker run -it --entrypoint sh image. С политикой перезапуска это превращается в бесконечный рестарт — см. контейнер Docker перезапускается.
12. Сборка образа идёт 10 минут, хотя поменяли одну строку кода. Как ускорить?
Что хочет услышать интервьюер: порядок слоёв и кэш сборки.
Ответ
По документации Docker, если слой изменился, все слои после него пересобираются. Если COPY . . стоит до установки зависимостей, любая правка кода заново качает все пакеты. Правильный порядок: скопировать только манифесты (package.json и lock-файл), установить зависимости, потом копировать код. .dockerignore убирает из контекста .git и node_modules, чтобы они не ломали кэш. Дальше — кэш-монтирование BuildKit (RUN --mount=type=cache,...) и кэш из registry в CI.
13. Токен для приватного репозитория передают в Dockerfile через ARG. Чем это плохо?
Что хочет услышать интервьюер: аргументы сборки остаются в образе; история Codecov; secret mounts.
Ответ
Документация Docker прямо говорит: аргументы сборки и переменные окружения не подходят для секретов, потому что остаются в итоговом образе. Их видно в docker history и метаданных, а файл, удалённый в следующем слое, остаётся в предыдущем. В 2021 году атакующий достал ключ Google Cloud Storage из промежуточного слоя публичного образа Codecov, подменил скрипт загрузки отчётов и два месяца собирал переменные окружения из CI клиентов — см. взлом Codecov. Правильно — docker build --secret и RUN --mount=type=secret, а утёкший токен — отозвать.
14. На build-сервере кончилось место. Что чистить и как не допустить повторения?
Что хочет услышать интервьюер: docker system df, чистку с фильтрами и ротацию логов.
Ответ
docker system df покажет, что занимает место: образы, контейнеры, тома или кэш сборки. Кэш чищу docker builder prune --filter until=72h, неиспользуемые образы — docker image prune -a --filter until=168h, помня, что -a удаляет все неиспользуемые образы, а не только безымянные. Тома вслепую не чищу: там данные. Отдельно проверяю логи: драйвер json-file по умолчанию их не ротирует, нужны max-size и max-file в daemon.json или драйвер local. Профилактика — чистка по расписанию и алерт на диск. Подробнее — No space left on device в Docker.
Kubernetes
Подробная подборка — 15 вопросов по Kubernetes.
15. Под в CrashLoopBackOff. Твои действия?
Что хочет услышать интервьюер: логи предыдущего запуска, describe, код выхода и понимание, что такое backoff.
Ответ
CrashLoopBackOff значит, что контейнер падает, а kubelet ждёт перед каждым новым запуском всё дольше: по умолчанию 10, 20, 40 секунд и так до 5 минут; после 10 минут стабильной работы счётчик сбрасывается. kubectl logs pod --previous — логи упавшего экземпляра, kubectl describe pod — Last State, Exit Code, Reason и события, например проваленные пробы. Типичные причины: ошибка в приложении или конфиге, нет переменной или секрета, liveness-проба убивает медленный старт, OOM. Подробнее — CrashLoopBackOff.
16. Под висит в Pending уже десять минут.
Что хочет услышать интервьюер: события FailedScheduling и их причины.
Ответ
Pending — под принят кластером, но контейнеры ещё не запущены: его не распределили на узел или всё ещё скачивается образ. kubectl describe pod покажет в событиях FailedScheduling с причиной. Частые: запрошенные requests не помещаются ни на один узел (планировщик смотрит на requests, а не на фактическую загрузку), taint без toleration, не совпал nodeSelector или affinity, не привязан PVC. Лечится правкой requests, добавлением узлов или исправлением правил размещения. Подробнее — под в Pending.
17. Service создан, а запросы до подов не доходят.
Что хочет услышать интервьюер: селектор, EndpointSlice, targetPort и readiness.
Ответ
kubectl get endpointslices -l kubernetes.io/service-name=app: если адресов нет, селектор Service не совпадает с метками подов (kubectl get pods --show-labels) или поды не Ready — проваленная readiness-проба убирает под из эндпоинтов. Если адреса есть — проверяю, что targetPort совпадает с портом, который слушает приложение, и что оно слушает 0.0.0.0, а не 127.0.0.1. Проверяю под напрямую через kubectl port-forward, потом сервис из соседнего пода по имени app.namespace.svc.cluster.local. Остаётся NetworkPolicy.
18. Выкатка встала: новые поды не становятся Ready.
Что хочет услышать интервьюер: как ведёт себя RollingUpdate, где искать причину и как откатить.
Ответ
kubectl rollout status deploy/app висит. При стратегии RollingUpdate с настройками по умолчанию (maxUnavailable и maxSurge по 25%) Deployment не гасит старые поды, пока новые не готовы, поэтому сервис продолжает работать на старой версии. Причину ищу в kubectl describe pod новых подов: readiness не проходит, ImagePullBackOff, падение при старте. Через progressDeadlineSeconds (по умолчанию 600 секунд) Deployment получит условие ProgressDeadlineExceeded, но сам не откатится. Откат — kubectl rollout undo deploy/app. См. также ImagePullBackOff.
19. Под периодически перезапускается с OOMKilled.
Что хочет услышать интервьюер: лимит памяти, код 137, утечка или заниженный лимит.
Ответ
В kubectl describe pod: Last State — Terminated, Reason — OOMKilled, Exit Code — 137. Контейнер превысил лимит памяти, и ядро его убило. Смотрю реальное потребление: kubectl top pod и графики за несколько дней. Растёт ровно и без остановки — похоже на утечку. Скачки на пиках — нагрузка или настройки кучи: у JVM или Node.js куча может быть больше лимита контейнера. Лечится лимитом по реальному пику с запасом или исправлением приложения. Для памяти удобно ставить requests равными limits. Подробнее — OOMKilled и exit code 137.
CI/CD
20. Опиши пайплайн от коммита до прода для веб-сервиса.
Что хочет услышать интервьюер: этапы, неизменяемый артефакт, проверки и откат.
Ответ
Линтеры и юнит-тесты. Сборка образа один раз с тегом по SHA коммита и публикация в registry. Сканирование зависимостей, образа и секретов. Автоматический деплой на staging, интеграционные и smoke-тесты. В прод — по тегу или ручному подтверждению. После деплоя — проверка здоровья и доли ошибок, при деградации — остановка и откат. Главное: один и тот же артефакт проходит все окружения, отличается только конфигурация. Секреты — из переменных CI или хранилища, не из репозитория.
21. Релиз сломал оплату. Как откатиться за минуту и почему это не всегда просто?
Что хочет услышать интервьюер: откат на прошлый артефакт, миграции базы и фича-флаги.
Ответ
Быстрый откат — это деплой предыдущего неизменяемого образа, а не пересборка старого коммита: при пересборке могут подтянуться другие версии зависимостей. В Kubernetes — kubectl rollout undo. Главный враг отката — миграции базы: если новая версия несовместимо поменяла схему, старый код с ней не заработает. Поэтому миграции делают обратно совместимыми: сначала расширить схему, потом перевести код, потом убрать старое. Фича-флаги позволяют выключить функцию без деплоя. Если ошибки начались вместе с релизом — сначала откат, разбор потом.
22. Где хранить секреты для пайплайна?
Что хочет услышать интервьюер: не в репозитории; маскированные переменные, хранилище, короткоживущие токены, минимальные права.
Ответ
Не в коде и не в Dockerfile. Минимум — защищённые и маскированные переменные CI, доступные только защищённым веткам. Лучше — хранилище секретов (Vault, менеджер секретов облака) и короткоживущие учётные данные через OIDC вместо статичных ключей облака. У каждой джобы — минимальные права, у ключей — ротация. Всё, что лежит в окружении CI, может утечь: подменённый скрипт Codecov отправлял наружу переменные окружения из CI клиентов, а после взлома CircleCI в 2023 году клиентам пришлось менять все секреты — см. взлом CircleCI.
23. Нужно выкатить рискованное изменение без простоя. Как?
Что хочет услышать интервьюер: canary или blue-green, метрики и автоматическая остановка.
Ответ
Blue-green — второе полное окружение с новой версией, трафик переключается целиком и так же быстро возвращается. Минусы — двойные ресурсы и общая база. Canary — новая версия получает 1–5% трафика, её ошибки и задержку сравнивают со старой и расширяют долю ступенями. При деградации выкатка останавливается и откатывается сама: в Kubernetes это умеют Argo Rollouts и Flagger. То же касается конфигов и правил. Обновление CrowdStrike в 2024 году ушло сразу на все машины и уронило миллионы компьютеров — см. сбой CrowdStrike.
24. Деплой скриптом по SSH упал на середине: часть серверов с новой версией, часть со старой. Как сделать деплой надёжнее?
Что хочет услышать интервьюер: идемпотентность, атомарное переключение, проверку результата и партии.
Ответ
Деплой должен быть идемпотентным — повторный запуск безопасен — и проверять результат на каждом сервере: эндпоинт с версией, проверку здоровья, а не только код выхода скрипта. Новый релиз кладётся в отдельный каталог, переключение — сменой симлинка и перезапуском, прошлый релиз остаётся для отката. Серверы обновляются партиями с остановкой при ошибках, например serial и max_fail_percentage в Ansible. У Knight Capital в 2012 году новый код не скопировали на один из восьми серверов, и никто этого не проверил — см. сбой Knight Capital.
Git
25. Кто-то сделал force push в main и затёр чужие коммиты. Как вернуть?
Что хочет услышать интервьюер: reflog, копии у коллег и защита веток.
Ответ
Коммиты почти наверняка живы: в локальном репозитории того, у кого они были, в клонах коллег, в раннерах CI. У автора git reflog покажет, куда указывала ветка до перезаписи; по умолчанию записи reflog живут 90 дней, недостижимые — 30. Нахожу нужный SHA, проверяю содержимое и возвращаю ветку на него — тоже принудительным пушем, но уже согласованно с командой. После — защищаю main от force push и принимаю изменения только через merge request. В своих ветках использую --force-with-lease: он откажется перезаписывать, если на сервере появились чужие коммиты.
26. Релиз сломался, между рабочей и сломанной версией 200 коммитов. Как найти виновный?
Что хочет услышать интервьюер: git bisect и его автоматизацию.
Ответ
git bisect start, git bisect bad v2.4.0, git bisect good v2.3.0 — Git берёт коммит посередине, я проверяю и отмечаю good или bad. Для 200 коммитов хватит около восьми шагов: каждый делит диапазон пополам. Если проверку можно автоматизировать, git bisect run ./test.sh пройдёт всё сам: код 0 — хороший коммит, от 1 до 127 — плохой, 125 — пропустить непроверяемый. В конце git bisect reset.
27. В репозиторий закоммитили ключ от облака и удалили его следующим коммитом. Этого достаточно?
Что хочет услышать интервьюер: ключ скомпрометирован — сначала отозвать и заменить, потом история и защита.
Ответ
Нет. Ключ остался в истории, клонах, форках и кэшах CI. Первый шаг, как пишет и документация GitHub, — отозвать или заменить секрет; после этого его уже нельзя использовать, и переписывать историю иногда даже не нужно. Параллельно — проверить журналы облака, не пользовался ли ключом кто-то чужой. Потом, если нужно, чистка истории через git filter-repo с пересозданием всех клонов. Профилактика — сканер секретов до коммита и в CI. В 2016 году атакующие нашли ключ AWS в коде приватного репозитория Uber — см. утечка Uber.
28. Плохой коммит уже в main и задеплоен. revert или reset?
Что хочет услышать интервьюер: в общей ветке — revert, потому что reset переписывает историю.
Ответ
git revert <sha> создаёт новый коммит, который отменяет изменения. История не меняется, коллеги ничего не теряют, отмена проходит обычный пайплайн. git reset --hard с force push переписывает общую историю и ломает чужие клоны — так можно только в своей, никому не отданной ветке. Для merge-коммита нужен git revert -m 1 <sha>. Нюанс: если потом снова вливать ту же ветку, сначала придётся отменить сам revert, иначе изменения из неё не вернутся.
Инфраструктура как код
29. terraform plan показывает, что база будет пересоздана. Что делаешь?
Что хочет услышать интервьюер: прочитать план, найти, что вызывает замену, не применять и защитить ресурсы с данными.
Ответ
В плане будет must be replaced, символ -/+ и атрибут с пометкой # forces replacement — именно он вызывает пересоздание. Не применяю. Типичные причины: изменили атрибут, который нельзя поменять на месте; переименовали ресурс в коде, и у него сменился адрес — тогда нужен блок moved (Terraform 1.1+) или terraform state mv; обновили провайдер. Для баз и хранилищ ставлю lifecycle { prevent_destroy = true }: Terraform откажется строить план с их удалением. Но если удалить сам блок ресурса из кода, эта защита уже не сработает.
30. Кто-то поменял настройки в облачной консоли руками. Как это заметить и что делать?
Что хочет услышать интервьюер: дрейф, plan -refresh-only и решение — вернуть или перенести в код.
Ответ
Ручное изменение видно в terraform plan как правка, которую Terraform хочет откатить. terraform plan -refresh-only показывает, что изменилось вне Terraform, не предлагая менять инфраструктуру. Дальше решаю вместе с автором: если изменение было нужно, например срочный фикс во время инцидента, переношу его в код. Если нет — применяю план и возвращаю как было. Профилактика — plan по расписанию в CI с алертом на непустой дифф (-detailed-exitcode вернёт 2), доступ к консоли только на чтение и изменения только через пайплайн.
31. Двое одновременно запустили terraform apply. Что может случиться и как защититься?
Что хочет услышать интервьюер: удалённый state с блокировкой и apply только из пайплайна.
Ответ
С локальным state или без блокировки два apply могут перетереть state друг друга и создать дубликаты ресурсов. Защита — удалённый backend с блокировкой: второй запуск получит Error acquiring the state lock. В S3 для этого есть use_lockfile = true, блокировка через DynamoDB объявлена устаревшей. Подходят и state в GitLab, и HCP Terraform. terraform force-unlock — только если точно знаете, что блокировка зависла. Лучше всего запускать apply только из пайплайна, по одному на окружение.
32. Нужно поменять конфиг nginx на 50 серверах через Ansible. Как не уронить все сразу?
Что хочет услышать интервьюер: проверку перед запуском, партии, остановку на ошибках и валидацию конфига.
Ответ
Сначала ansible-playbook site.yml --check --diff --limit web-01 — что изменится, без изменений, — и прогон на staging. В плее — serial: 5 или процент и max_fail_percentage: 0, чтобы первая же ошибка остановила выкатку. Для основного nginx.conf в модуле template — validate: nginx -t -c %s: сломанный конфиг не будет записан. Хендлер делает reload, а не restart, после партии — проверка здоровья. В 2017 году команда из плейбука с неверным параметром вывела из строя S3 в регионе AWS, и исправили инструмент, а не человека — см. сбой AWS S3.
Мониторинг
33. Ночью разбудил алерт «CPU выше 90%», а пользователи ничего не заметили. Что не так?
Что хочет услышать интервьюер: алертить нужно по симптомам, а не по причинам.
Ответ
Загрузка CPU — причина, а не симптом. В книге Google SRE мониторинг отвечает на два вопроса: что сломалось и почему. Будить человека должно «что сломалось» — то, что чувствуют пользователи. Четыре золотых сигнала: задержка, трафик, ошибки и насыщение. Высокий CPU без влияния на пользователей — повод для дашборда или тикета, а не для звонка ночью. Лучший вариант — алерт на скорость расхода бюджета ошибок по SLO, подробнее — SLI, SLO и бюджет ошибок.
34. Как узнать заранее, когда кончится диск?
Что хочет услышать интервьюер: прогноз по тренду, а не порог в процентах.
Ответ
Порог в процентах врёт: 90% на диске в 10 ТБ — это терабайт свободного места, а на 20 ГБ — минуты до отказа. Лучше алертить на время до заполнения: predict_linear(node_filesystem_avail_bytes{mountpoint="/"}[6h], 4 * 3600) < 0 — «при текущем темпе диск заполнится в ближайшие 4 часа». Этот алерт дополняют жёстким порогом на случай резкого роста, который тренд не успеет поймать.
35. Поддержка пишет: «сайт тормозит». Где смотреть?
Что хочет услышать интервьюер: путь от симптома к компоненту — перцентили задержки, трейсы, насыщение.
Ответ
Сначала подтвердить и очертить проблему: p95 и p99 задержки (не среднее) на входе — балансировщике или ingress; какие эндпоинты; с какого момента; совпадает ли это с релизом или ростом трафика. Потом идти вниз по цепочке вызовов: у какого сервиса выросла задержка. Трейсы показывают, на каком шаге уходит время. Дальше насыщение: медленные запросы и соединения базы, троттлинг CPU в контейнерах, паузы сборщика мусора. И всегда сравнивать с последним изменением.
36. Мониторинг лёг вместе с продом. Как узнать, что мониторинг сам не работает?
Что хочет услышать интервьюер: внешний мониторинг, «сторожевой» алерт, алерты на отсутствие данных.
Ответ
Мониторинг должен проверяться снаружи: внешняя проверка сайта и самого Prometheus из другого региона или сервиса. Второй приём — алерт, который горит всегда, как Watchdog в kube-prometheus, и уходит во внешний сервис: если сигнал перестал приходить, сломана цепочка алертинга. Третий — алерты на отсутствие данных: absent(up{job="node"}) и на возраст важных метрик, например времени последнего успешного бэкапа. У GitLab в 2017 году письма об ошибках бэкапа не доходили, и никто не знал, что бэкапов нет — см. сбой GitLab.
Инциденты
37. Прод лежит, ты дежурный. Что делаешь в первые 15 минут?
Что хочет услышать интервьюер: подтвердить и оценить влияние, объявить инцидент, сообщить, сначала восстановить, всё записывать.
Ответ
Подтверждаю алерт, чтобы его не взял кто-то ещё и не пошла лишняя эскалация. Проверяю влияние со стороны пользователя: что сломано и у кого. Объявляю инцидент рано. Книга Google SRE советует объявлять, если нужна вторая команда, сбой виден клиентам или проблема не решена за час анализа. Открываю канал инцидента и регулярно пишу статус. Смотрю последние изменения — релизы и конфиги — и сначала восстанавливаю сервис: откат, переключение трафика, масштабирование. Записываю действия со временем для постмортема. Не справляюсь — зову помощь по политике эскалации. См. первое дежурство.
38. Пять минут назад был релиз, и выросли ошибки. Откатывать или чинить вперёд?
Что хочет услышать интервьюер: сначала смягчить последствия; откат по умолчанию; когда он опасен.
Ответ
Если рост ошибок совпал с релизом, по умолчанию откатываю: это известное рабочее состояние и самый быстрый способ остановить ущерб. В книге Google SRE порядок такой: остановить кровотечение, восстановить сервис, сохранить улики для поиска причины. Чинить вперёд — только если откат невозможен или опаснее, например миграция необратима, а исправление маленькое и готово. Случайные правки на проде под давлением делают хуже: у Knight Capital в 2012 году удаление нового кода с семи исправных серверов усугубило сбой.
39. Инцидент идёт третий час, в канале 20 человек, все что-то пробуют. Как навести порядок?
Что хочет услышать интервьюер: роли командира инцидента, операций и коммуникаций и один источник правды.
Ответ
В книге Google SRE управление инцидентом построено на системе Incident Command. Командир держит общую картину и раздаёт роли. Операционная группа — единственная, кто меняет систему во время инцидента. Коммуникатор регулярно рассылает статус. Планирование занимается долгими вопросами: заявками, сменой людей, списком временных изменений, которые потом надо вернуть. Всё живёт в одном документе инцидента. Смена командира — явная, с подтверждением от нового. Параллельные несогласованные правки прекращаются.
40. Пришёл алерт по сервису, который ты не знаешь. Что делаешь?
Что хочет услышать интервьюер: runbook, эскалацию и осторожность.
Ответ
Открываю runbook из алерта и дашборд сервиса: есть ли влияние на пользователей. Если runbook покрывает ситуацию — действую по нему и записываю шаги. Если нет, а влияние есть — эскалирую владельцу сервиса или второй линии по политике. Эскалация — часть процесса, а не слабость: книга Google SRE советует следить за своим состоянием и звать поддержку, если чувствуешь, что не справляешься. Рискованные изменения в незнакомой системе вслепую не делаю. Алерт без runbook — готовая задача для постмортема. См. что такое on-call.
41. Инцидент закрыт. Что дальше?
Что хочет услышать интервьюер: постмортем без поиска виноватых и задачи с владельцами.
Ответ
Постмортем в ближайшие дни, пока детали свежие: резюме, влияние в цифрах, хронология, причины — отдельно триггер и условия, — что сработало и где повезло, задачи с владельцами и сроками. Разбор без поиска виноватых: вопрос не «кто ошибся», а «почему система это позволила». Задачи — в бэклог с контролем выполнения, выводы — всем, кого это касается. Подробнее — как писать постмортем и blameless-постмортем.
Как готовиться
Вопросы-ситуации не выучить по списку — нужен опыт, пусть и учебный. Соберите стенд и ломайте его: заполните диск, уроните сервис, сломайте DNS, выкатите образ с ошибкой. Читайте публичные постмортемы и пробуйте ответить, что сделали бы на месте дежурного. К домашнему заданию готовьтесь отдельно — см. тестовое задание DevOps.
Проверить себя на похожих ситуациях можно в бесплатном тесте навыков DevOps: 18 рабочих ситуаций, 10–15 минут, без регистрации.
Частые вопросы
Какие вопросы задают на собеседовании DevOps чаще всего? Ситуации по Linux и сетям, контейнерам, Kubernetes и CI/CD: что делать, если сервис не стартует, диск кончился, под падает или релиз сломал прод. Всё чаще спрашивают про инциденты и постмортемы: как вы действуете под давлением и что делаете после.
Как отвечать, если не знаешь ответа? Честно сказать и рассказать, как бы вы выясняли: какие команды запустили бы, где искали бы, кого спросили. Интервьюеру важен ход мысли, а выдуманный уверенный ответ обычно заметен со второго уточняющего вопроса.
Нужно ли знать точные флаги команд? Нужно знать, какой инструмент решает задачу и что он покажет. Точный флаг можно посмотреть в man, а понимание, что du и df могут расходиться из-за открытых удалённых файлов, в справке не найти.
Сколько времени готовиться к собеседованию DevOps? Зависит от опыта. Сисадмину с уверенным Linux и сетями обычно нужно подтянуть контейнеры, Kubernetes, CI/CD и инфраструктуру как код. Мерить готовность лучше не временем, а тем, сможете ли вы по шагам разобрать любой вопрос из этой подборки.
Источники
- Google. Site Reliability Engineering: Monitoring Distributed Systems — симптомы и причины, четыре золотых сигнала.
- Google. Site Reliability Engineering: Managing Incidents — роли в инциденте, когда объявлять инцидент, приоритеты.
- Linux man-pages. proc_loadavg(5) — что считает load average.
- Kubernetes. Pod Lifecycle и Deployments — фазы пода, backoff при перезапусках, параметры выкатки.
- Kubernetes. Resource Management for Pods and Containers — requests, limits, OOMKilled.
- Docker. Build cache, Build secrets, Configure logging drivers.
- Codecov. Post-Mortem / Root Cause Analysis (April 2021).
- Terraform. terraform plan, Backend S3, lifecycle.
- Git. git-reflog, git-bisect; GitHub. Removing sensitive data from a repository.
- SEC. Order in the matter of Knight Capital Americas LLC, 16.10.2013.
- AWS. Summary of the Amazon S3 Service Disruption, 2017.