cloudnative-1c | Овчаренко Дмитрий – Telegram
cloudnative-1c | Овчаренко Дмитрий
228 subscribers
9 photos
19 links
Канал о том, как платформа 1С становится "first-class citizen" в кластерах Kubernetes

@ovcharenko_di
Download Telegram
Что здесь происходит?

TL;DR:
Я решил сделать так, чтобы платформа 1С стала объектом первого класса в кластерах Kubernetes. Дело это непростое, и чтобы оно шло веселее, я создал этот канал.
Обещаю делиться здесь идеями по проектированию, находками, приемами и самыми грязными подробностями о том, какие вещи мне приходится делать, чтобы решить эту задачу. Уверен, что интересно будет тем, кто работает с платформой и хочет расширить кругозор: например, хотя бы немного разобраться в кубере.

===

Чтобы платформа стала тем самым "first-class citizen", надо сделать 3 вещи:

1️⃣ Научиться размещать кластер 1С в k8s так, чтобы пользователи снаружи кластера полноценно и стабильно работали в информационных базах.

С этим все более-менее понятно, но это только на первый взгляд. Через веб-клиент будет работать без проблем, но когда мы захотим зайти в базу в тонком или толстом клиенте, нас будут ждать различные сюрпризы. А толстый клиент нам 100% нужен, потому что в конфигуратор так или иначе заходить придется. Также есть вопросы по лицензиям, но они решаемы.

2️⃣ Научиться администрировать кластер не через rac или встроенные обработки, а с помощью манифестов и kubectl.

Какие операции надо выполнять с помощью манифестов:
• добавление\изменение\удаление рабочих серверов кластера 1С
• изменение параметров серверов
• установка ТНФ
• добавление\изменение\удаление администраторов серверов и кластеров 1С
• и так далее, вплоть до автомасштабирования

Этот список далеко не исчерпывающий и приведен для примера.

3️⃣ Сделать так, чтобы кластер 1С сам подключался к различным средствам observability кластера k8s

С этим тоже более менее понятно, кроме того, что серверы 1С не пишут в stdout\stderr. Зато на них формируется технологический журнал, а в базах еще есть журналы регистрации. Все это - очень ценная информация для мониторинга и хочется, чтобы она была доступна "из коробки".

Сейчас мне видится, что задача такого масштаба будет измеряться в человеко-годах. Ну что же, зато будет много контента :)

Присоединяйтесь!
❤‍🔥32👍2👏1
👋 Знакомство

Меня зовут Овчаренко Дмитрий, я занимаюсь 1С уже лет 15.

Сейчас я технический архитектор 1С в компании Корус Консалтинг. В этом году я получил заветный сертификат "Эксперт по технологическим вопросам". С первой попытки сдачи прошло целых 10 лет!
Последние несколько нет мой фокус в работе сместился с функционала в сторону инфраструктуры, производительности и управления качеством кода.
Я хорошо разбираюсь в облачных технологиях и люблю автоматизировать инфраструктурные задачи.

📺 Мои выступления:
• Infostart Event 2021 Moscow Premiere, Мастер-класс: реализация веб-сервиса по обработке ошибок на OneScript.Web для платформы 1С:Предприятие 8.3.18+
• Желтый клуб СПб, август 2024, нагрузочное тестирование 1С в облаке
• Infostart Event 2024, Облака и "инфраструктура как код": оптимизируем и удешевляем нагрузочное тестирование 1С с помощью современных технологий
• Клуб питерских одинесников, март 2025, Криптозоология. Исследуем неизвестные науке веб-сервисы с помощью автономного сервера

👨‍💻Проекты на гитхабе, в которых я либо автор, либо активный участник:
jenkins-lib - CI-библиотека для Jenkins
onec-docker - сборка самых разных образов с 1С на борту
reperr - инструмент для перехвата и регистрации пользовательских ошибок в 1С
crserver-filter - прокси для хранилища 1С

Зачем мне вдруг понадобилось тащить 1С в k8s? По сути, просто ради развлечения! К тому же, эта задача позволит мне прокачать знания внутреннего устройства k8s и инструментария вокруг него, что будет полезно.
❤‍🔥4👏3👍21
🐘 Зачем это все?

Не буду игнорировать слона в комнате, отвечу на самый очевидный вопрос:

Зачем тащить 1С в k8s? Платформа же для этого не предназначена!


