Kubernetes - открытая платформа созданная для автомтаического деплоя, масштабирования и оперирования контейнерами приложений.
Портативная расширяемая платформа с открытым исходным кодом для управления контейнеризованными рабочими нагрузками и сервисами которая облегчает как декларативную настройку так и автоматизацию.
Kubernetes состоит из нод. Как правило рекомендуют использовать не менее 3х нод для Kubernetes. Master Node и 2 Work Nodes.
Master Node - отвечает за поддержание желаемого состояния для вашего кластера. С Master Node взаимодействует kubectl - интерфейс командной строки, который позволяет через командную строку управлять Kubernetes кластером.
С другой стороны у нас есть пользователь, который через интернет обращается к нашему приложению через Work Node и через kube-proxy ходит непосредственно на pod'ы.Основные фундаментальные концепции Kubernetes - это pod и node, а также kublet, kube-proxy, etcd.
Nodes(узлы) - это виртуальные либо физические машины в Kubernetes кластере на которых будут запускаться контейнеры. Нода содержит kublet, Docker, kube-proxy. Также нода может содержать 1 или несколько под.
Pod - минимальный юнит в Kubernetes с которым можно взаимодействовать, абстрактный объект Kubernetes представляющий группу из одного или нескольких контейнеров приложения (например Docker).
Поды можно создавать, деплоить и удалять. Одна пода - один процесс в кластере. Под содержит: Docker container, storage resources, уникальный IP.
Cluster - совокупность мастер-сервисов и нод.
Namespace - это способ разделения ресурсов кластера между несколькими пользователями. Например, namespace команд, проектов и тд.
Чтобы зайти в кластер и начать запускать команды нужно установить kubectl.
kubectl - это инструмент командной строки kubernetes, который позволяет запускать команды для кластеров Kubernetes. Вы можете использовать kubectl для развертывания приложений проверки и управлени ресурсов кластера а также просмотра логов
Чтобы работало автодоплнение нужно выполнить команду:
source <(kubectl completion bash)
Далее нужно получить доступ к кластеру:
kubectl get namespaces
kubectl get pods --all-namespaces
kubectl get pods --all-namespaces -o wide |grep ssr
kubectl get pods -n core-team
kubectl get pods -n core-team|grep besida-madmax
После того как вышел список подов мы можем увидеть статусы в которых они находятся:
kubectl -n core-team describe pod besida-trunk-ua-685d5d4f-hpdw2
kubectl -n core-team logs besida-trunk-ua-685d5d4f-hpdw2
отображает логи на лету
kubectl -n core-team logs -f besida-trunk-ua-685d5d4f-hpdw2
Управляется Controller Manager'ом.
Виды контроллеров:
ReplicaSets - проверяет что необходимое количество pod запущено все время. Если pods стало меньше (например одна изпод закрешилась), то replicaSet создаст новую. ReplicaSets существует не самостоятельно а в рамках Deployment.
Deployments - предоставляет декларативное описание для апдейта ReplicaSet и Pod. В ранних версиях Kubernetes вместо ReplicaSet и Deployment использовался Replication Controller. Но это нарушало принцип single responsibilities и в дальнейшем он был разделен и облегчилась задача rollback'a - если во время деплоймента что то пошло не так то в текущих условиях легко откатиться назад и востановить работоспособность приложения.
DeamonSets - проверяет что на каждой ноде запущен экземпляр конкретной поды. Если ноды добавляются в кластер или удаляются из кластера то DeamonSet добавить или удалить поды на этой ноде. Удаление DeamonSet означает удаление всех под из кластера.
Jobs - это процесс верхнего уровня для пода. Используется когда нужно запустить pod для выполнения какой то задачи один раз или по расписанию. Типичный пример - cron job.
Services - позволяет сетевое взаимодействие между деплойментами. Необходимы, когда нужно, чтобы поды из разных деплойментов взаимодействовали между собой.
Например: FrontEnd Pod взаимодействует с BackEnd Pods через Backend Service.
Internal - ip-адрес доступен только внутри кластера.
External - эндпоинт доступен по ip адресу ноды(такой сервис называют NodePod).
Load Balancer - открывает приложение в интернет через лоад балансер (обычно используется когда кубернетис кластер развернут в облаке (GCP, AWS, Azure).
Пара ключ/значение, может быть присоединена к таким объектам как поды, сервисы и доплойменты. Используются пользователями Кубернетис для идентификации аттрибутов для объектов. Уникальны в пределах объекта.
Пример: "environment": "dev", "environment": "qa", "environment": "prod"
Labels как правило используются не одни а с selectors.
Labels и Selectors обычно используются в kubectl командах для получения списков объектов и их фильтрации. НапримерЖ получение списка под на QA env.
Концепция неймспейсов позволяет реализовать множество виртуальных кластеров внутри одного физического кластера. Это полезно, когда есть необходимость разделять ресурсы физического кластера между командами и контролировать доступ к ресурсам.
Распределённое и высоконадёжное хранилище данных в формате "ключ-значение", которое используется как основное хранилище всех данных кластера в Kubernetes.
Компонент плоскости управления, который отслеживает созданные поды без привязанного узла и выбирает узел, на котором они должны работать.
kubectl get pods
kubectl get services
kubectl get deployments
kubectl create -f selenium-hub-deployment.yaml
kubectl create -f selenium-hub-svc.yaml
kubectl create -f selenium-node-chrome-deployment.yaml
CI - Continious Integration это когда разработчики интегрируют свои код в общий репозиторий на постоянной основе и постоянно проходят некий quality gate который показывает что их код синтегрировался корректно.
CD - Continious Delivery это когда артефакт который мы собрали в рамках Continious Integration и начинаем поставлять его на разные окружения. Continious De[loyment это когда мы в процессе Continious Delivery не ждем ручного апрува а автоматом через энвайронменты проводим и выкатываем на продакшен.
Как этого достичь: 1. Докеризация микросервисов нужно получить артефакт который будет неизменным - нужно быть уверенным что тот артефакт который мы собрали в таком же виде дойдет до продакшена 2. Мы можем присваивать артефакту теги и тем самым продвигать его на следущую стадию 3. Мы не завязываемся на технический стек 4. Это прощает деплоймент, управление окружением, конфигурацию и т.д. 5. Эфективное использование ресурсов
У нас есть контейнер - запущенный процесс который представляет наш микросервис и image - immutable артефакт который мы собрали в рамках CI и выложили его в registry - реестр images, где хранятся наши артефакты.
Семантическое версионирование - главная версия отвечает за то какие знаковые изменения были сделаны в микросервисе(то что мы не поломали API), если мы не имеем обратной совместимости то увеличиваем эту версию либо по большим релизом и с каждым релизом увеличиваем; минорная версия - либо начинаем каждый раз с нуля в рамках каждого нового большошо релиза либо если девелопим интерациями то используют номер интерации, тогда можно быстро востановить когда эта версия была выпущена. патч версия - для хот фиксов комит хештег как суффикс и дата как дополнительный суффикс
Разработчик делает комит в гит репозиторий на CI делается: build code, run unit tests, build image, push image(пушится в реестр контейнеров). На выходе мы получаем кодовые артифакты, результаты тестов, image контейнер.
Quality Gates:
Чтобы поставить полностью всю систему нужно знать версии всех микросервисов.
Здесь нужно учитывать совместимость - это когда мы взяли набор микросервисов подняли провели тесты и после этого мы говорим что этот набор сервисов совместим
Поэтому нужно сохранять нобор версий этих сервисов как отдельный артефакт Этот артефакт можно положить в систему контроля версий(например гит) Дальше в Continious Delivery будет участвовать этот набор. и дальше можно промоутить этот артефакт между разными окружениями. Если мы добавим зависимость на какую то версию postgress или elastic то мы получим полную совместимсоть
Это делается с помощью property файла и прописываем версии. Можно использовать helm.
Пример:
У нас есть 3 сервиса с соответсвущими версиями и мы их собрали в compatible set.
И тут появляется доработка в одном из сервисов и появляется его новая версия и это новый кандидат мы хотим его продвинуть.
Мы собираем новый set с этим кандидатом и пытаемся его запустить и билд падает(возможно оказалась проблема в несовместимости например с ui частью).
И появилась необходимость сделать исправление в другом микросервисе, разработчики делают исправление, получают новую версию и хотят ее задеплоить. И тут вступает фактор, что нужно подхватывать всех новых кандидатов, потому что если бы подхватили только последний кандидат, он могбы упасть так как ожидает исправлений, которые появились в первом сервисе.
Если билд проходит успешно, то мы делаем совместимый между собой set и сохраняем его в сисетму контроля версий.
Если билд падает, то артифакт невидим и нет возможность такой билд куда-то задеплоить просто так, не пройдя тест на совместимость.
После того как артефакт появился в системе контроля версий, то либо jenkins джоба это проверяет, либо оператор в Kubernetes переодически мониторит что появляется и говорит что надо это деплоить - вручную или по расписанию.
Flux CD мониторит появление новых images в гите и говорит что можно их задеплоить.
Для этого мы создаем Jenkins джобу или github actions которая показывает нам список окружений который нам доступен: dev, qa, stage, prod либо оставляем создаем новое окружение. Также показываются для выбора не отдельные микросервисы а показыватся сеты. Еще нужно указать TTL(Time To Live) окружение будет автоматически очищаться по истечению времени.
Но если будет много окружений - это займет все ресурс и для решения этой проблемы нужен Kubernetes.
Как ускорить создание окружения в Kubernetes:
zhuk.__