17 вопросов по Kubernetes, которые может услышать разработчик на собеседовании

image

Kubernetes прочно вошел в технологический стек разработки cloud-native-приложений, став мейнстримовой технологией.

Разработчику, конечно же, не нужно быть экспертом по Kubernetes, чтобы запустить в нем свое приложение. Но понимание азов даст лучшее представление о том, как приложение живет и работает в Kubernetes.

Мы собрали список вопросов про Kubernetes, с которыми может столкнуться разработчик на собеседовании, подготовили короткие ответы и ссылки на более подробную информацию в документации и не только.

Если есть свободные 20 минут, приглашаем устроить внеплановую ревизию своих знаний.

Вопрос 1. Что такое контейнеры? Чем они отличаются от виртуальных машин?


Да, может показаться странным, что кто-то этого может не знать в 2023 году, но опыт показывает, что пробелы в знаниях могут обнаруживаться там, где их совсем не ждешь.

Контейнеры — это сущность, которая содержит в себе все зависимости (системные библиотеки, сторонние пакеты кода и прочее), необходимые для запуска приложения. Контейнеры позволяют быстро запускать приложения без оглядки на окружающую среду.

И контейнеры, и виртуальные машины — это технологии виртуализации ресурсов.

Основное различие контейнеров и виртуальных машин заключается в том, что виртуальные машины виртуализируют весь компьютер/сервер вплоть до аппаратного уровня. На виртуальную машину можно установить любую гостевую ОС, и она может быть отличной от ОС компьютера/сервера.

Контейнеры же виртуализируют только то, что выше уровня операционной системы. То есть контейнеры делят друг с другом ядро операционной системы, которая установлена на сервере. Благодаря этому контейнеры занимают меньше ресурсов и быстрее запускаются. В то же время контейнеры не так изолированы друг от друга, как виртуальные машины.

Контейнеры — это сущность, которая содержит в себе все зависимости (системные библиотеки, сторонние пакеты кода и прочее), необходимые для запуска приложения. Контейнеры позволяют быстро запускать приложения без оглядки на окружающую среду.

И контейнеры, и виртуальные машины — это технологии виртуализации ресурсов.
Основное различие контейнеров и виртуальных машин заключается в том, что виртуальные машины виртуализируют весь компьютер/сервер вплоть до аппаратного уровня. На виртуальную машину можно установить любую гостевую ОС, и она может быть отличной от ОС компьютера/сервера.

Контейнеры же виртуализируют только то, что выше уровня операционной системы. То есть контейнеры делят друг с другом ядро операционной системы, которая установлена на сервере. Благодаря этому контейнеры занимают меньше ресурсов и быстрее запускаются. В то же время контейнеры не так изолированы друг от друга, как виртуальные машины.

image

Вопрос 2. В чем разница stateful и stateless?


Если говорить применительно к приложениям, то Stateful-приложение — это то, которое сохраняет данные при работе как состояние внутри себя. Примером могут быть сессии пользователей, которые хранятся на сервере. Ответ на запрос пользователя зависит от состояния сессии.

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

Stateless — любой запрос к приложению уникален, а его ответ не зависит от какого-либо состояния приложения. Stateless-приложения легко масштабируются горизонтально, упрощают автоматизированное тестирование, так как нет состояния, которое нужно воспроизводить.

Вопрос 3. Docker-контейнер и runtime — это одно и то же?


Есть Docker как стандарт, по которому описываются контейнеры, а есть Docker-движок, он же runtime, — это то, что запускает контейнер.

В Kubernetes благодаря Container Runtime Interface (CRI) API в контейнерах можно запускать разные runtime, например CRI-O, Containerd.

Так как Docker-движок старше, чем Kubernetes, он не отвечает стандартам CRI, поэтому уже некоторое время Docker runtime не поддерживается в Kubernetes.

Но это не означает, что сами Docker-контейнеры нельзя использовать в Kubernetes.

За словом Docker действительно скрывается много всего, что вызывает путаницу. Об этом даже говорил сам Джо Беда, один из создателей Kubernetes. Так что вы точно не одиноки :)

image

Подробнее о том, как соотносятся контейнеры, Container Runtime, CRI и о судьбе Docker runtime в Kubernetes, можно почитать тут.

