сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · Инфраструктура данных

Kubernetes для дата-инженера

Kubernetes: желаемое состояние

Kubernetes оркеструет контейнеры декларативно: ты описываешь, что хочешь, а контроллеры это поддерживают. Собес для DE проверяет практичное - requests/limits, пробы и примитивы для джоб, а не всю глубину.

Стержень: описываешь желаемое состояние, контроллеры непрерывно приводят к нему факт; requests/limits и пробы - то, на чём спотыкаются в проде.

// Формулировки: «что такое requests и limits?», «зачем liveness и readiness?», «чем StatefulSet отличается от Deployment?».

Декларативность и объекты

K8s декларативен: в Deployment ты описываешь желаемое - образ, число реплик, ресурсы, а контроллеры непрерывно приводят фактическое состояние к нему. Упал под - поднимут, не хватает реплик - досоздадут.

Pod - минимальная единица (один или несколько контейнеров с общей сетью и томами). Deployment управляет ReplicaSet'ами и rolling-обновлением stateless-сервисов. Service - стабильный адрес поверх смертных подов (ClusterIP внутри, LoadBalancer наружу), Ingress - HTTP-маршрутизация по хостам и путям.

// Под в статусе Pending это не «кубер сломался»: kubectl describe pod покажет причину в событиях, обычно не хватает ресурсов или нет нод под селектор.

Pod / Deployment
единица запуска / управление репликами и раскаткой
Service / Ingress
стабильный адрес подов / HTTP-вход в кластер

Ресурсы и пробы

requests и limits - про ресурсы. По requests шедулер решает, на какую ноду поставить под (сколько он гарантированно займёт); limits - жёсткий потолок: CPU при достижении троттлится, память при превышении вызывает OOMKill. Без них нода перегружается и эвикшены случайны.

Пробы: liveness перезапускает зависшее, readiness не пускает трафик на ещё не готовое.

// Опасна неверная liveness-проба на медленную зависимость: если она дёргает тормозящую БД, k8s сочтёт здоровый, но медленный сервис мёртвым и устроит рестарт-шторм. Liveness проверяет сам процесс, а не его зависимости.

requests / limits
гарантия для шедулера / жёсткий потолок ресурсов
liveness / readiness
перезапуск зависшего / допуск трафика готовому

Примитивы для DE и диагностика

Для DE-задач ключевые примитивы: CronJob (регулярные джобы), Job (batch до завершения с ретраями), StatefulSet (БД и брокеры со стабильной идентичностью и постоянными дисками PVC). Стейтфул-базу нельзя гонять Deployment'ом без PVC (persistent volume claim) - новый под поднимется с пустыми данными.

Конфиг держат в ConfigMap, секреты - в Secret плюс внешние менеджеры; под получает их переменными или файлами, так что образ один на все среды.

// Диагностика начинается с трёх команд: kubectl describe pod (события - почему не шедулится или падает), logs (с --previous после рестарта), get events. 90% разборов - здесь, а не в гадании.

CronJob / Job
джобы по расписанию / batch до завершения с ретраями
StatefulSet / PVC
стейтфул со стабильной идентичностью и постоянным диском

Как отвечать: «Что такое requests/limits и зачем liveness/readiness?»

requests и limits описывают ресурсы пода. requests это сколько под гарантированно получает, и по ним шедулер выбирает ноду, где хватит места. limits - жёсткий потолок: при упоре в CPU-limit под троттлится, при превышении памяти его убивают OOMKill. Без requests и limits нода легко перегружается, соседи страдают, а вытеснения становятся случайными, поэтому их ставят всегда. Пробы - про здоровье. Liveness проверяет, жив ли сам процесс: если он завис, k8s его перезапустит. Readiness проверяет, готов ли под принимать трафик: пока идёт прогрев или зависимости не поднялись, трафик на него не шлют. Главная ловушка - вешать liveness на внешнюю зависимость вроде БД: если база тормозит, проба решит, что здоровый сервис мёртв, и устроит рестарт-шторм. Поэтому liveness смотрит на сам процесс, а готовность зависимостей это readiness.

Почему это сильный ответ: разведены requests (шедулинг) и limits (потолок с CPU-троттл/OOMKill), и liveness/readiness с классической ловушкой (liveness на зависимость = рестарт-шторм).

