Kubernetes: основы
От backend-разработчика не ждут, что он админ кластера. Но ждут, что он понимает, во что превращается его сервис в k8s: под, Deployment, Service, конфиг, пробы, ресурсы. По этим ответам видно, деплоил человек в прод или только слышал слово «кубер».
Мы пройдём по цепочке: как запускается (Pod/Deployment), как его находят (Service), откуда берётся конфиг (ConfigMap/Secret) и что удерживает выкатку от ошибок (пробы, ресурсы, graceful shutdown).
Pod, Deployment, Service
Под - минимальная единица запуска: один-два контейнера с общим IP и namespace. Поды эфемерны: их создают и убивают, IP меняется. Голый под никто не воскресит, поэтому им управляет Deployment - он держит заданное число реплик, пересоздаёт упавшие и катит rolling update при смене образа.
Раз поды эфемерны, ходить на их IP нельзя. Стабильную точку входа даёт Service: у него постоянные DNS-имя и виртуальный IP, а за ним k8s держит список живых подов (endpoints) и балансирует на них. Клиент обращается к имени сервиса, не зная, какие поды сейчас живы.
- Pod
- эфемерная единица запуска контейнеров
- Deployment
- реплики + rolling update + воскрешение
- Service
- стабильный адрес поверх живых подов
Конфиг, пробы, ресурсы
Конфиг выносят из образа (12-factor): несекретное - в ConfigMap, чувствительное - в Secret (это base64, не шифр; защита добавляется RBAC и шифрованием etcd). Их монтируют переменными окружения или файлом, и один образ работает во всех средах.
Выкатку удерживают пробы: liveness перезапускает зависший контейнер, readiness решает, пускать ли трафик - неготовый под исключается из endpoints. Ресурсы задают requests (гарантия для планировщика) и limit (потолок; память сверх лимита → OOMKilled). HPA (horizontal pod autoscaler) меняет число реплик по метрике нагрузки.
readinessProbe:
httpGet: { path: /healthz, port: 8080 }
initialDelaySeconds: 3- RBAC
- role-based access control
Как отвечать: «Чем liveness отличается от readiness?»
Liveness отвечает на вопрос «жив ли процесс»: провалилась - k8s перезапускает контейнер, это лечит зависания. Readiness - «готов ли принимать запросы»: пока сервис не прогрелся и не поднял коннекты, под исключается из балансировки, но не рестартится. Во время rolling update именно readiness держит трафик от неготовых подов, поэтому путать их - значит ловить всплеск ошибок на каждой выкатке.
Показывает понимание жизненного цикла пода и того, что делает выкатку безопасной, а не заученные определения.
На чём валят
- −Ходить на под по IP: он эфемерен, поменяется при пересоздании - только через Service.
- −Путать liveness и readiness: рестартит liveness, из трафика убирает readiness.
- −Писать логи в файл внутри пода: ФС (файловая система) эфемерна, под умер - логи ушли; пиши в stdout.
- −Заниженный memory-limit → OOMKilled под нагрузкой; секреты класть в ConfigMap, а не Secret.
Проверьте себя
Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.
- Зачем нужен Deployment, если под и так можно создать?A)Deployment хранит переменные окружения и конфиги, недоступные обычному подуB)Держит N реплик, катит обновления и пересоздаёт упавшие подыC)Deployment открывает сервису внешний порт и балансирует трафик между подамиD)Он собирает Docker-образ приложения из исходников прямо внутри кластера при каждом релизе
показать ответ и разбор
+B)Держит N реплик, катит обновления и пересоздаёт упавшие поды// разбор: Deployment описывает желаемое состояние: сколько реплик пода держать и из какого образа. Контроллер приводит реальность к этому: пересоздаёт упавшие поды, при смене образа катит rolling update. Голый под никто не воскресит — умер и умер.
- Поды эфемерны, их IP меняются. Как один сервис стабильно находит другой внутри кластера?A)Захардкодив IP конкретного пода в конфиг клиента при деплоеB)Опрашивая kube-apiserver из кода при каждом запросе, чтобы узнать текущий IP подаC)Через Service — стабильные имя и виртуальный IP поверх подовD)Складывая актуальные адреса подов в общий файл на диске и перечитывая его
показать ответ и разбор
+C)Через Service — стабильные имя и виртуальный IP поверх подов// разбор: Service — стабильная точка входа: у неё постоянные DNS-имя и виртуальный IP, а за ней k8s держит актуальный список живых подов (endpoints) и балансирует на них. Клиент ходит на имя сервиса, не зная и не завися от того, какие поды сейчас живы и где.
- В чём разница между liveness- и readiness-пробами?A)Это два имени одной и той же проверки, оставленные для обратной совместимостиB)Liveness проверяет диск узла, readiness — доступность внешней базы данныхC)Readiness перезапускает контейнер, а liveness временно убирает под из-под трафика до восстановленияD)Liveness — перезапустить зависший под; readiness — пускать ли трафик
показать ответ и разбор
+D)Liveness — перезапустить зависший под; readiness — пускать ли трафик// разбор: Liveness-проба отвечает на вопрос «жив ли процесс»: провалилась — k8s перезапускает контейнер (лечит зависания/дедлоки). Readiness-проба — «готов ли принимать запросы»: пока не готов (прогрев, коннект к БД), под исключается из endpoints сервиса, но не рестартится. Путаница между ними ломает выкатки.
- Куда в k8s выносят несекретный конфиг приложения (URL-ы, флаги, размеры пулов)?A)В ConfigMap — и монтируют как env или файлB)Прямо в Docker-образ на этапе сборки, чтобы конфиг ехал вместе с кодомC)В имя Deployment, откуда приложение считывает его при старте подаD)В отдельную таблицу PostgreSQL, которую сервис читает при каждом обращении к настройкам
показать ответ и разбор
+A)В ConfigMap — и монтируют как env или файл// разбор: ConfigMap хранит несекретную конфигурацию (адреса, флаги, числовые параметры) вне образа: её монтируют в под переменными окружения или файлом. Так один образ работает во всех средах, а различия среды описаны декларативно — это прямое следствие 12-factor.
- Пароль к БД и токен внешнего API в k8s кладут в Secret, а не в ConfigMap. Что реально даёт Secret?A)Secret автоматически шифрует значение стойким алгоритмом на уровне приложенияB)Отдельный тип для чувствительного: контроль доступа и base64-хранениеC)Secret скрывает значение даже от подов, которые его монтируют, отдавая лишь хешD)Никакой разницы с ConfigMap нет, это исторический дубликат с другим именем для тех же данных
показать ответ и разбор
+B)Отдельный тип для чувствительного: контроль доступа и base64-хранение// разбор: Secret — отдельный ресурс под чувствительные данные: он хранится в base64 (это кодирование, не шифрование), но к нему применяют RBAC-доступ, шифрование etcd и правила, отличные от обычного конфига. Разделение с ConfigMap важно, чтобы секреты не текли в логи, дампы и общие настройки.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.