Вопросы с собеседований по DevOps — devoops

Чем отличаются права 644 и 755 и почему у каталогов обычно 755?

junior · Linux

Цифры — это чтение (4), запись (2) и выполнение (1) для владельца, группы и остальных.

У каталога бит x означает не «запустить», а «войти внутрь». Без него нельзя обратиться к файлу по пути, даже зная имя и имея права на сам файл. Поэтому каталогам нужен 755, а обычным файлам — нет.

Что проверяют: понимаете ли вы, что x у каталога и у файла значит разное. Это самая частая причина «permission denied» там, где права на файл выглядят правильными.

В чём разница между образом и контейнером?

junior · Контейнеры

Образ — неизменяемый набор слоёв файловой системы плюс метаданные о том, что запускать. Контейнер — процесс, запущенный из образа, с добавленным поверх записываемым слоем.

Из одного образа можно запустить сколько угодно контейнеров, и каждый получит свой пустой записываемый слой. Всё, что контейнер туда напишет, исчезнет вместе с ним — поэтому данные выносят в volume.

Аналогия «образ — класс, контейнер — объект» работает, но не объясняет слои, а именно из-за них образ пересобирается быстро и занимает меньше, чем кажется.

Что происходит между вводом адреса в браузере и ответом сервера?

junior · Сети

Коротко: разрешение имени → установка соединения → запрос → ответ.

  1. DNS: браузер спрашивает у резолвера IP по имени. Ответ кешируется, поэтому старая запись живёт дольше, чем ожидаешь.
  2. TCP-рукопожатие с этим IP на порт 443.
  3. TLS: сервер предъявляет сертификат, стороны договариваются о ключах.
  4. HTTP-запрос, ответ, закрытие или переиспользование соединения.

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

Connection refused и connection timeout — в чём разница?

junior · Сети

Refused — пакет дошёл, хост ответил RST: на этом порту никто не слушает. Значит, сеть в порядке, а сервис не запущен или слушает другой адрес (частый случай — 127.0.0.1 вместо 0.0.0.0).

Timeout — ответа не было вообще. Пакет где-то отбросили молча: firewall с политикой DROP, security group, неправильный маршрут.

Это первое ветвление при диагностике: refused отправляет смотреть на сервис, timeout — на сеть между вами.

Когда merge, а когда rebase?

junior · Git

merge сохраняет историю как она была и добавляет коммит слияния. rebase переписывает ваши коммиты поверх новой базы, история становится линейной.

Практическое правило: rebase — для своей ветки, которую ещё никто не забрал; merge — для всего, что уже опубликовано. Rebase меняет хеши, поэтому у того, кто успел спуллить, ветка разъедется.

Что проверяют: скажете ли вы про «не переписывать общую историю». Без этого ответ выглядит как вкусовщина.

Continuous delivery и continuous deployment — это одно и то же?

junior · CI/CD

Нет. В обоих случаях каждое изменение автоматически собирается и проходит проверки. Разница в последнем шаге:

Deployment требует того, что delivery прощает: хорошего покрытия тестами, мониторинга, который заметит проблему раньше пользователей, и быстрого отката. Ответ «у нас CD» без этих трёх вещей — обычно delivery.

Зачем нужен Deployment, если можно создать Pod?

junior · Kubernetes

Pod — единица запуска, но сам по себе он смертен: упала нода — Pod исчез, и никто его не вернёт.

Deployment описывает желаемое состояние («хочу три реплики такого-то Pod») и через ReplicaSet следит, чтобы оно выполнялось. Он же умеет обновлять версию постепенно и откатываться.

Одиночный Pod осмыслен только для отладки. В проде за ним всегда стоит контроллер — Deployment, StatefulSet или DaemonSet, смотря что нужно.

Что такое идемпотентность и почему на ней настаивают в IaC?

junior · Автоматизация

Идемпотентная операция даёт один и тот же результат независимо от того, применили её один раз или десять.

useradd deploy не идемпотентна: второй запуск завершится ошибкой. Описание «пользователь deploy существует» — идемпотентно: инструмент сам посмотрит, что есть, и сделает только недостающее.

Это позволяет применять конфигурацию повторно, не боясь: после сбоя на середине можно просто запустить заново. Без идемпотентности каждый повторный прогон требует помнить, что уже успело выполниться — а именно этого IaC и должен избавлять.

Процесс завис и не отвечает. Как понять, что с ним происходит?

