Подготовка к алгоритмическим задачам

Собеседование DevOps-инженера: вопросы и что за ними стоит
Коротко
| Блок | Доля вопросов |
|---|---|
| Linux и сети | ~25% |
| Docker и Kubernetes | ~25% |
| CI/CD | ~20% |
| Инфраструктура как код | ~15% |
| Мониторинг и надёжность | ~15% |
Особенность DevOps-собеседований: вопросы почти всегда практические. Вместо «что такое X» спрашивают «как бы вы это диагностировали».
Блок 1. Linux
Как найти, что занимает место на диске
df -h # свободное место по разделам du -sh /var/* | sort -h # что занимает место lsof +L1 # удалённые, но открытые файлы
Последняя команда — важная деталь. Классическая ситуация: файл удалили, но процесс держит дескриптор, и место не освобождается. df показывает занятое, du — нет. Знание этого случая сразу выделяет кандидата.
Процесс потребляет 100% CPU: что делать
top -H -p <pid> # какие потоки грузят strace -p <pid> # системные вызовы perf top -p <pid> # где именно в коде cat /proc/<pid>/status # состояние процесса
Оценивают не знание команд, а последовательность действий: сузить область, собрать данные, сделать вывод.
Разница между сигналами
SIGTERM (15) — вежливая просьба завершиться, процесс может её обработать. SIGKILL (9) — принудительное завершение ядром, перехватить нельзя.
Практический вывод: kill -9 не даёт приложению закрыть соединения и сбросить буферы. Именно поэтому Kubernetes сначала шлёт SIGTERM и только после terminationGracePeriodSeconds — SIGKILL.
Решай алгоритмические задачи как профи

