(java || kotlin) && devOps
369 subscribers
6 photos
1 video
6 files
306 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
Всем привет!

Я упомянул в предыдущем посте про Сhaos engineering. Хочу немного развить тему, тем более она стала популярна в последнее время.
Если описать вкратце - это контролируемая поломка системы.
Алгоритм такой:
1) определяем чтобы такого сломать. Очевидно, ломать нужно то, что с большей вероятностью может сломаться в ПРОДе
2) определяем как мы хотим, чтобы система вела себя при поломке
3) определяем как мы будем мониторить ее поведение
4) ломаем систему
5) сравниваем план и факт
6) опциально: заводим задачи на исправление))))
Вот тут подробнее https://habr.com/ru/company/flant/blog/460367/
Что интересно - тема chaos engineering "попала в топ" после того, как начался массовый переход в облака и в частности на k8s. И это неспроста.
Ключевой момент в chaos engineering - контролируемость эксперимента. Да, настоящих bare metal серверов все меньше, все чаще используются виртуалки. VMWare позволяет автоматизировать запуск и остановку отдельного сервера.
Но k8s и особенно Istio благодаря своим прокси на каждом узле (kube-proxy и envoy соответственно) позволяет централизовано управлять маршрутизацией. А это дает нам:
1) эмуляцию потери пакетов
2) эмуляцию увеличенных таймаутов
3) "виртуальное" отключение сервера - отключение трафика на сервер без отключения сервера, т.наз. blackhole. А это ускоряет тестирование.
4) отключение на уровне namespace
и какие-то более сложные сценарии.

В общем унификация в данном случае рулит!)

#haos_engeniring #k8s #istio
Всем привет!

Когда-то давно - год назад - у меня была заметка, чем хорош k8s: https://t.me/javaKotlinDevOps/6
Там был упомянут Docker, пришло время подробнее раскрыть, что же дают нам контейнеры. Вообще говоря контейнеры и Docker не одно и тоже, но в данном случае различием можно пренебречь.

1) идентичное окружение на dev, test и prod. Да, JRE уже дает нам уровень абстракции от ОС и железа, и это большой плюс в плане запуска Java в разных ОС. Но есть проблемы:
а) разные версии JDK
б) разные сервера приложений\контейнеры сервлетов
в) разный classpath, часто как следствие предыдущего пункта
г) разные переменные среды
д) разное состояние файловой системы
Все это можно решить, но часто решение дорогое - сложные CD pipeline, долгое время деплоя, сложность поднятия prod-like среды на машине разработчика.
C Docker-ом мы получаем immutable infrastructure - набор ПО, настроек и состояние файловой системы зафиксированы на dev и остаются неизменными дальше.

2) легковесная изоляция сервисов. Контейнеризация обеспечивает изоляцию файловой системы, процессов, сетевых интерфейсов и резервирование ресурсов для каждого запущенного на сервере контейнера. Используются механизмы ядра Linux, подробнее см. https://habr.com/ru/articles/659049/
Ключевой момент тут - легковесная, т.к. технологии изоляции в виде виртуальных машин известны давно. Но виртуальная машина эмулирует железо, что сложно, см. стоимость лицензии VMware, к тому же приводит к достаточно высоким накладным расходам по CPU, памяти и диску. Плюс поверх виртуалки нужна гостевая операционная система, а значит запуск виртуалки - это долго.

3) легкость установки. Т.к в Docker сейчас упаковывается почти все (https://hub.docker.com/search, нужна регистрация), то появляется возможность быстро и без ущерба для компьютера разработчика развернуть необходимое серверное ПО - СУБД, Kafka, кэши, мониторинг... А если данные сервисы нужны для тестов - на помощь приходит Testсontainers https://java.testcontainers.org/ Все это работает на Linux, MacOS и Windows, например, с помощью Docker Desktop https://www.docker.com/products/docker-desktop/ Может возникнуть вопрос - откуда на Windows появились механизмы ядра Linux? Ответ: благодаря технологии WSL - https://learn.microsoft.com/ru-ru/windows/wsl/.
Аналогично на серверах - установка образа проще и стабильнее установки классического серверного ПО.

Если говорить именно о Docker - то в общем то это все, остальные преимущества раскрываются в связке с k8s и Service Mesh.

#docker #k8s
Всем привет!

Среди первых постов этого канала был пост про k8s - для чего он нужен https://t.me/javaKotlinDevOps/6
Но я забыл рассказать про Service Mesh - что же она добавляет к k8s. Если вы не понимаете, что за Service Mesh такой - самой известной реализацией является Istio https://istio.io/latest/docs/ На его примере хочу рассказать про Service Mesh.

Начал искать материалы и сразу наткнулся на серию отличных статей:
https://habr.com/ru/companies/flant/articles/438426/
https://habr.com/ru/companies/flant/articles/569612/
https://habr.com/ru/companies/oleg-bunin/articles/726958/
Рекомендую их почитать, там есть и про устройство Istio на сетевом уровне, и про решаемые им задачи, и про вносимые данной технологией риски.

Для тех, кому лень читать поработаю продвинутой версией Yandex GPT.
Основные "плюшки" Istio:
1) возможность аутентификации и авторизации запросов как по адресам, url-ам, так и с помощью OAuth
2) продвинутые возможности балансировки - например, привязка клиента к конкретному серверу или геопривязка: перенаправление только на экземпляры сервиса, находящиеся в том же гео-кластере
3) реализация паттерна Circuit Breaker, повторов и настройка таймаутов для запросов
4) продвинутые возможности маршрутизации: по URL и http заголовкам
5) реализация канареечного развертывания и зеркалирования траффика
6) TLS Termination и Origination - снятие и добавление TLS шифрования на входе\выходе из namespace, что позволяет полностью переложить работу с сертификатами с разработки на сопровождение