Вопрос 4. Что такое Kubernetes и зачем он нужен?


Kubernetes — это open-source-платформа для автоматизированного запуска, масштабирования и управления контейнеризированными приложениями.

С помощью Kubernetes можно:

  • запускать приложение в контейнере на нескольких серверах/площадках. Если ваши приложения работают на 2–3 серверах, то можно обойтись и без Kubernetes, но если их десятки и сотни, то дальнейшее масштабирование, управление и апдейт будет сложнее без дополнительного инструмента оркестрации. Как раз таким и является Kubernetes;
  • автоматически развертывать, апдейтить, откатывать назад обновления, управлять состоянием контейнеров;
  • управлять нагрузкой и оперативно масштабироваться в большую или меньшую сторону.


Если хотите блеснуть эрудицией, можно сказать, что Kubernetes — это детище Google, в k8s 8 означает 8 букв в слове kubernetes, а само название переводится с греческого как «кормчий, рулевой».

Вопрос 5. Как Kubernetes соотносится с Docker?


Docker — это один из общепринятых стандартов контейнеризации. С его помощью мы упаковываем приложения в контейнеры, автоматизируем их запуск и развертывание, управление их жизненным циклом. Docker позволяет запускать один контейнер на одном хосте. А что если нужно запустить несколько контейнеров на разных хостах и как-то ими управлять?

Вот здесь приходит на помощь Kubernetes, который помогает настраивать сетевую связность Docker-контейнеров, запущенных на разных хостах, и оркестровать их.

То есть Docker — контейнер, Kubernetes — платформа для управления контейнерами, или оркестратор контейнеров.

Вопрос 6. Назовите главные компоненты архитектуры Kubernetes


Master-ноды (master node, control plane) координируют все активности кластера: распределяют и резервируют ресурсы, управляют состоянием контейнеров, масштабируют, раскатывают обновления. Мастер-ноды состоят из следующих компонентов:

  • kube-apiserver — это точка входа в панель управления master-ноды. Он отвечает за взаимодействие между master- и worker-нодами, отслеживает состояние worker-узлов и оповещает master о важных изменениях;
  • kube-scheduler отвечает за распределение нагрузки на рабочие узлы, постоянно отслеживает, сколько ресурсов сейчас доступно и сколько из них задействовано под нагрузку на каждом узле. Он решает, на каком узле запускать новый Pod;
  • Controller Manager отвечает за работу контроллеров: Deployment, ReplicaSet, StatefulSets, DaemonSet, Jobs, CronJob;
  • ETCD хранит информацию о настройках и состоянии кластера, его метаданные. Представляет собой распределенную базу данных в формате ключ-значение.

Nodes (workers) — рабочие узлы в кластере. На них запускаются поды с контейнерами.

На каждой worker-ноде Kubernetes работают:

  • kubelet — процесс, который запускает, удаляет, обновляет поды с контейнерами;
  • kube-proxy — конфигурирует правила сети на рабочих узлах.


image
Схема архитектуры и основных компонентов Kubernetes

Вопрос 7. Что такое под (pod)?


Под — это самая маленькая сущность в Kubernetes, в которой запускаются контейнеры. Контейнеров внутри пода может быть несколько.

Помимо контейнеров, у каждого пода есть:

— уникальный IP-адрес, который позволяет подам общаться друг с другом;
— хранилище PV (по необходимости);
— данные по конфигурации, которые определяют, как контейнер должен запускаться.

image
Внутри пода может быть один или несколько контейнеров

Вопрос 8. Что такое пространство имен (namespaces)? Почему не стоит использовать одно namespace для всех приложений?


Пространства имен позволяют разделять кластер на виртуальные кластеры, в которых можно объединять приложения в группы по нужному принципу. При этом эти группы будут изолированы друг от друга. Благодаря этому можно, например, создать приложение с одинаковым именем в двух разных пространствах.

Если использовать только одно пространство имен, которое было по умолчанию при запуске кластера, то со временем будет сложно ориентироваться во всех запущенных там приложениях. Группировка приложений в разных пространствах имен упростит работу: например, можно в одном пространстве разместить приложение мониторинга, в другом — приложения, связанные с ИБ.

