Files
resume/stack/kubernetes/QUESTIONS.md

9.3 KiB
Raw Blame History

Вопросы: Kubernetes

Опираются на кейс: CASE.md. Источники реальных вопросов — Реалист банк.md, Bi.Zone.md, Alfa-Bank.md, VK Cloud.md, см. сводку в ../../interview/real-interviews.md.

Из чего состоит Kubernetes?

Control-plane — kube-apiserver (единая точка входа для всех операций), etcd (хранилище состояния кластера), kube-scheduler (распределяет поды по нодам), kube-controller-manager (следит за соответствием реального состояния желаемому). На worker-нодах — kubelet (управляет подами на своей ноде) и kube-proxy (сетевые правила доступа к Service), плюс container runtime (containerd). У себя в кластере (kind, 1 control-plane + 2 worker) я это видел напрямую через kubectl get pods -n kube-system.

etcd будет на одной виртуалке с K8s или отдельно?

В маленьких/pet-инсталляциях (у меня в kind) etcd живёт на той же control-plane ноде. В проде для отказоустойчивости etcd обычно выносят на отдельные ноды нечётным числом (3 или 5) — так работает кворум: при потере части узлов кластер etcd продолжает принимать решения, если жива больше половины. Consul в этом контексте — альтернатива service discovery/конфиг-хранилища, не замена etcd как хранилища состояния самого K8s.

Что такое DaemonSet?

Контроллер, который гарантирует, что на каждой (или на подмножестве по селектору) ноде кластера запущена ровно одна копия пода — используется для агентов уровня ноды: kube-proxy, CNI-плагин, node-exporter для мониторинга. В отличие от Deployment, DaemonSet не масштабируется числом реплик — он масштабируется вместе с числом нод: добавили ноду — на ней автоматически появился под DaemonSet.

Нарисуй два ЦОД под K8s с балансировщиком — на каких виртуалках это будет работать?

Внешний балансировщик (L4/L7, например HAProxy/облачный LB) перед двумя ЦОД → в каждом ЦОД — набор worker-нод под control-plane (control-plane лучше растянуть между ЦОД нечётным числом инстансов ради кворума etcd, например 3: 2 в одном ЦОД + 1 в другом, или 3+2 при пяти) → внутри кластера трафик до пода идёт через Service (ClusterIP/NodePort) и kube-proxy, который резолвит запрос в конкретный под по iptables/IPVS-правилам. Каждый ЦОД — набор физических/виртуальных worker-нод с kubelet и containerd. Я такую схему целиком не эксплуатировал (моя лаба — 3 ноды на одной машине), но принцип балансировки и роль каждого компонента понимаю и воспроизвёл в миниатюре.

Как будешь разворачивать PostgreSQL на две ноды K8s?

Через StatefulSet (не Deployment — под'ам БД нужны стабильные имена и отдельные PersistentVolume на каждую реплику) с master-replica топологией: обычно готовый оператор (например, CloudNativePG или Zalando Postgres Operator) заводит StatefulSet, PersistentVolumeClaim на каждую ноду и Service, разделяющий трафик на запись (к master) и на чтение (к репликам). Сам оператор в кластере не поднимал — но принцип репликации PostgreSQL прогнан отдельно в Docker Compose, см. ../databases/CASE.md; K8s тут просто уровень оркестрации поверх той же логики репликации.

Что такое Namespace и зачем он нужен?

Логическая изоляция ресурсов внутри одного кластера — разделение по окружениям (dev/stage/prod) или командам, без поднятия отдельных кластеров. Объекты в разных namespace могут называться одинаково и не конфликтуют; ресурсы вроде Node и PersistentVolume — не namespaced, они общие на весь кластер. В своей лабе завёл отдельный namespace demo под тестовое приложение и отдельный monitoring под kube-prometheus-stack — чтобы не мешать их друг другу и явно видеть границу через kubectl -n <namespace>.

Чем отличается ConfigMap от Secret?

ConfigMap — для несекретных конфигурационных данных (переменные окружения, конфиг-файлы), Secret — для чувствительных значений (пароли, токены, ключи). Технически Secret по умолчанию хранит значения в base64 — это кодирование, а не шифрование, то есть сам по себе Secret не «защищает» данные от того, кто имеет доступ к API/etcd. Для реальной защиты нужны либо шифрование etcd at rest, либо внешние системы вроде Vault (см. ../vault/CASE.md) или Sealed Secrets. В своём манифесте завёл и ConfigMap, и Secret и явно проверил разницу через kubectl get secret app-secret -o yaml — значение там закодировано base64, не зашифровано.

Какой у тебя опыт с Helm и разворотом кластеров K8s?

Helm — пакетный менеджер для K8s: чарт описывает набор шаблонизированных манифестов с параметрами в values.yaml, helm install/upgrade разворачивает/обновляет релиз одной командой вместо ручного kubectl apply на десяток файлов. У себя разворачивал kube-prometheus-stack через helm install в отдельный namespace — это дало сразу Prometheus + Grafana + Alertmanager + нужные ServiceMonitor-ресурсы с рабочими дефолтами, которые я после точечно переопределял через --set/values.yaml.

Как работает трафик в K8s?

Клиент → внешний балансировщик/Ingress-контроллер (роутинг по host/path) → Service (стабильный виртуальный IP/DNS-имя, абстракция над множеством подов) → kube-proxy на нодах транслирует обращение к Service в адрес конкретного пода по правилам iptables/IPVS, с балансировкой между подами, которые матчатся по selector в Service. Между подами внутри кластера — плоская сеть через CNI-плагин, любой под может обратиться к любому другому по его Pod IP или через Service DNS-имя (<service>.<namespace>.svc.cluster.local).

Как проверить логи и поды в кластере?

kubectl get pods -A — все поды по всем namespace; kubectl -n <ns> logs <pod> — логи контейнера, --previous — логи упавшего перед текущим рестартом контейнера; kubectl -n <ns> describe pod <pod> — события и причина, если под не стартует (ImagePullBackOff, CrashLoopBackOff); kubectl get events --sort-by=.lastTimestamp — хронология событий по всему namespace. Специально ронял под (указывал несуществующий образ) и разбирал describe, чтобы увидеть, как выглядит диагностика в реальности, а не в теории.