Files
resume/stack/kubernetes/QUESTIONS.md

44 lines
9.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Вопросы: Kubernetes
Опираются на кейс: [CASE.md](CASE.md). Источники реальных вопросов — [Реалист банк.md](../../interview/Реалист%20банк.md), [Bi.Zone.md](../../interview/Bi.Zone.md), [Alfa-Bank.md](../../interview/Alfa-Bank.md), [VK Cloud.md](../../interview/VK%20Cloud.md), см. сводку в [../../interview/real-interviews.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](../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](../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`, чтобы увидеть, как выглядит диагностика в реальности, а не в теории.