Другой сценарий, когда пригодится нескольких пространств имен, — это работа нескольких команд с одним кластером.

Вопрос 9. Какую функцию выполняет ReplicaSet?


Задача ReplicaSet (RS) — поддерживать работу определенного количества экземпляров подов в кластере Kubernetes. Это базовый строительный блок Kubernetes, который используется для запуска Stateless-приложения. RS часто используется для обеспечения доступности приложения. Если какие-то из подов покрашатся, то Kubernetes с помощью RS автоматически запускает новые экземпляры подов, чтобы заменить вышедшие из строя. Без RS пришлось бы их запускать вручную. Тем самым RS помогает сохранить приложение доступным для пользователей.

Вопрос 10. Что такое Deployment?


Deployment, по сравнению с ReplicaSet, — это абстракция более высокого уровня. Если ReplicaSet отвечает за то, чтобы поды были запущены и доступны, то Deployment помогает делать декларативные апдейты подов, используя ReplicaSet.

Когда для группы контейнеров нужно обновить версии или откатиться к предыдущей, мы используем Deployment.

Другие сценарии применения Deployment можно найти здесь.

Вопрос 11. За что отвечает StatefulSet?


StatefulSet управляет развертыванием и масштабированием группы подов, но при этом он дает возможность сохранять состояние и характеристики подов.

Например, если нужно, чтобы поды запускались в определенном порядке, на тех же нодах, чтобы при каждом запуске у каждого было хранилище (PVC) или какие-то специальные сетевые идентификаторы, используют StatefulSet.

Обычно он используется для запуска подов с очередями сообщений, брокеров и БД.

Вопрос 12. Какая роль у контроллера DaemonSet?


DaemonSet используется в Kubernetes, когда нужно запустить один или несколько подов на всех рабочих узлах кластера. То есть при запуске новых нод вам не потребуется вручную запускать поды, которые должны там быть для каких-то служебных задач. Например, с помощью него можно запустить поды с Prometheus Node Exporter для мониторинга, collectd или поды с fluentd or logstash для логирования узлов.

Примечание: это не полный список контроллеров, есть еще Jobs.

Вопрос 13. Как в Kubernetes устроена работа с хранилищами?


У Kubernetes есть volumes, например, нативный emtyDir. Часть из них stateless, то есть они живут, пока жив под. Судьба у данных, которые туда попадают, аналогичная.

Для statefull-приложений используются постоянные хранилища, Persistent Volumes (PV). Persistent Volumes (PV) — это единицы хранения, которые были выделены кластеру Kubernetes его администратором. Это могут быть локальные диски, СХД, внешние дисковые полки. Они никак не зависят от жизненного цикла подов.

Persistent Volume Claim (PVC) — это запрос на выделение PV определенных характеристик: типа хранилища, объема, типа доступа (чтение и/или запись). Для описания подробных характеристик доступных PV используются Storage Classes.

В динамике это все выглядит следующим образом: под отправляет PVC, а PVC уже обращается к PV и передает ее поду.

image
Схема выделения PV подам

Вопрос 14. Как в Kubernetes сделать приложение доступным извне по сети интернет?


Для этого нужно будет настроить сервисы (Services).

ClusterIP — сущность, которая позволяет маршрутизировать запросы к подам на статичный IP-адрес. Благодаря ClusterIP у нас будет неизменная точка входа, даже если сами поды будут крашиться и восстанавливаться снова.

NodePort делает сервис доступным извне через статический порт на каждом узле кластера. Любой трафик, отправленный на этот порт, будет перенаправлен на сервис. При этом ClusterIP создается автоматически.

LoadBalancer публикует сервис вовне и заводит трафик от балансировщика облачного провайдера внутрь кластера.

External name сопоставляет сервис с DNS-именем (например, example.com). Он создает CNAME-запись, которая соединяет DNS-имя с определенным именем внутри кластера. Выступает как прокси, которое позволяет пользователю перенаправлять запросы сервису, находящемуся внутри или за пределами кластера.

Вопрос 15. Что такое ingress и зачем он нужен?


Ingress позволяет настраивать правила маршрутизации для трафика от внешних источников до сервисов внутри кластера.