Права и SUID
chmod 644 file # rw-r--r-- chmod 755 dir # rwxr-xr-x
Первая цифра — владелец, вторая — группа, третья — остальные. 4 чтение, 2 запись, 1 выполнение.
Про SUID спрашивают отдельно: бит, позволяющий запускать файл с правами владельца. Классический пример — passwd. И классическая уязвимость, если поставить его не туда.
Блок 2. Docker
Чем контейнер отличается от виртуальной машины
Контейнер использует ядро хоста и изолируется через namespaces и cgroups. Виртуальная машина запускает собственное ядро поверх гипервизора.
| Контейнер | ВМ | |
|---|---|---|
| Ядро | общее с хостом | своё |
| Запуск | секунды | минуты |
| Размер | мегабайты | гигабайты |
| Изоляция | слабее | сильнее |
Последняя строка важна: контейнеры не панацея для многоарендных сред, где нужна жёсткая изоляция.
Как уменьшить размер образа
# многостадийная сборка: инструменты не попадают в финальный образ FROM golang:1.22 AS builder WORKDIR /src COPY . . RUN go build -o app FROM alpine:3.19 COPY /src/app /app CMD ["/app"]
Плюс: базовый образ поменьше (alpine, distroless), объединение слоёв RUN, .dockerignore, отсутствие кэша пакетного менеджера.
Порядок слоёв и кэш
# плохо: любое изменение кода инвалидирует установку зависимостей COPY . . RUN npm ci # хорошо: зависимости кэшируются отдельно COPY package*.json ./ RUN npm ci COPY . .
Этот вопрос задают почти всегда — он показывает, понимаете ли вы механику слоёв.
CMD против ENTRYPOINT
ENTRYPOINT — что запускается всегда. CMD — аргументы по умолчанию, которые можно переопределить при docker run.
Блок 3. Kubernetes
Что происходит при kubectl apply
- Запрос идёт в API-сервер, проходит аутентификацию и валидацию.
- Объект сохраняется в etcd.
- Контроллер замечает расхождение желаемого и текущего состояния.
- Планировщик выбирает узел.
- Kubelet на узле создаёт под через среду выполнения контейнеров.
Ответ показывает понимание декларативной модели: вы описываете желаемое состояние, а контроллеры приводят к нему систему.
Под в состоянии CrashLoopBackOff: как разбираться
kubectl describe pod <name> # события, причина kubectl logs <name> --previous # логи упавшего контейнера kubectl get events --sort-by=.lastTimestamp
Типичные причины: ошибка в приложении, нехватка памяти (OOMKilled), неверная проба готовности, отсутствие секрета или конфига, неправильная команда запуска.
Что оценивают: системность диагностики, а не заученный список.
Liveness против readiness
liveness — жив ли контейнер. При провале под перезапускается.
readiness — готов ли принимать трафик. При провале под убирается из сервиса, но не перезапускается.
Классическая ошибка: указать в liveness проверку внешней зависимости. База недоступна — приложение перезапускается по кругу, хотя проблема не в нём.
Requests и limits
requests — гарантированные ресурсы, по ним планировщик выбирает узел. limits — потолок.
Тонкость: превышение лимита памяти означает немедленное убийство контейнера (OOMKilled). Превышение лимита CPU — только замедление (throttling). Разница принципиальная, и её спрашивают.
Блок 4. CI/CD
Разница между непрерывной поставкой и развёртыванием
Continuous Delivery — сборка автоматически готова к выкладке, но релиз запускает человек. Continuous Deployment — выкладка происходит автоматически при прохождении тестов.
Стратегии выкладки
| Стратегия | Суть | Откат |
|---|---|---|
| Rolling | поды заменяются постепенно | медленный |
| Blue-green | две среды, переключение трафика | мгновенный |
| Canary | часть трафика на новую версию | быстрый |
Про canary спрашивают отдельно: как определить, что версия плохая. Ответ — метрики ошибок и задержек с автоматическим откатом по порогу.
Как хранить секреты
Плохо: в репозитории, в переменных окружения открытым текстом, в образе.
Хорошо: Vault, облачные менеджеры секретов, sealed secrets, внешние провайдеры для Kubernetes.
Вопрос «что делать, если секрет утёк в git» тоже частый. Правильный ответ начинается с ротации, а не с переписывания истории: секрет уже скомпрометирован, историю могли скачать.
Блок 5. Инфраструктура как код
Terraform: state и зачем он нужен
Файл состояния хранит соответствие между конфигурацией и реальными ресурсами. Без него Terraform не знает, что уже создано.
Практические вопросы: где хранить (удалённый бэкенд с блокировкой), что делать при расхождении (terraform import, refresh), почему нельзя править вручную.
Идемпотентность
Повторный запуск не должен ничего менять, если состояние уже целевое. На этом строятся и Terraform, и Ansible.
Вопрос-проверка: «чем command в Ansible отличается от специализированного модуля». Ответ: command не идемпотентен, выполняется всегда; модуль проверяет состояние и меняет только при необходимости.
Блок 6. Мониторинг
Четыре золотых сигнала
Задержка, трафик, ошибки, насыщенность. Базовый набор для любого сервиса.
SLI, SLO, SLA
SLI — измеряемый показатель (доля успешных запросов). SLO — внутренняя цель (99.9%). SLA — договор с клиентом и штрафы.
Отсюда бюджет ошибок: при SLO 99.9% допустимы 43 минуты недоступности в месяц. Пока бюджет не израсходован — команда катит новые фичи; израсходован — фокус на надёжности.
Метрики против логов против трассировок
Метрики — числа во времени, дёшево, отвечают «что-то не так». Логи — события, дорого, отвечают «что именно». Трассировки — путь запроса через сервисы, отвечают «где именно».
Как отвечать
Формат почти всех вопросов — «как бы вы диагностировали». Отвечайте последовательностью действий, а не списком команд:
«Сначала посмотрю, локальная ли проблема или общая — метрики по всем инстансам. Потом сужу до конкретного сервиса по трассировкам. Затем логи за нужный интервал. Если видно рост задержек без роста ошибок — скорее всего ресурсы или внешняя зависимость».
Такой ответ ценится выше, чем перечисление утилит.
Что запомнить
- Вопросы практические: ждут алгоритм диагностики, а не определения.
- Контейнер делит ядро с хостом — отсюда скорость и более слабая изоляция.
- Порядок слоёв в Dockerfile определяет эффективность кэша.
- Liveness перезапускает под, readiness убирает из балансировки; не проверяйте внешние зависимости в liveness.
- Превышение лимита памяти убивает контейнер, лимита CPU — только замедляет.
- Утёкший секрет требует ротации, а не чистки истории.