Я тоже считал, что она не предназначена. Не так давно я даже сам лично отговаривал от таких идей коллег и заказчиков.
Поворотный момент случился, когда я познакомился с проектом cloudnative-pg, а чуть позже — со Strimzi. Это два open source проекта, предназначенные для разворачивания в Kubernetes кластеров Postgres и Kafka и управления ими. То есть некий коллектив разработчиков сделал то, что считается невозможным, нерациональным или идеологически неверным: им удалось затащить stateful-приложения в кластер k8s и сделать их там объектами первого класса! А ведь помимо Postgres и Kafka что только сейчас не разворачивают в k8s.

Чем 1С хуже? Какие особенности платформы не позволят сделать то же самое? Похоже, что никаких ограничений нет, всё реализуемо. Действительно, платформа не создавалась в парадигме cloudnative, но ведь и Postgres, и Kafka — тоже.

Вот с такими мыслями и установками я решил начать работу в этом направлении.
🤓3👏2🔥1
Идеальный конечный результат

⚠️ Если терминология и концепции звучат незнакомо - не переживайте и скорее подписывайтесь, потому что в следующих постах я шаг за шагом всё разъясню.


В первом посте я привел примеры операций, которые предстоит реализовать через манифесты и kubectl.
Здесь расскажу чуть подробнее о своем видении. Включайте воображение:

Имеем кластер k8s на несколько узлов, в котором установлен ArgoCD и какой-нибудь observability-стек типа VictoriaMetrics. В ArgoCD добавлено приложение (Application), желаемая конфигурация которого находится в определенной ветке репозитория GitLab. Репозиторий хранит заготовку нашего кластера 1C в виде yaml-манифестов или helm-чарта. Прямо в репозитории мы указываем параметры нашего кластера: количество центральных и рабочих серверов, ТНФ, подключаем сервер лицензирования, подсовываем конфиг для техжурнала. Мы коммитим и пушим наши изменения в репозиторий. ArgoCD определяет, что приложение рассинхронизировано с веткой, получает новые версии манифестов и начинает их применять в кластере. Что при этом происходит:
• поднимаются поды с контейнерами, в которых работают серверы 1С
• стартуют сервисы k8s (LoadBalancer, ClusterIP), поды подключаются к сервисам k8s
• некоторые сервисы k8s публикуются "наружу"
• из серверов 1С собирается кластер, на них настраиваются ТНФ, активируются лицензии
• подключаются экспортеры для техжурнала

Вуаля! Кластер работоспособен, а вы - великолепны. Можно создавать информационные базы и работать. Причем, любые изменения в конфигурации кластера 1С в дальнейшем выполняются точно так же, через git. А там, где git, там и версионирование, а там, где версионирование, там и контроль, и возможность откатить действие. К слову, этот подход называется GitOps.

📈 Наиболее смелая идея - это сделать так, чтобы кластер 1С мог автомасштабироваться в зависимости от нагрузки. Представьте, что когда в нашу ИБ зайдет еще 500 пользователей, то кубер автоматически создаст новый сервер 1С и подключит его к кластеру. А когда нагрузка снизится, то сервер будет удален. How cool is that? 😎

Я еще не решил, нужно ли делать так, чтобы сущность "Информационная база" тоже была объектом первого класса в k8s. Пока думаю, что нет, но в том же Strimzi из предыдущего поста даже такие штуки как Kafka Topic можно создавать с помощью отдельного манифеста. В общем, я буду рад услышать ваши соображения на этот счет.

Кстати, пишите мне пожелания, о чем надо рассказать подробнее. Особенно если ни*его не понял, но очень интересно 😁
😁2
🥼🧪 Обустраиваем лабу

Мне нужно определить место для экспериментов. Я уже выбрал один вариант - kind (или KinD, то есть "Kubernetes in Docker"). Это проект с открытым исходным кодом, который позволяет развернуть полноценный кластер k8s в докере на вашей локальной машине. Каждая нода кластера - это отдельный контейнер. Есть и другие альтернативы: minikube, k3s. В конце концов, можно арендовать минималистичный кластер у одного из облачных провайдеров, но это стоит реальных денег. У меня был опыт с minikube, но он как будто "тяжелее", чем kind. Пока что kind мне показался самым разумным вариантом: он прост в освоении и при этом очень похож на настоящий k8s. Его будет достаточно, чтобы работать в режиме "на коленке" первое время, а дальше посмотрим.