Вывод следующий: Service Mesh - новый уровень абстракции поверх обычного облака (k8s). Да, он добавляет сложность, особенно в части сопровождения. Вносит небольшие задержки, которые в определенных случаях могут быть критичны. Требует ресурсов, что также может быть важно. Но если его "плюшки" вам полезны - оно того стоит)

#istio #k8s #service_mesh #cloud
Всем привет!

К двум моим статьям про k8s (https://t.me/javaKotlinDevOps/6) и Istio (https://t.me/javaKotlinDevOps/210) прямо напрашивается третья - про Openshift.

Тут может возникнуть вопрос - а что это вообще такое и почему напрашивается?)
Ответ: это "допиленный напильником" k8s от компании Redhat для enterprise.
Поэтому если вы работаете в enterprise, особенно кровавом, то тема актуальная)

Второй вопрос, который может возникнуть - какой такой западный enterprise в России сейчас?
Ответ: есть opensource версия https://habr.com/ru/companies/redhatrussia/articles/511800/

Итак, что же добавляет Openshift к k8s.

1) Istio - включен в дистрибутив

2) встроенный Docker Registry

Небольшое уведомление. Основной пласт возможностей, которые предоставляет Openshift, реализован за счет кастомных ресурсов - CRD - и оператора, который их обрабатывает.
https://kubernetes.io/docs/concepts/extend-kubernetes/operator/
https://habr.com/ru/companies/slurm/articles/556860/
Идем дальше.

3) настройки безопасности: ролевая модель https://docs.openshift.com/container-platform/4.8/rest_api/role_apis/role-apis-index.html, авторизация https://docs.openshift.com/container-platform/4.8/rest_api/authorization_apis/authorization-apis-index.html , OAuth https://docs.openshift.com/container-platform/4.8/rest_api/oauth_apis/oauth-apis-index.html

4) механизм шаблонов (ресурс типа Template) - позволяет в одном файле задать несколько ресурсов с параметрами. Значения параметров можно как задать в самом шаблоне (значения по умолчанию), так и передать в момент применения Template
https://docs.openshift.com/container-platform/4.8/rest_api/template_apis/template-apis-index.html

5) Имея механизм шаблонов, ролевую модель и настройку лимитов из k8s можно упростить создание новых namespace: для этого вводится проект - аналог namespace в Openshift. https://docs.openshift.com/container-platform/4.8/rest_api/project_apis/project-apis-index.html

6) самое интересное - концепция build-related ресурсов. Идея в том, что при изменении исходников или появлении нового образа в Docker происходит автоматическая сборка и установка новой версии приложения. Т.е. фактически мы получаем встроенный в кластер CI\CD.
https://docs.openshift.com/container-platform/4.10/cicd/index.html
https://docs.openshift.com/container-platform/4.8/rest_api/workloads_apis/buildconfig-build-openshift-io-v1.html
Данная концепция приводит к тому, что стандартный ресурс Deployment в Openshift заменяется на очень похожий DeploymentConfig, поддерживающий пересоздание подов при появлении нового кода https://docs.openshift.com/container-platform/4.8/rest_api/workloads_apis/deploymentconfig-apps-openshift-io-v1.html

7) само собой новая веб-консоль и новая CLI утилита (oc), поддерживающие все вышеописанные возможности.

Вот пожалуй и все основные отличия Openshift. В целом неплохо, хотя и не так революционно, как Istio

#openshift #istio #cloud #k8s
Всем привет!

