Всем привет! Меня зовут Денис, можно просто Дэн. Я пришёл в разработку 20 лет назад, когда ещё был жив Delphi, где-то через 3 года перешёл на Java. За это время успел покодить, побыть тимлидом, начальником отдела, ИТ-директором, техлидом и даже на пару лет отойти от Java. Каюсь) За это время накопилось немного опыта, мыслей, вопросов, идей, которыми хочется поделиться. Поэтому и решил завести канал про Java разработку и сопутствующие ей темы. Что здесь будет - да много чего :) В частности: сравнение технологий, может даже с холиваром, а ля Java vs Kotlin, Maven vs Gradle, Lombok или не Lombok. Еще: типичные проблемы при разработке и что с ними можно сделать, мысли про новые фреймворки, библиотеки, языки, и т.д. DevOps в части CI. Совсем базовых вещей здесь не будет, для этого есть Baeldung, куча бесплатных курсов и хороших книг
Послушал доклад на JPoint про уже подзабытую уязвимость log4j и удивился 3 вещам.
Напомню: оказывается некоторые версии log4j2 позволяли вставлять в выводимое в лог сообщение выражение, позволяющее сделать удалённый вызов через механизм JNDI lookup. Причём есть возможность не только слить какие-то критичные данные, но и что-то запустить на сервере, пишущем логи, через встроенный в JDK JS движок и его функцию eval.
Первое, что удивило: уязвимость появилась в 2014 году, найдена и обсуждена на конференции по ИБ в 2016 году. Примерно тогда же появился первый фикс, который ничего не фиксил) Выстрелила в конце 2021. Как можно было про нее забыть??? Неразвитость ИБ? Информационная перегрузка? Кому-то было выгодно?
Второе: на первый взгляд эксплуатировать уязвимость сложно - нужно чтобы совпали 3 фактора: использование log4j определённого диапазона версий, отсутствие валидации пользовательского ввода и либо возможность вызвать внешний сервер для передачи конфиденциальных данных или загрузки remote code из внутренней сети, либо сервер атакующего уже должен быть во внутренней сети. Ну и детали об атакуемой системе неплохо бы знать: куда передавать сообщение с exploit-ом, что можно слить, что можно запустить на сервере. Но если подумать, несколько широко распространён log4j, как много пользовательских данных, http заголовков к нам приходит, и что-то из этого точно логируется, а главное как много ИТ систем в мире и 100% не у всех хватает денег на выделенного ИБ спеца - уязвимость совсем не кажется абстрактной, скорее наоборот.
И наконец третье. Разные я видел способы пропатчить библиотеку, сам патчил, но чтобы взять и вырезать файл - это что новое. Но способ эффективный - учитывая редкость использования функционала, в котором была найдена уязвимость, появившийся на сервере ClassNotFoundException в 99,9% случаев будет указывать на атаку. Ну и напоследок - как можно было такое редкий и опасный функционал включать по умолчанию...
Вывод: следование практикам ИБ и feature toggling рулят
#security #vulnerability
Напомню: оказывается некоторые версии log4j2 позволяли вставлять в выводимое в лог сообщение выражение, позволяющее сделать удалённый вызов через механизм JNDI lookup. Причём есть возможность не только слить какие-то критичные данные, но и что-то запустить на сервере, пишущем логи, через встроенный в JDK JS движок и его функцию eval.
Первое, что удивило: уязвимость появилась в 2014 году, найдена и обсуждена на конференции по ИБ в 2016 году. Примерно тогда же появился первый фикс, который ничего не фиксил) Выстрелила в конце 2021. Как можно было про нее забыть??? Неразвитость ИБ? Информационная перегрузка? Кому-то было выгодно?
Второе: на первый взгляд эксплуатировать уязвимость сложно - нужно чтобы совпали 3 фактора: использование log4j определённого диапазона версий, отсутствие валидации пользовательского ввода и либо возможность вызвать внешний сервер для передачи конфиденциальных данных или загрузки remote code из внутренней сети, либо сервер атакующего уже должен быть во внутренней сети. Ну и детали об атакуемой системе неплохо бы знать: куда передавать сообщение с exploit-ом, что можно слить, что можно запустить на сервере. Но если подумать, несколько широко распространён log4j, как много пользовательских данных, http заголовков к нам приходит, и что-то из этого точно логируется, а главное как много ИТ систем в мире и 100% не у всех хватает денег на выделенного ИБ спеца - уязвимость совсем не кажется абстрактной, скорее наоборот.
И наконец третье. Разные я видел способы пропатчить библиотеку, сам патчил, но чтобы взять и вырезать файл - это что новое. Но способ эффективный - учитывая редкость использования функционала, в котором была найдена уязвимость, появившийся на сервере ClassNotFoundException в 99,9% случаев будет указывать на атаку. Ну и напоследок - как можно было такое редкий и опасный функционал включать по умолчанию...
Вывод: следование практикам ИБ и feature toggling рулят
#security #vulnerability
(java || kotlin) && devOps pinned «Всем привет! Меня зовут Денис, можно просто Дэн. Я пришёл в разработку 20 лет назад, когда ещё был жив Delphi, где-то через 3 года перешёл на Java. За это время успел покодить, побыть тимлидом, начальником отдела, ИТ-директором, техлидом и даже на пару лет…»
Чем kubernetes, он же k8s лучше контейнера сервлетов или сервера приложений.
Во-первых под капотом k8s лежит Docker, а значит мы получаем все его плюшки. Не зря k8s называют оркестратором контейнеров. Чем занимается оркестратор?
1) планированиеи ресурсов. Разработчик декларативно задает как он хочет задеплоить своё приложение в Deployment. А именно: сколько нужно экземпляров - replicas, сколько CPU и памяти - requests и limits, про соседству с какими приложениями его нужно размещать, по соседству с какими не нужно - labels и (anti) affinity. k8s исходя из имеющихся у него серверов, они же nodes, и их загрузки размещает экземпляры приложения - pods. Или процесс раскатки падает, если подходящих серверов нет( У серверов приложений такого механизма нет. Важно добавить - процесс поддержания требуемой конфигурации приложения непрерывный, при любых отклонениях k8s будет убивать и добавлять поды.
2) стратегия раскатки. k8s позволяет в том же Deployment в параметре strategy задать два базовых варианта: при появлении новой версии гасить все поды сразу и поднимать новые или раскатывать плавно, учитывая значения максимально допустимого превышения и нехватки числа экземпляров MaxSurge и MaxUnaveilable. Для серверов приложений такое поведение можно реализовать с помощью DevOps джобы.
3) автоматическое восстановление. Нода или под могут упасть. Падение определяется по healthcheck, заданному в том же Deployment, причём очень гибко, см livenessProbe, readinessProbe и startupProbe. k8s при наступлении такого события рестартует pod. Для серверов приложений это либо делается руками, либо автоматизируется извне.
4) горизонтальное масштабирование. С помощью HorizontalPodAutoscaller можно задать диапазон числа реплик и предельную загрузку CPU, при которой k8s добавляет или убирает реплики. Для серверов приложений - опять же ручное управление.
Отдельно хочу отменить внутреннюю DNS в k8s. Если у вас несколько приложений в одном облаке, он же cluster, то можно делать запросы по имени из Service. Вся внутренняя маршрутизация в облаке работает именно так. Для серверов приложений снова ничего такого нет.
Ну и load balancing, url/port mapping и SSL termination. В старом мире этим занимался отдельно стоящий nginx, в k8s его включили в периметр системы. #cloud
Во-первых под капотом k8s лежит Docker, а значит мы получаем все его плюшки. Не зря k8s называют оркестратором контейнеров. Чем занимается оркестратор?
1) планированиеи ресурсов. Разработчик декларативно задает как он хочет задеплоить своё приложение в Deployment. А именно: сколько нужно экземпляров - replicas, сколько CPU и памяти - requests и limits, про соседству с какими приложениями его нужно размещать, по соседству с какими не нужно - labels и (anti) affinity. k8s исходя из имеющихся у него серверов, они же nodes, и их загрузки размещает экземпляры приложения - pods. Или процесс раскатки падает, если подходящих серверов нет( У серверов приложений такого механизма нет. Важно добавить - процесс поддержания требуемой конфигурации приложения непрерывный, при любых отклонениях k8s будет убивать и добавлять поды.
2) стратегия раскатки. k8s позволяет в том же Deployment в параметре strategy задать два базовых варианта: при появлении новой версии гасить все поды сразу и поднимать новые или раскатывать плавно, учитывая значения максимально допустимого превышения и нехватки числа экземпляров MaxSurge и MaxUnaveilable. Для серверов приложений такое поведение можно реализовать с помощью DevOps джобы.
3) автоматическое восстановление. Нода или под могут упасть. Падение определяется по healthcheck, заданному в том же Deployment, причём очень гибко, см livenessProbe, readinessProbe и startupProbe. k8s при наступлении такого события рестартует pod. Для серверов приложений это либо делается руками, либо автоматизируется извне.
4) горизонтальное масштабирование. С помощью HorizontalPodAutoscaller можно задать диапазон числа реплик и предельную загрузку CPU, при которой k8s добавляет или убирает реплики. Для серверов приложений - опять же ручное управление.
Отдельно хочу отменить внутреннюю DNS в k8s. Если у вас несколько приложений в одном облаке, он же cluster, то можно делать запросы по имени из Service. Вся внутренняя маршрутизация в облаке работает именно так. Для серверов приложений снова ничего такого нет.
Ну и load balancing, url/port mapping и SSL termination. В старом мире этим занимался отдельно стоящий nginx, в k8s его включили в периметр системы. #cloud
Всем привет! Решил написать пост про архитектурную проблему, с которой столкнулся недавно. Где делать сортировку данных? Обычно проблема звучит так: на клиенте, т.е в коде приложения, или на сервере, т.е. в БД? У нас все чуть сложнее. Дано:
1) БД
2) бэк-система
3) миддл-система, обслуживает веб-клиентов
4) веб-клиент.
Для начала я бы отбросил бэк-систему и веб-клиента. Веб-клиента - потому что в презентационном слое логики должно быть как можно меньше. При этом надо отметить, что исключения из этого правила могут быть, т.к клиенты сейчас мощные - 4+ ядра, 8+ Гб памяти. А бэк-систему исключаем потому, что с одной стороны рядом есть БД, а с другой - сортировка нужна для отображения пользователю, поэтому логичнее ее переместить поближе к месту использования. Т.е. сводим проблему к исходной - клиент (миддл) или сервер (БД). Исходя из каких аргументов можно сделать окончательный выбор:
1) является ли сортировка частью контракта, т.е API? Нужна ли она другим потребителям? Если является - то в БД
2) нужна ли пагинация? Если да - то сортируем в БД, т.к. только там есть полный набор данных
3) сложность условия сортировки. Можно ли его реализовать в SQL?
4) наличие индекса в БД и возможность его добавить. С индексом по полю сортировки в БД она в большинстве случае будет быстрее, чем на клиенте
5) число клиентов, обращающихся к БД. Если БД перегружена, а масштабирование невозможно, то имеет смысл вынести сортировку выше по цепочке. Еще важен тип БД, RDBMS можно масштабировать только горизонтально, 64 ядерные сервера дороги, а 128 ядерных не бывает)
6) может ли клиент менять способ сортировки при работе с данными? Если да, то стоит рассмотреть реализацию всех сортировок на клиенте
7) трудоемкость кодирования. В большинстве случаев тут "выигрывает" БД, т.к. ORDER BY декларативен и проще любых алгоритмов на Java. #arch
1) БД
2) бэк-система
3) миддл-система, обслуживает веб-клиентов
4) веб-клиент.
Для начала я бы отбросил бэк-систему и веб-клиента. Веб-клиента - потому что в презентационном слое логики должно быть как можно меньше. При этом надо отметить, что исключения из этого правила могут быть, т.к клиенты сейчас мощные - 4+ ядра, 8+ Гб памяти. А бэк-систему исключаем потому, что с одной стороны рядом есть БД, а с другой - сортировка нужна для отображения пользователю, поэтому логичнее ее переместить поближе к месту использования. Т.е. сводим проблему к исходной - клиент (миддл) или сервер (БД). Исходя из каких аргументов можно сделать окончательный выбор:
1) является ли сортировка частью контракта, т.е API? Нужна ли она другим потребителям? Если является - то в БД
2) нужна ли пагинация? Если да - то сортируем в БД, т.к. только там есть полный набор данных
3) сложность условия сортировки. Можно ли его реализовать в SQL?
4) наличие индекса в БД и возможность его добавить. С индексом по полю сортировки в БД она в большинстве случае будет быстрее, чем на клиенте
5) число клиентов, обращающихся к БД. Если БД перегружена, а масштабирование невозможно, то имеет смысл вынести сортировку выше по цепочке. Еще важен тип БД, RDBMS можно масштабировать только горизонтально, 64 ядерные сервера дороги, а 128 ядерных не бывает)
6) может ли клиент менять способ сортировки при работе с данными? Если да, то стоит рассмотреть реализацию всех сортировок на клиенте
7) трудоемкость кодирования. В большинстве случаев тут "выигрывает" БД, т.к. ORDER BY декларативен и проще любых алгоритмов на Java. #arch
Всем доброго вечера. Возвращаясь к теме k8s - может возникнуть вопрос: как его можно запустить на машине разработчика? Покрутить, поиграться с конфигами. Все-таки кластер, nodes, БД для хранения конфигурации, контроллеры, ingress proxy, администратор в придачу - выглядит страшно) Но есть альтернативы.
1) minikube. Упомянут в официальной документации k8s - https://kubernetes.io/docs/tutorials/hello-minikube/ Давно развивается. Поддерживает Win, Mac, Lin. Позволяет запустить k8s внутри VM, Docker образа или даже на голой операционке через механизм драйверов https://minikube.sigs.k8s.io/docs/drivers/ Последние два варианта запуска, увы, доступны только на Linux. Скорость запуска и требования к ресурсам при этом меняются от медленно и много к быстро и мало) Позволяет выбрать Docker или Podman. Позволяет подключать частные Docker репозитории или создать локальный. По умолчанию, как впрочем и все его соперники, стартует в режиме одной node, на которой расположены как служебные модули k8s, так и ваш код. Но можно и добавить node, и создать несколько кластеров. Есть web dashboard. kubectl - утилиту по управлению кластером через CLI API и VM гипервизор нужно ставить отдельно, но есть хорошая инструкция.
Подробнее https://minikube.sigs.k8s.io/docs/start/
2) kind. Работает поверх Docker Desktop, т.е. внутри Docker контейнера. Поддерживает Win, Mac, Lin. В случае Win есть возможность запуска без VM через WSL - https://docs.docker.com/desktop/windows/wsl/. Можно выбрать Docker образ с разными версиями k8s. Запускается достаточно быстро, хорошо совместим с CI системами. Позволяет настраивать частные и локальный Docker Registry, мультикластерную систему. kubectl и Docker Desktop нужно ставить отдельно.
https://kind.sigs.k8s.io/docs/user/quick-start/
3) Docker Desktop. Как ни странно включает в себя урезанный вариант k8s. Включается в админке Docker Desktop. Не кастомизируется. Все в одном - включает kubectl, не нужно ставить отдельно гипервизор. Хорош для начального знакомства.
https://docs.docker.com/desktop/kubernetes/
4) k3s. Интересно происхождение названия - если в слове k8s\kubernetes 10 символов, то k3s - 5, т.к. по задумке он должен потреблять в 2 раза меньше ресурсов. Запускается внутри Docker контейнера. Заточен под запуск на слабых машинах, в том числе ARM. Состоит из одного бинарника, из которого выкинуто все лишнее. Заточен под Lin, но вроде бы появилась поддержка Win. Но не Mac. Самый быстрый и легковесный. Хорошо совместим с CI системами. Позволяет подключать частные репозитории Docker образов. Для хранения конфигурации кластера по умолчанию использует SQLite, но через адаптер позволяет подключить внешнюю СУБД. Подчеркивает, что по умолчанию безопасно настроен. Позиционируется как production ready. Может запускаться как в режиме одной ноды, так и с несколькими, а также в режиме мультикластера.
https://k3s.io/ #cloud #ci
1) minikube. Упомянут в официальной документации k8s - https://kubernetes.io/docs/tutorials/hello-minikube/ Давно развивается. Поддерживает Win, Mac, Lin. Позволяет запустить k8s внутри VM, Docker образа или даже на голой операционке через механизм драйверов https://minikube.sigs.k8s.io/docs/drivers/ Последние два варианта запуска, увы, доступны только на Linux. Скорость запуска и требования к ресурсам при этом меняются от медленно и много к быстро и мало) Позволяет выбрать Docker или Podman. Позволяет подключать частные Docker репозитории или создать локальный. По умолчанию, как впрочем и все его соперники, стартует в режиме одной node, на которой расположены как служебные модули k8s, так и ваш код. Но можно и добавить node, и создать несколько кластеров. Есть web dashboard. kubectl - утилиту по управлению кластером через CLI API и VM гипервизор нужно ставить отдельно, но есть хорошая инструкция.
Подробнее https://minikube.sigs.k8s.io/docs/start/
2) kind. Работает поверх Docker Desktop, т.е. внутри Docker контейнера. Поддерживает Win, Mac, Lin. В случае Win есть возможность запуска без VM через WSL - https://docs.docker.com/desktop/windows/wsl/. Можно выбрать Docker образ с разными версиями k8s. Запускается достаточно быстро, хорошо совместим с CI системами. Позволяет настраивать частные и локальный Docker Registry, мультикластерную систему. kubectl и Docker Desktop нужно ставить отдельно.
https://kind.sigs.k8s.io/docs/user/quick-start/
3) Docker Desktop. Как ни странно включает в себя урезанный вариант k8s. Включается в админке Docker Desktop. Не кастомизируется. Все в одном - включает kubectl, не нужно ставить отдельно гипервизор. Хорош для начального знакомства.
https://docs.docker.com/desktop/kubernetes/
4) k3s. Интересно происхождение названия - если в слове k8s\kubernetes 10 символов, то k3s - 5, т.к. по задумке он должен потреблять в 2 раза меньше ресурсов. Запускается внутри Docker контейнера. Заточен под запуск на слабых машинах, в том числе ARM. Состоит из одного бинарника, из которого выкинуто все лишнее. Заточен под Lin, но вроде бы появилась поддержка Win. Но не Mac. Самый быстрый и легковесный. Хорошо совместим с CI системами. Позволяет подключать частные репозитории Docker образов. Для хранения конфигурации кластера по умолчанию использует SQLite, но через адаптер позволяет подключить внешнюю СУБД. Подчеркивает, что по умолчанию безопасно настроен. Позиционируется как production ready. Может запускаться как в режиме одной ноды, так и с несколькими, а также в режиме мультикластера.
https://k3s.io/ #cloud #ci
Kubernetes
Hello Minikube
This tutorial shows you how to run a sample app on Kubernetes using minikube. The tutorial provides a container image that uses NGINX to echo back all the requests.
Objectives Deploy a sample application to minikube. Run the app. View application logs. Before…
Objectives Deploy a sample application to minikube. Run the app. View application logs. Before…