На чём валят

  • Без requests/limits - нода перегружена, соседи страдают, эвикшены случайны.
  • Liveness-проба на медленную зависимость - рестарт-шторм при тормозах БД.
  • Стейтфул БД Deployment'ом без PVC - новый под, пустые данные.
  • CronJob без concurrencyPolicy: прошлый запуск не докрутил - второй бежит параллельно, дубли.
  • Pending-под и «кубер сломался» - describe показал бы: не хватает ресурсов или нет нод под селектор.

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 11, остальные разбираются в тренажёре.

  1. #kubernetes1 / 5
    Что делает Deployment в Kubernetes?
    A)Deployment создаёт один под ровно один раз и при его падении никак не восстанавливает его
    B)Deployment хранит данные приложения на диске, выступая постоянным хранилищем состояния
    C)Поддерживает N реплик, self-heal, rolling update/rollback
    D)Deployment обновляет приложение с полной остановкой всех подов и последующим запуском
    показать ответ и разбор
    +C)Поддерживает N реплик, self-heal, rolling update/rollback

    // разбор: Deployment — контроллер, декларативно управляющий stateless-приложением: ты указываешь образ и число реплик, а он поддерживает это состояние — создаёт поды, пересоздаёт упавшие (самовосстановление), при смене образа катит обновление постепенно (rolling update: поднимает новые поды, гасит старые, без простоя) и умеет откатиться на прошлую версию. Так не управляют подами вручную. Для stateful-нагрузок (БД с идентичностью подов) есть StatefulSet, для батчей — Job/CronJob, а Deployment — рабочая лошадка для сервисов.

  2. #kubernetes2 / 5
    Зачем контейнеру в Kubernetes задают resources requests и limits?
    A)Requests и limits задают, в каком порядке поды будут выполняться на узле по приоритету
    B)Limit обеспечивает ресурсы поду, а request задаёт максимальный потолок его потребления
    C)Их задавать необязательно: Kubernetes сам поровну делит все ресурсы узла между всеми подами
    D)Request — гарантия для планировщика; limit — потолок (OOMKill/троттл)
    показать ответ и разбор
    +D)Request — гарантия для планировщика; limit — потолок (OOMKill/троттл)

    // разбор: Requests и limits управляют ресурсами пода. Request (CPU/память) — сколько гарантированно нужно: планировщик размещает под только на узел, где столько есть, и резервирует это. Limit — жёсткий потолок: контейнер, превысивший лимит памяти, убивается (OOMKilled и перезапускается), а по CPU — троттлится. Без них один прожорливый под может выесть ресурсы узла и уронить соседей (noisy neighbor). Для дата-нагрузок (Spark-executors, тяжёлые трансформации) корректные requests/limits критичны: заниженные ведут к OOMKilled-подам, завышенные — к простою ресурсов.

  3. #kubernetes3 / 5
    Зачем в Kubernetes конфигурацию и секреты выносят в ConfigMap и Secret, а не в образ?
    A)Конфиг/секреты снаружи → один образ на все среды, секретов в образе нет
    B)Чтобы пересобирать образ заново под каждую среду, вшивая в него её конкретную конфигурацию
    C)ConfigMap и Secret хранят сами данные приложения, заменяя ему базу данных в кластере
    D)Секреты безопаснее всего хранить прямо в образе — так они не покидают контейнер приложения
    показать ответ и разбор
    +A)Конфиг/секреты снаружи → один образ на все среды, секретов в образе нет

    // разбор: ConfigMap хранит конфигурацию (параметры, адреса), Secret — чувствительные данные (пароли, токены, ключи), отдельно от образа. K8s подставляет их в под как переменные окружения или файлы. Выгода: один и тот же неизменяемый образ едет из dev в prod, а различается лишь подставляемым конфигом (12-factor); секреты не вшиты в образ (иначе они утекли бы в реестр и в git). Захардкодить пароль в Dockerfile/код — грубая ошибка безопасности. Secret по умолчанию лишь base64 (не шифрование), поэтому его защищают RBAC и внешними хранилищами.

  4. #kubernetes4 / 5
    Чем Job/CronJob в Kubernetes отличается от Deployment и для чего они дата-инженеру?
    A)Job и CronJob держат сервис запущенным вечно, а Deployment выполняет задачу один раз и останавливается
    B)Job — batch до завершения, CronJob — по расписанию; Deployment — постоянный сервис
    C)Job и Deployment — полные синонимы, разница лишь в названии контроллера в разных версиях K8s
    D)CronJob — это то же, что Deployment, но с добавленным ограничением по потреблению памяти пода
    показать ответ и разбор
    +B)Job — batch до завершения, CronJob — по расписанию; Deployment — постоянный сервис

    // разбор: Deployment держит долгоживущий сервис (его поды должны работать всегда). Job — контроллер для задач, которые выполняются до успешного завершения и заканчиваются (батч-обработка, миграция, разовый пересчёт): запустил под, дождался успеха, остановил, при падении — ретрай. CronJob запускает Job по cron-расписанию (ночная агрегация, регулярная выгрузка). Дата-инженеру это нативный способ гонять батч-задачи в K8s без отдельного оркестратора — хотя для сложных пайплайнов с зависимостями всё равно берут Airflow (часто поверх K8s).

  5. #kubernetes5 / 5
    Что даёт запуск Spark или Airflow на Kubernetes (KubernetesExecutor, Spark on K8s)?
    A)Это заставляет все задачи выполняться в одном общем постоянном поде без какой-либо изоляции
    B)Запуск на K8s убирает необходимость в самих Spark и Airflow, заменяя их собой
    C)Эластичность и изоляцию: под каждую задачу/executor поднимается отдельный под с своими ресурсами, а после завершения освобождается
    D)Это фиксирует ресурсы под пул воркеров, независимо от наличия текущих задач
    показать ответ и разбор
    +C)Эластичность и изоляцию: под каждую задачу/executor поднимается отдельный под с своими ресурсами, а после завершения освобождается

    // разбор: На K8s дата-фреймворки берут ресурсы динамически. Airflow KubernetesExecutor запускает каждую задачу в отдельном поде: задача получает свои ресурсы и зависимости (свой образ), изолирована от других, а под гасится по завершении — не нужен постоянный пул воркеров. Spark on K8s поднимает executors как поды под конкретную джобу и освобождает их после. Выгода — эластичность (платишь/держишь ресурсы только на время работы), изоляция задач по образам и лимитам, единая инфраструктура. Плата — накладные на старт пода и сложность кластера.

дальше

Теорию прочитали. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.