44 lines
9.3 KiB
Markdown
44 lines
9.3 KiB
Markdown
# Вопросы: 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`, чтобы увидеть, как выглядит диагностика в реальности, а не в теории.
|