У меня есть подходящая под мои задачи машина с Ubuntu Server 22.04, само собой, без графического интерфейса. Она и будет моим НИИ на первое время. Однако, мне предстоит редактировать много развесистых yaml-ов, поэтому очень важно иметь удобный редактор, например VS Code. Причем, VS Code я буду открывать локально, а уже в нем по ssh я буду работать файлами и консолью удаленного сервера. Лепота!

Так, kind создаст нам кластер k8s, но мне этим кластером еще нужно будет управлять. Для этого потребуется kubectl.
На моей "лабораторной" машине уже есть docker, поэтому ставить я буду только kind и kubectl. Установка обоих инструментов заключается, по сути, в скачивании двух бинарников. Лепота №2! Очень люблю за такое проекты, написанные на go.

Как заведено, прежде чем делать что-либо свое, разумно будет развернуть "hello-world". Для kind - это создать кластер с конфигом по умолчанию, задеплоить какой-нибудь стандартный nginx и потыкать в него палочкой браузером или curl-ом.
Расписывать это здесь не буду, задача тривиальная.

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

Лаба более менее обустроена, завтра начинаем варить, ага 😎 думать над тем, как засунуть 1С в k8s 🤓
3
Когда всего месяц назад пересматривал Breaking Bad и ассоциация с лабораторией у тебя сейчас может быть только одна ⚗️
😁3
👀 Как разместить кластер 1С в кубере?

Да очень просто! Надо взять и установить соответствующий helm-чарт, вот так:
haha helm install go brrr...


Для большинства приложений такой сценарий действительно применим, но для 1С - нет.

Я знаю только один helm-чарт с сервером 1С от Руслана Жданова (@TheDemonCat). Насколько мне известно, Руслан - первопроходец этой темы, но его чарт не подразумевает работу с кластером 1С извне. А еще с его помощью можно поднять несколько серверов 1С, но собрать их в кластер не получится.

Это не совсем подходит под описанный мной ранее идеальный конечный результат, поэтому будем делать все самостоятельно.

✏️ Что такое этот ваш чарт?
k8s все объекты внутри себя представляет в виде так называемых манифестов - файлов в формате yml. Эти файлы описывают состояние объектов в кластере. Чтобы создать или изменить объект, нужно применить соответствующий манифест к кластеру. k8s "увидит", что текущее состояние отличается от желаемого и сделает все от него зависящее, чтобы устранить эти расхождения.

k8s состоит из множества разных объектов, под каждый есть свои манифесты. Вот они слева направо:
Pod, ConfigMap, ReplicaSet, Deployment, StatefulSet, Ingress, Service, Namespace, PersistentVolumeClaim, PersistentVolume, Role и тд и тп.

Более-менее сложное приложение обычно состоит из десятков разных манифестов. Чтобы управлять ими было проще, разработчики придумали Helm. По сути, это пакетный менеджер для k8s. Он позволяет "упаковать" все манифесты приложения в одну сущность под названием "чарт", а все параметры этого чарта вынести в отдельный файл. Возможности Helm этим не ограничиваются, но об этом как-нибудь в другой раз.

Итак, для проектирования кластера 1С в Kubernetes нужно разобраться с назначением ключевых объектов k8s, чтобы понять, какие из них подходят для нашего конструктора и как их лучше скомпоновать.

С этого поста начинается рубрика #k8s_101, stay tuned 📻
3👍1🔥1
🎓 Pod, Deployment, StatefulSet

Рубрика #k8s_101 начинается с этих трех объектов.

🧩 Pod
Это самый базовый объект k8s, точнее, это некая абстракция. Именно Pod определяет, какие контейнеры должны быть запущены. Чаще всего в поде один контейнер, но их может быть и несколько. Все поды размещаются на нодах кластера k8s и могут взаимодействовать друг с другом. Практически всегда поды описываются не напрямую, а через другие объекты - Deployment или StatefulSet.

🧩 Deployment
Используется для описания stateless-приложений.

Stateless-приложения - это приложения, которые не сохраняют свое состояние. А экземпляры таких приложений являются взаимозаменяемыми.


Спецификация Deployment описывает шаблон для создания подов и требуемое их количество. Также этот объект реализует различные стратегии обновления и масштабирование.

🧩 StatefulSet
В отличие от stateless, stateful-приложения должны хранить свое состояние. Получается, что каждый экземпляр должен иметь какой-то стабильный идентификатор, который не изменится в случае перезапуска и в случае его переноса на другую ноду. Самый простой пример stateful-приложения - база данных, например, Postgres. Для описания таких приложений используется StatefulSet. Помимо количества экземпляров приложения, в StatefulSet также описываются тома для хранения постоянных данных. Кластер будет сохранять эти тома за теми же подами. Важно понимать, что изначально поды - эфемерные объекты, но в StatefulSet они становятся очень даже "постоянными".