Формат yaml все больше входит в нашу жизнь, самые очевидные примеры - k8s, Docker Compose и Ansible.
Его главным преимуществом я считаю ссылки - соблюдается принцип DRY.
Главным недостатком - зависимость от числа tab\пробелов как в Python.

А чтобы не дать лишнему пробелу все сломать - нужна валидация.

Для начала - валидация синтаксиса https://yamllint.readthedocs.io/en/stable/index.html
Хотя в списке ОС для скачивания нет Windows - он ставится на Win с помощью python + pip.
Также есть плагин для IDEA https://plugins.jetbrains.com/plugin/15349-yamllint

Да, подсветка синтаксиса хотя и не заменяет валидацию, но тоже полезна - IDEA, Notepad++ и Atom поддерживают его из коробки.

Далее можно прикрутить валидацию, специфичную для конкретной области применения.
Для k8s есть утилиты kubeval, kube-score и Polaris см. https://habr.com/ru/companies/flant/articles/511018/
Они проверяют манифесты на соответствие best practices.
В docker-compose валидация вызывается с помощью команды https://docs.docker.com/engine/reference/commandline/compose_config/
Для Ansible - базовые проверки встроены в Ansible, также есть ansible-lint, детали см. https://www.deploymastery.com/2023/03/31/how-to-verify-ansible-playbook-syntax/

Альтернатива - написать нужные проверки самому. Тут есть 4 библиотеки из уже приведенной выше статьи:
config-lint, copper, conftest, Polaris
https://habr.com/ru/companies/flant/articles/511018/ Основное различие - в языке, на котором будет ваш код проверки. Есть и декларативный yaml, есть и императивный JS.

#yaml #k8s #ansible #docker-compose #validation
Всем привет!

Есть такой интересный вопрос - можно ли поместить СУБД в облако?
Если отвечать на него строго технически - да, можно, для этого в k8s есть специальные типы объектов - StatefulSet https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/ и PersistentVolume
https://kubernetes.io/docs/concepts/storage/persistent-volumes/
которые обеспечивают ряд требуемых для СУБД характеристик:
1) подключенное хранилище не удаляется при каждой остановке пода
2) экземпляр StatefulSet имеет постоянное имя
3) процедура масштабирования StatefulSet в обе стороны последовательна - поды добавляются\удаляются по одному

Более того, в документации кубера есть пример с раскатыванием MySQL https://kubernetes.io/docs/tasks/run-application/run-replicated-stateful-application
Причем с возможностью автоматического масштабирования на чтение. Пример на самом деле меня впечатлил: сотня строк манифестов yaml - и БД уезжает в облако.

Так ли все хорошо?
Конечно же нет)
Для начала я бы задал типичный "менеджерский" вопрос - какую задачу решаем?

Первый момент - горизонтальное масштабирование на чтение можно обеспечить для любой СУБД. Как в облаке, так и без облака. На запись - только для NoSQL хранилищ с поддержкой шардирования.

Второй момент: сопровождение СУБД - это не просто гарантия наличия работоспособного инстанса на ПРОМ. Это еще и периодические бэкапы, откаты на резервную копию, начальное заполнение БД данными, заполнение "горячего" кэша, выбор нового master если старому плохо (leader election), тонкие настройки репликации и многое другое, чего я просто не знаю. А знают - хорошие DBA. Т.е. получается даже если мы поместим обычную СУБД в облако - DBA все равно нужен. Причем DBA, умеющий в облако, а это, кажется, редкая птица)

Т.е. все плохо? И снова нет. Если есть потребность отдать БД "на аутсорс" в облако, то выход - использование хранилищ от облачных провайдеров, спроектированных для работы в облаке. Там все вышеописанные тонкости будут учтены. Примеры:
1) Amazon Aurora https://habr.com/ru/companies/oleg-bunin/articles/471686/
2) YDB https://cloud.yandex.ru/ru/services/ydb
3) Azure Cosmos DB for PostgreSQL https://learn.microsoft.com/en-us/azure/cosmos-db/postgresql/introduction

Ну или хотя бы использование заточенных под работу в облаке СУБД. Вот пара примеров, первыми попавшихся мне на глаза:
1) Tarantool https://habr.com/ru/companies/vk/articles/533308/
2) CockroachDB https://www.cockroachlabs.com/docs/v23.2/deploy-cockroachdb-with-kubernetes
Как можно заметить, в обоих случаях есть специальный оператор k8s для управления кластером.

P.S. Тема сложная, интересная, поэтому думаю это не последняя статья.

#k8s #storage #cloud #rdbms
Всем привет!

Как можно масштабировать нагрузку в облаке? Под облаком я понимаю k8s как некий стандарт.

1) "ручками". Простой, но не надежный способ. Отягощающий фактор - не всегда у сопровождения ПРОМ есть права на смену настроек Deployment, тогда требуется отдельный деплой