middle · Linux

По порядку, от дешёвого к дорогому:

  1. ps -o stat= -p PID — состояние. D означает непрерываемый сон, почти всегда ожидание диска или сети; такой процесс не убьётся даже SIGKILL.
  2. cat /proc/PID/wchan — в какой функции ядра он стоит.
  3. ss -tnp | grep PID — висит ли соединение.
  4. strace -p PID — на каком системном вызове застрял. Дорого, тормозит процесс, поэтому в последнюю очередь.

Что проверяют: пойдёте ли вы сразу перезапускать. Ответ «перезапустил, помогло» на middle-позиции не засчитывается — нужно назвать, что именно посмотрите до перезапуска.

Образ весит 1.5 ГБ. Как уменьшить и за счёт чего это работает?

middle · Контейнеры

Основные приёмы, по убыванию эффекта:

  1. Многостадийная сборка. Компилятор, заголовочные файлы и кеш пакетного менеджера нужны при сборке, но не в рантайме. Копируем из стадии сборки только артефакт.
  2. База поменьше. alpine или distroless вместо полного дистрибутива.
  3. Чистка в том же слое. apt-get install && rm -rf /var/lib/apt/lists/* одной командой. Отдельным RUN файлы останутся в предыдущем слое — слои только добавляются, удаление в следующем слое ничего не освобождает.
  4. Порядок слоёв. Зависимости ставим до копирования исходников, тогда кеш не инвалидируется при каждом изменении кода.

Что проверяют: понимаете ли вы, что слои неизменяемы. Пункт 3 без этого объяснения — заученный рецепт.

Pod висит в Pending. С чего начнёте?

middle · Kubernetes

kubectl describe pod и смотреть события внизу — там почти всегда написана причина.

Типичные:

Что проверяют: пойдёте ли вы в события или начнёте перезапускать и пересоздавать. Pending — это состояние «планировщик не смог», и он объясняет почему.

Чем liveness отличается от readiness и что будет, если их перепутать?

middle · Kubernetes

Readiness отвечает на вопрос «можно ли слать сюда трафик». Провал — Pod убирают из Service, но не трогают.

Liveness отвечает на «жив ли процесс». Провал — контейнер перезапускают.

Если поставить liveness туда, где нужен readiness (например, проверять доступность базы), то при недоступной базе Kubernetes начнёт перезапускать все реплики по кругу. База от этого не поднимется, а приложение будет гарантированно недоступно — вы своими руками превратите частичный отказ в полный.

Обратная ошибка тише: зависший процесс останется в строю и будет отдавать ошибки, пока кто-нибудь не заметит.

Когда нужна метрика, когда лог, а когда трейс?

middle · Наблюдаемость

Порядок в инциденте обычно такой же: метрика показала, что сломалось; трейс — в каком сервисе; лог — почему.

Частая ошибка — писать в метрику то, что должно быть логом. Метка с высокой кардинальностью (ID пользователя, URL с параметрами) создаёт отдельный временной ряд на каждое значение и рано или поздно кладёт хранилище.

Как убедиться, что бэкапы рабочие?

middle · Эксплуатация

Единственный способ — регулярно восстанавливаться из них в отдельное окружение и проверять результат автоматически: поднялась ли база, сходится ли количество записей, открывается ли приложение.

Успешно завершившийся job бэкапа не значит ничего. Типичные способы получить бесполезный архив: дамп снят без нужных прав и молча пропустил часть таблиц; архив бьётся при записи и никто не проверяет контрольную сумму; ретеншен удалил всё старше недели, а проблему заметили через две.

Здесь же стоит назвать RPO и RTO — сколько данных допустимо потерять и за сколько нужно подняться. Без этих двух чисел «бэкапы есть» не отвечает ни на один вопрос бизнеса.

Зачем нужен пул соединений к базе и что будет без него?

middle · Данные

Установка соединения с Postgres стоит дорого: TCP, аутентификация, а на сервере — отдельный процесс на каждое соединение. Пул держит несколько открытых и переиспользует их.

Без пула под нагрузкой приложение открывает соединение на запрос и упирается в max_connections, после чего база начинает отказывать всем, включая уже работающие сервисы.

Важный нюанс при масштабировании: размер пула умножается на количество реплик. Десять подов по двадцать соединений — это двести, и в max_connections по умолчанию они не поместятся. Поэтому перед базой обычно ставят внешний пулер вроде PgBouncer.