🪄 Перекладываем то, что узнали, на мир 1С
Очевидно, что каждый сервер 1С внутри кластера k8s должен быть отдельным подом. Но что использовать для описания подов - Deployment или StatefulSet? Каким приложением является сервер 1С - stateless или stateful?

🤔 Рассуждаем
На сервере 1С есть каталог кластера, в котором хранятся (как минимум):
• реестр кластера, настройки кластера
• рабочие каталоги ИБ с журналом регистрации, индексом полнотекстового поиска
• сеансовые данные

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

Еще есть такой момент: центральные серверы назначают для нового соединения рабочий процесс на конкретном сервере. Если в ходе работы пользователя именно этого сервера вдруг не окажется, то пользователь получит ошибку. Значит, серверы 1С в кластере не взаимозаменяемы.

И вдогонку: для добавления сервера 1С в кластер недостаточно просто поднять еще один под, необходимо также выполнить команду rac server insert и настроить на новом сервере требования назначения функциональности.

✏️ Вывод:
Сервер 1С - это stateful-приложение и описывать его надо как StatefulSet.

Завтра очень кратко расскажу про то, как поды в k8s общаются друг с другом \ с внешним миром и как это все подружить с 1С!
32🔥2
🔗 Service, Ingress

Продолжаю рубрику #k8s_101!

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

🔎 ClusterIP
Поды - вещь эфемерная, поэтому Kubernetes не заботится о том, чтобы у них были стабильные IP-адреса. Сервис типа ClusterIP нужен для того, чтобы у группы подов появился фиксированный внутренний IP-адрес. Этот адрес будет доступен только внутри кластера. Когда него придет запрос, Kubernetes будет знать, каким конкретно подам его направить.

🔎 Headless Service
Этот тип сервиса нужен для того, чтобы наладить обращение к конкретному поду по имени внутри кластера. По сути, этот сервис просто создает специальные DNS-записи внутри кластера. Такой тип сервисов часто используется для stateful-приложений. Это надо запомнить, пригодится!

🔎 NodePort
Сервис типа NodePort открывает указанные порты на каждой ноде кластера. Например, есть кластер Kubernetes из трех узлов. Если создать в нем сервис NodePort с портом 30001, то этот порт будет открыт на всех трех нодах. Запросы по IP-адресу любой ноды и по порту NodePort будут направлены в соответствующие поды. Этот тип сервиса удобен для разработки и отладки, но редко используется в промышленных системах.

🔎 LoadBalancer
Сервис типа LoadBalancer - это один из способов публикации приложения в Kubernetes. Важно понимать, что реализует такой сервис облачный провайдер. То есть да, это объект Kubernetes и манифест для него нужно писать самостоятельно, но где-то в недрах вашего облака реализован специальный контроллер, который определит, что вы добавили LoadBalancer и настроит ваше облако так, чтобы трафик шел "куда надо".

🔎 Ingress (Gateway API)
С Ingress ситуация похожа на LoadBalancer в том плане что эта вещь тоже работает на стороне облачного провайдера. Обычно Ingress обрабатывает HTTP(S) трафик, но многие реализации поддерживают и другие протоколы, например, TCP.
На замену Ingress в свежих версиях Kubernetes пришел Gateway API.

Пост получился довольно большим, поэтому примерять сервисы Kubernetes к кластеру 1С я продолжу завтра!
2🔥21
🕗 В прошлом посте я разобрал базовые компоненты Kubernetes Networking.

Так что там с 1С?
Открываем документацию к платформе. В ней написано, что толстый и тонкий клиент 1С работает с кластером 1С по TCP. Причем, сначала клиент обращается к менеджеру кластера, а менеджер кластера передает клиенту адрес рабочего процесса. Понятнее будет на схеме, см. картинку.

Имеем кластер 1С из двух серверов: srv-1c-01 (центральный) и srv-1c-02 (рабочий). Пользователь заходит в информационную базу Srvr="srv-1c-01";Ref="ERP".
1️⃣ Тонкий клиент подключается к менеджеру сервера (rmngr), порт 1541.
2️⃣ Менеджер сервера регулярно синхронизирует информацию о состоянии всего кластера и знает, где работают рабочие процессы, как они загружены и какого рода нагрузку можно на них подавать.
3️⃣ Менеджер кластера выбирает наиболее подходящий рабочий процесс и отправляет клиенту его адрес в формате сервер:порт.
4️⃣ Тонкий клиент устанавливает соединение с рабочим процессом и начинает работу в информационной базе.