2) выставить число подов и limits, соответствующими максимальной нагрузке. Еще проще, но совсем не рационально в плане использования ресурсов

3) HorizontalPodAutoscaler https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/ Позволяет менять число подов сервиса при превышении некого порога нагрузки по cpu и memory. Порог - это не процент использования, а соотношения заданного requests с текущим значением. Подходит если требуемая нагрузка может превышать возможности 1 пода, и если сервис поддерживает горизонтальное масштабирование - т.е. stateless.

4) VerticalPodAutoscaler https://habr.com/ru/companies/flant/articles/541642/ Как следует из название - масштабирует поды вертикально. Тут есть нюанс - на данный момент k8s не позволяет менять requests и limits у пода "на ходу". Данная фича называется In-Place Update of Pod Resources и пока находится в бета-версии https://github.com/kubernetes/enhancements/issues/1287
Сейчас VerticalPodAutoscaler может следующее:
а) на основе истории использования подом ресурсов рассчитать и выдать рекомендуемые значения
б) применить эти значения при очередном плановом рестарте
в) самому рестартовать под
Подходит для следующих случаев:
а) statefull сервисы типа хранилища данных в облаке StatefullSet, для которых горизонтальное масштабирование или невозможно, или не приветствуется
б) "легкие" сервисы, которым достаточно одной реплики (или двух по требованиям надежности)
Из особенностей - не гарантируется корректная работа совместно с HorizontalPodAutoscaler по одним и тем же метрикам cpu и memory. И не работает с Java приложениями в плане нагрузки по памяти, т.к. Java сама управляет памятью, а VerticalPodAutoscaler эти данные не видит.
Ну и главный минус - необходимость рестарта для применения настроек

5) как избавиться от необходимости рестарта? Дождаться полноценного внедрения In-Place Update of Pod Resources и доработки VerticalPodAutoscaler. Или использовать бета-версию In-Place Update of Pod Resources реализовать соответствующий k8s controller самому. Это уже сделано: https://piotrminkowski.com/2023/08/22/resize-cpu-limit-to-speed-up-java-startup-on-kubernetes/
Данная реализация не умеет сама рассчитывать рекомендуемые значения requests. Зато позволяет красиво проблему JVM приложений, о которой я уже писал ранее - проблему долгого старта. Java, а точнее Spring приложение, при старте производит достаточно ресурсоемкую настройку контекста. Речь идет про обычный Spring Boot без применения всех возможных способов ускорить запуск. Если память после первоначальной настройки так и остается занятой созданными бинами, то cpu при старте требуется сильно больше, чем при обычной работе. Что с этим делать?
а) Не выделять лишние cpu - время старта увеличивается в разы
б) Пойти по пути, описанному в п.2 - выдать максимум ресурсов. Тогда может получиться, что мы тратим cpu на быстрый старт приложения, а далее ресурсы не утилизируются
в) In-Place Update of Pod Resources
Конкретно по данной реализации - мне она кажется не идеальной, т.к. ресурс по cpu настраивается в 2 манифестах, это не наглядно и способствует внесению несогласованных правок. Но решение в целом - полезное.

#k8s #cloud #scalability
k8s HPA бесполезен? Или нет?)

Я уже писал о возможности масштабировать поды горизонтально через компонент HPA — Horizontal Pod Autoscaler. Он собирает метрики загрузки пода (границы можно настраивать) и меняет число реплик в заданных границах.

Круто? Да. Но есть одно «но». В namespace ресурсы часто прибиты гвоздями. Один namespace = один микросервис. Микросервис имеет некие бизнес-требования по нагрузке, проходит нагрузочное тестирование и получает некоторое количество ресурсов. Хуже того — кластер, в котором находится namespace, тоже имеет жёсткое ограничение по ресурсам. Это частное, небольшое по сравнению с cloud-провайдерами облако. Лишним node взяться неоткуда. Поэтому HPA в частном облаке бесполезен. Все ресурсы уже забронированы. От того, что часть из них уберут из балансировки, ни холодно ни жарко. Только замедление при старте пода.

В больших облаках, типа AWS, эту проблему решают тем, что прячут кластер от клиента и динамически меняют его размер.Если потребителей много и у них разный характер нагрузки, всё должно работать хорошо.

Что можно сделать в частном облаке? Например, вот так: https://youtu.be/GWJ9rDrsBdQ?si=dx-VHMlIIYKo2g4q Кейс не универсальный, но если есть свой кластер и понятно, что в нём будут жить приложения с разными пиками нагрузки — потребление ресурсов можно оптимизировать. Как развитие идеи — автоматическая генерация рекомендаций по настройке кластера.

#k8s #optimization