В Ingress описываются сами правила маршрутизации к сетевым сервисам, а 
контроллер Ingress отвечает за их выполнение. Контроллер не поставляется в Kubernetes, но можно использовать одно из сторонних решений, предварительно изучив их возможности и особенности.

Вопрос 16. Расскажите, как вы будете запускать приложение в Kubernetes, если из инструментов у вас только kubectl?


В общем виде последовательность действий выглядит следующим образом:

  1. Для запуска в Kubernetes приложение должно быть упаковано в контейнер, поэтому первым шагом будет поместить приложение в контейнер.
  2. Затем нужно запустить контейнер в виде набора реплик (подов). Для этого используем Deployment.
  3. Для того чтобы приложение было доступно в интернете и к нему можно было подключиться, нужно настроить сервис LoadBalancer, который позволит присвоить публичный IP-адрес и подключиться к кластеру из внешней сети.
  4. Чтобы маршрутизировать пришедший через балансировщик трафик до приложения, в кластере должен быть создан Ingress, описывающий правила маршрутизации, и запущен Ingress-контроллер.


Проделать все это можно через kubectl, командную строку по сути. Это императивный и самый простой способ, когда мы как бы говорим Kubernetes «сделай это и это».

Второй способ, который применяется уже в промышленной эксплуатации, — это управление через декларативные манифесты, в которых мы описываем желаемое состояние, а Kubernetes уже сам решает, какие действия для этого нужно сделать. Затем эти манифесты отправляем в Kubernetes c помощью команды kubectl apply.

Подробную инструкцию по запуску приложения в Kubernetes c примерами yaml-файлов читайте здесь.

Вопрос 17. Приложение перестало работать — как понять, что случилось?


Причин, по которым приложение не работает в кластере Kubernetes, много.

Вот самые распространенные:

  • под отсутствует;
  • под не запускается (статус Pending);
  • под запускается, но падает с ошибкой (статус CrashLoopBackOff);
  • под работает (статус Runnung), но недоступен по сети.


Ниже кратко рассмотрим алгоритмы, позволяющие понять, что же все-таки случилось.

  1. Для начала нужно убедиться, что манифест выполнился и под действительно зарегистрирован в кластере. Если подов и деплоймента не находится, проверьте манифесты.
  2. Если поды находятся в статусе Pending, значит Scheduler не может найти подходящую ноду для запуска пода. На это тоже может быть много причин: недостаточно ресурсов в кластере, несовпадение taints/tolerances, невозможность скачать образ и многое другое. Найти причину помогут события, связанные с подом, однако некоторые проблемы (например, отказ Scheduler) не попадут в этот список. Также проверьте статус нод в кластере и селекторы, указанные в манифесте.
  3. Если под был назначен ноде, но при запуске произошла ошибка, под будет иметь статус CrashLoopBackOff и кластер будет предпринимать попытки запустить его повторно. Обычно это происходит в случае ошибки в самом приложении внутри контейнера, а найти причину обычно помогают логи (если приложение их пишет, конечно).
  4. Следующая ситуация — поды работают (статус Running), однако не доступны по сети из других подов. Для начала нужно проверить, создан ли Service с соответствующим селектором. Также необходимо проверить, что они находятся в одном namespace.


Если сервисы существуют, но доступа нет, причина может быть в правилах NetworkPolicy, ограничивающих доступ сервисов друг к другу. Проверьте эти ограничения.

Если сервис должен быть доступен извне кластера (из интернета или приватной сети), необходимо проверить наличие Ingress-правила, описывающего маршрутизацию L7-трафика на выбранный сервис. Также стоит проверить состояние Ingress Controller: если он не работает, правила не будут исполняться.

Кроме того, для прохождения запроса внутрь кластера должна существовать точка входа, через которую запрос попадает на Ingress Controller. Такой точкой служит Service NodePort для кластеров on-premise инфраструктуры или LoadBalancer для кластеров в облаке.

Каждый из этих шагов можно выполнить через набор команд kubectl или через графический клиент, например, Lens.

Подробнее можно почитать тут.

Это была наша версия вопросов по Kubernetes для разработчика.

Напишите в комментариях, что еще, на ваш взгляд, важно понимать про Kubernetes или, наоборот, что в нашем списке вам показалось избыточным.


gz5opfttva6zuzxinkdyakvpi1g.png

© Habrahabr.ru