На что надо обратить внимание:
📌 в примере выше центральный сервер направил клиента на другой рабочий сервер, а это значит, что клиент должен иметь возможность подключаться к любому серверу кластера 1С напрямую
📌 имя рабочего сервера, которое выдается клиенту, берется из реестра кластера: клиенту будет выдано именно то имя, которое там указано
📌 когда центральных серверов 1С больше одного, в настройках подключения к базе нужно перечислить все. Тогда клиент 1С будет обращаться сначала к первому, потом ко второму в случае недоступности первого и т.д.

Получается, что для размещения кластера 1С в Kubernetes надо решить две задачи:
1️⃣ каждый сервер 1С, размещенный в кластере Kubernetes и обслуживающий клиентские соединения по TCP, должен быть выставлен наружу Kubernetes
2️⃣ надо сделать так, чтобы клиент, который находится за пределами кластера Kubernetes, мог разрешать DNS-имена серверов 1С в IP-адреса

Решаем первую задачу.
Есть три варианта сделать так, чтобы серверы 1С были выставлены наружу Kubernetes:

🖼️ NodePort
Сервис типа NodePort открывает указанные порты на каждом узле кластера Kubernetes. Это приведет к тому, что в реальных больших кластерах Kubernetes диапазоны портов разных кластеров 1С должны быть очень тщательно спланированы заранее. В противном случае переезд сервера 1С с узла на узел легко может привести к конфликтам. Этот вариант технически приемлем, но сейчас выглядит для меня очень неуклюжим.

🖼️ LoadBalancer
Под каждый сервер 1С надо создать отдельный LoadBalancer. LoadBalancer будет иметь отдельный внешний IP и весь трафик, приходящий на него, будет направлен на конкретный Pod с сервером 1С. Тоже не идеально, но пока что этот вариант мне больше всего по душе.

🖼️ Ingress
ingress-nginx можно настроить так, чтобы TCP-трафик перенаправлялся на определенный Service. Мой опыт использования публичных облаков говорит о том, что Ingress тяжелее, чем остальные варианты. Как минимум, он долго перенастраивается при внесении изменений в конфиг. Это может в будущем стать критичным недостатком, ведь я хочу динамически масштабировать кластер 1С, поэтому перенастройка должна выполняться за секунды, а не за минуты.

Вывод:
Пока что я выбираю реализацию на LoadBalancer, а Ingress оставлю как запасной вариант для TCP и как основной вариант для HTTP(S).

Решение второй задачи будет в следующем посте. Самое время подписаться, потому что shit is getting real 😎
Please open Telegram to view this post
VIEW IN TELEGRAM
3🔥21
Решение второй задачи из прошлого поста.

Напомню:

Надо сделать так, чтобы клиент, который находится за пределами кластера Kubernetes, мог разрешать имена серверов 1С в IP-адреса


Подумал, поприкидывал. Родилась схема, см. картинку.

Очень упрощенно она читается так:
1️⃣ CoreDNS кластера Kubernetes выставляется наружу через отдельный LoadBalancer с 53 портом.
2️⃣ Клиентская машина настраивается так, чтобы определенные зоны резолвились именно через CoreDNS кубера. Тогда клиент при открытии 1С зарезолвит имя сервера во внешний IP LoadBalancer-а.
3️⃣ LoadBalancer направляет запрос к единственному поду за ним - к центральному серверу srv-1c-01, а тот вернет адрес рабочего процесса, например srv-1c-02:1560. Обратите внимание: сервер, где находится рабочий процесс, уже другой! Все, как в реальной жизни.
4️⃣ Клиент точно так же резолвит имя srv-1c-02 во внешний IP другого LoadBalancer-а и устанавливает соединение с рабочим процессом по порту 1560.
5️⃣ Где-то тут нужны будут Headless-сервисы, которые, собственно, и создадут нужные DNS записи в CoreDNS кластера Kubernetes.

На бумаге решение выглядит рабочим, надо пробовать! 🚀
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥3
😺 Какая же серьезная инициатива без отдельной организации на GitHub?

Создал репозиторий, в который буду выкладывать скрипты, манифесты и инструкции.

https://github.com/cloudnative-1c/1c-k8s-lab

Пока что добавил инструкции по подготовке окружения, а уже совсем скоро там появится прототип!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍4