👀 Как разместить кластер 1С в кубере?
Да очень просто! Надо взять и установить соответствующий helm-чарт, вот так:
Для большинства приложений такой сценарий действительно применим, но для 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 📻
Да очень просто! Надо взять и установить соответствующий 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-приложений.
Спецификация Deployment описывает шаблон для создания подов и требуемое их количество. Также этот объект реализует различные стратегии обновления и масштабирование.
🧩 StatefulSet
В отличие от stateless, stateful-приложения должны хранить свое состояние. Получается, что каждый экземпляр должен иметь какой-то стабильный идентификатор, который не изменится в случае перезапуска и в случае его переноса на другую ноду. Самый простой пример stateful-приложения - база данных, например, Postgres. Для описания таких приложений используется StatefulSet. Помимо количества экземпляров приложения, в StatefulSet также описываются тома для хранения постоянных данных. Кластер будет сохранять эти тома за теми же подами. Важно понимать, что изначально поды - эфемерные объекты, но в StatefulSet они становятся очень даже "постоянными".
🪄 Перекладываем то, что узнали, на мир 1С
Очевидно, что каждый сервер 1С внутри кластера k8s должен быть отдельным подом. Но что использовать для описания подов - Deployment или StatefulSet? Каким приложением является сервер 1С - stateless или stateful?
🤔 Рассуждаем
На сервере 1С есть каталог кластера, в котором хранятся (как минимум):
• реестр кластера, настройки кластера
• рабочие каталоги ИБ с журналом регистрации, индексом полнотекстового поиска
• сеансовые данные
Потеря любого из этих компонентов приведет к полной / частичной недоступности системы, либо к ошибкам у пользователей.
Еще есть такой момент: центральные серверы назначают для нового соединения рабочий процесс на конкретном сервере. Если в ходе работы пользователя именно этого сервера вдруг не окажется, то пользователь получит ошибку. Значит, серверы 1С в кластере не взаимозаменяемы.
И вдогонку: для добавления сервера 1С в кластер недостаточно просто поднять еще один под, необходимо также выполнить команду
✏️ Вывод:
Сервер 1С - это stateful-приложение и описывать его надо как StatefulSet.
Завтра очень кратко расскажу про то, как поды в k8s общаются друг с другом \ с внешним миром и как это все подружить с 1С!
Рубрика #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С!
❤3✍2🔥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С я продолжу завтра!
Продолжаю рубрику #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🔥2✍1
🕗 В прошлом посте я разобрал базовые компоненты Kubernetes Networking.
Так что там с 1С?
Открываем документацию к платформе. В ней написано, что толстый и тонкий клиент 1С работает с кластером 1С по TCP. Причем, сначала клиент обращается к менеджеру кластера, а менеджер кластера передает клиенту адрес рабочего процесса. Понятнее будет на схеме, см. картинку.
Имеем кластер 1С из двух серверов: srv-1c-01 (центральный) и srv-1c-02 (рабочий). Пользователь заходит в информационную базу
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 😎
Так что там с 1С?
Открываем документацию к платформе. В ней написано, что толстый и тонкий клиент 1С работает с кластером 1С по TCP. Причем, сначала клиент обращается к менеджеру кластера, а менеджер кластера передает клиенту адрес рабочего процесса. Понятнее будет на схеме, см. картинку.
Имеем кластер 1С из двух серверов: srv-1c-01 (центральный) и srv-1c-02 (рабочий). Пользователь заходит в информационную базу
Srvr="srv-1c-01";Ref="ERP". сервер:порт.На что надо обратить внимание:
📌 в примере выше центральный сервер направил клиента на другой рабочий сервер, а это значит, что клиент должен иметь возможность подключаться к любому серверу кластера 1С напрямую
📌 имя рабочего сервера, которое выдается клиенту, берется из реестра кластера: клиенту будет выдано именно то имя, которое там указано
📌 когда центральных серверов 1С больше одного, в настройках подключения к базе нужно перечислить все. Тогда клиент 1С будет обращаться сначала к первому, потом ко второму в случае недоступности первого и т.д.
Получается, что для размещения кластера 1С в Kubernetes надо решить две задачи:
Решаем первую задачу.
Есть три варианта сделать так, чтобы серверы 1С были выставлены наружу Kubernetes:
Сервис типа NodePort открывает указанные порты на каждом узле кластера Kubernetes. Это приведет к тому, что в реальных больших кластерах Kubernetes диапазоны портов разных кластеров 1С должны быть очень тщательно спланированы заранее. В противном случае переезд сервера 1С с узла на узел легко может привести к конфликтам. Этот вариант технически приемлем, но сейчас выглядит для меня очень неуклюжим.
Под каждый сервер 1С надо создать отдельный LoadBalancer. LoadBalancer будет иметь отдельный внешний IP и весь трафик, приходящий на него, будет направлен на конкретный Pod с сервером 1С. Тоже не идеально, но пока что этот вариант мне больше всего по душе.
ingress-nginx можно настроить так, чтобы TCP-трафик перенаправлялся на определенный Service. Мой опыт использования публичных облаков говорит о том, что Ingress тяжелее, чем остальные варианты. Как минимум, он долго перенастраивается при внесении изменений в конфиг. Это может в будущем стать критичным недостатком, ведь я хочу динамически масштабировать кластер 1С, поэтому перенастройка должна выполняться за секунды, а не за минуты.
Вывод:
Пока что я выбираю реализацию на LoadBalancer, а Ingress оставлю как запасной вариант для TCP и как основной вариант для HTTP(S).
Решение второй задачи будет в следующем посте. Самое время подписаться, потому что
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥2✍1
Решение второй задачи из прошлого поста.
Напомню:
Подумал, поприкидывал. Родилась схема, см. картинку.
Очень упрощенно она читается так:
1️⃣ CoreDNS кластера Kubernetes выставляется наружу через отдельный LoadBalancer с 53 портом.
2️⃣ Клиентская машина настраивается так, чтобы определенные зоны резолвились именно через CoreDNS кубера. Тогда клиент при открытии 1С зарезолвит имя сервера во внешний IP LoadBalancer-а.
3️⃣ LoadBalancer направляет запрос к единственному поду за ним - к центральному серверу
4️⃣ Клиент точно так же резолвит имя
5️⃣ Где-то тут нужны будут Headless-сервисы, которые, собственно, и создадут нужные DNS записи в CoreDNS кластера Kubernetes.
На бумаге решение выглядит рабочим, надо пробовать! 🚀
Напомню:
Надо сделать так, чтобы клиент, который находится за пределами кластера Kubernetes, мог разрешать имена серверов 1С в IP-адреса
Подумал, поприкидывал. Родилась схема, см. картинку.
Очень упрощенно она читается так:
srv-1c-01, а тот вернет адрес рабочего процесса, например srv-1c-02:1560. Обратите внимание: сервер, где находится рабочий процесс, уже другой! Все, как в реальной жизни.srv-1c-02 во внешний IP другого LoadBalancer-а и устанавливает соединение с рабочим процессом по порту 1560.На бумаге решение выглядит рабочим, надо пробовать! 🚀
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥3
Создал репозиторий, в который буду выкладывать скрипты, манифесты и инструкции.
https://github.com/cloudnative-1c/1c-k8s-lab
Пока что добавил инструкции по подготовке окружения, а уже совсем скоро там появится прототип!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍4
Последние несколько вечеров я занимаюсь выпуском релизов новых версий gitsync-plugins (успешно) и gitsync (пока не очень успешно).
Но мне все равно есть, что показать: как поднять кластер kind и развернуть на нем приложение.
Как полагается, тренироваться надо накошках hello-world.
Инструкции разместил тут.
В результате у вас будет локальный Kubernetes из одного узла, на нем разворачивается два экземпляра nginx. Наружу он публикуется на
Обычно во всяких опасных видео на ютубе говорят "не повторяйте это дома", но тут немного другая ситуация, поэтому я говорю: "смело повторяйте это дома!" 😈
Дальше будет поинтереснее: соберем образ сервера 1С и запустим в Kubernetes уже его 🔥
Но мне все равно есть, что показать: как поднять кластер kind и развернуть на нем приложение.
Как полагается, тренироваться надо на
Инструкции разместил тут.
В результате у вас будет локальный Kubernetes из одного узла, на нем разворачивается два экземпляра nginx. Наружу он публикуется на
localhost:8080 через port forwardingОбычно во всяких опасных видео на ютубе говорят "не повторяйте это дома", но тут немного другая ситуация, поэтому я говорю: "смело повторяйте это дома!" 😈
Дальше будет поинтереснее: соберем образ сервера 1С и запустим в Kubernetes уже его 🔥
🔥5❤1👍1
🐳 Как обещал, в этот раз будем собирать образ с сервером 1С.
Почему нельзя взять готовый образ, как для nginx? Потому, что nginx распространяется свободно, а платформа 1С - нет. Образы с платформой 1С нельзя публиковать в общем доступе. Кстати, может кто-то и пушит образы в публичные репозитории, но он явно делает это не подумавши.
Правильное решение такое: взять свой логин и пароль от ИТС, клонировать себе проект onec-docker и собрать образ самостоятельно.
Я подготовил детальные инструкции по сборке в своем репозитории, см. тут: 02-1c-docker-image.
Кстати, во время подготовки этого поста мне пришлось доработать скрипты в проекте onec-docker, чтобы образы можно было собирать локально, без Docker Registry.
После выполнения инструкций у вас получится образ с сервером 1С.
Предлагаю его немножко препарировать. Полезно знать, с чем имеешь дело.
Сразу иду в самый конец
Что интересно в этом фрагменте:
🔘 ENTRYPOINT устанавливается из файла docker-entrypoint.sh, его рассмотрим далее
🔘 в EXPOSE не перечислены все порты рабочих процессов из стандартного диапазона, но это нужно больше для красоты
🔘 в CMD ["ragent"] означает, что в скрипт docker-entrypoint.sh будет передан параметр "ragent"
Ок, что интересного внутри
🔘 по умолчанию скрипт запускает процессы
🔘
🔘 морской практикой
🔘 все стандартные параметры запуска
🔘 в CMD можно вместо параметра "ragent" передать свою команду
Что еще в этом образе:
🔘 сборка состоит из нескольких этапов и финальный образ построен на минималистичном
🔘 добавлен симлинк
В общем, образ мне нравится, огромное спасибо автору - Егору Иванову и всем, кто приложил руку к
Единственное, что немного смущает: в таком контейнере не соблюдается принцип one service per container, потому что помимо сервера 1С в нем будет работать и ras, который в общем случае можно запустить отдельно. Но этот принцип - это тоже не догма и пока что это все вообще не принципиально. Сейчас игнорируем, но на будущее запомним.
Образ есть, в следующий раз засунем его в... (гусары, молчать!)kind и запустим 😁
PS: параллельно занимаюсь полировкой нового релиза gitsync, версия 3.7.0 уже почти готова.
Почему нельзя взять готовый образ, как для nginx? Потому, что nginx распространяется свободно, а платформа 1С - нет. Образы с платформой 1С нельзя публиковать в общем доступе. Кстати, может кто-то и пушит образы в публичные репозитории, но он явно делает это не подумавши.
Правильное решение такое: взять свой логин и пароль от ИТС, клонировать себе проект onec-docker и собрать образ самостоятельно.
Я подготовил детальные инструкции по сборке в своем репозитории, см. тут: 02-1c-docker-image.
Кстати, во время подготовки этого поста мне пришлось доработать скрипты в проекте onec-docker, чтобы образы можно было собирать локально, без Docker Registry.
После выполнения инструкций у вас получится образ с сервером 1С.
Предлагаю его немножко препарировать. Полезно знать, с чем имеешь дело.
Сразу иду в самый конец
server/Dockerfile и вижу это:# Настройка точки входа и экспонирование портов
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
EXPOSE 1540 1541 1545 1560
CMD ["ragent"]
Что интересно в этом фрагменте:
Ок, что интересного внутри
docker-entrypoint.sh?ragent и rasragent запускается через exec, то есть он станет PID 1. А это значит, что контейнер скорее всего будет корректно обрабатывать сигналы типа SIGTERM. Это очень правильный подход, это мы одобряем.ragent и ras запускаются через gosu от имени usr1cv8, что тоже является хорошей ragent и ras устанавливаются по умолчанию, но могут быть переопределеныЧто еще в этом образе:
debian:bookworm-slim/opt/1cv8/current, что *капец* как удобноВ общем, образ мне нравится, огромное спасибо автору - Егору Иванову и всем, кто приложил руку к
onec-docker. Да и мне самому тоже, чего уж там 😅Единственное, что немного смущает: в таком контейнере не соблюдается принцип one service per container, потому что помимо сервера 1С в нем будет работать и ras, который в общем случае можно запустить отдельно. Но этот принцип - это тоже не догма и пока что это все вообще не принципиально. Сейчас игнорируем, но на будущее запомним.
Образ есть, в следующий раз засунем его в... (гусары, молчать!)
PS: параллельно занимаюсь полировкой нового релиза gitsync, версия 3.7.0 уже почти готова.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3❤1👍1
Всем привет! Продолжаю тащить 1С в кубер 😎
Напомню: я хочу не просто запустить сервер 1С в Kubernetes, а хочу сделать так, чтобы с ним можно было работать из тонкого/толстого клиента снаружи Kubernetes.
Я думал было уместить все в один пост, но материала оказалось много, поэтому сделаю несколько частей. Подпишись, чтобы не пропустить!
Как обычно, все манифесты и скрипты по мере моего продвижения будут выкладывать в этом репозитории. Для сегодняшнего "занятия" материалы уже выложил.
Прокомментирую важные моменты по дизайну решения:
📌 можно запариться и развернуть Docker Registry с HTTPS, а можно просто "загрузить" образ сервера 1С прямо в kind командой
📌 каждый сервер 1С определяется через отдельный StatefulSet с количеством реплик равным 1
В будущем я хочу делать так, чтобы разные серверы 1С имели разные настройки, как минимум разные ТНФ. Для этого стандартный StatefulSet не подходит: в нем для всех реплик используется единая спецификация. То есть все поды-реплики хоть и будут иметь некую идентичность, настройки у них будут одинаковыми. Получается, в будущем надо будет придумать свой объект для кубера, описывающий сущность типа «группа серверов 1С». Да, такое возможно, но это я сильно вперед забегаю. Пока останавливаюсь на формуле
📌 сервисы Kubernetes
Помимо манифестов StatefulSet, в
Первый сервис нужен для взаимодействия с серверами по имени. Второй нужен для того, чтобы опубликовать серверы 1С наружу. См. схему из предыдущего поста. В манифестах сервисов я указал все порты 1С по умолчанию и успел огорчиться от того, что в них нельзя задавать порты диапазонами 😢 Из-за этого манифест превращается в простыню на 600+ строк.
Как сервисы понимают, к каким StatefulSet им надо "присоединиться"? Все просто - по совпадению полей
📌 использование MetalLB
В моей лаборатории нет настоящего managed-кластера Kubernetes, которым управляет большой облачный провайдер, поэтому приходится решать многие вопросы самостоятельно. Например, выставлять сервисы наружу я буду с помощью собственного балансировщика на базе MetalLB.
В манифесте
А вот о настройке CoreDNS + resolvctl и обо всем остальном я расскажу в следующих постах.
Кстати, я совсем забыл: куда же без базы данных? Предлагаю решить голосованием, какой вариант мне поднять - обычный контейнер с Postgres от 1C или сразу сloudnative-pg? Как говорится, чего мелочиться-то?
PS:тем временем релиз gitsync 3.7.0 я наконец-таки выпустил ! Ура!
Напомню: я хочу не просто запустить сервер 1С в Kubernetes, а хочу сделать так, чтобы с ним можно было работать из тонкого/толстого клиента снаружи Kubernetes.
Я думал было уместить все в один пост, но материала оказалось много, поэтому сделаю несколько частей. Подпишись, чтобы не пропустить!
Как обычно, все манифесты и скрипты по мере моего продвижения будут выкладывать в этом репозитории. Для сегодняшнего "занятия" материалы уже выложил.
Прокомментирую важные моменты по дизайну решения:
kind load docker-image. Я выбрал второе 😅В будущем я хочу делать так, чтобы разные серверы 1С имели разные настройки, как минимум разные ТНФ. Для этого стандартный StatefulSet не подходит: в нем для всех реплик используется единая спецификация. То есть все поды-реплики хоть и будут иметь некую идентичность, настройки у них будут одинаковыми. Получается, в будущем надо будет придумать свой объект для кубера, описывающий сущность типа «группа серверов 1С». Да, такое возможно, но это я сильно вперед забегаю. Пока останавливаюсь на формуле
один сервер 1С = один StatefulSet с одной репликой. Кстати, для начала я в кубере разверну не один кластер из двух серверов 1С, а два разных кластера. Но это тоже пока.Помимо манифестов StatefulSet, в
cluster1c.yaml есть также манифесты для сервисов двух типов: Headless Service и LoadBalancer.Первый сервис нужен для взаимодействия с серверами по имени. Второй нужен для того, чтобы опубликовать серверы 1С наружу. См. схему из предыдущего поста. В манифестах сервисов я указал все порты 1С по умолчанию и успел огорчиться от того, что в них нельзя задавать порты диапазонами 😢 Из-за этого манифест превращается в простыню на 600+ строк.
Как сервисы понимают, к каким StatefulSet им надо "присоединиться"? Все просто - по совпадению полей
selector, которые указываются и в Service, и в StatefulSet. Там и там они должны совпадать.В моей лаборатории нет настоящего managed-кластера Kubernetes, которым управляет большой облачный провайдер, поэтому приходится решать многие вопросы самостоятельно. Например, выставлять сервисы наружу я буду с помощью собственного балансировщика на базе MetalLB.
В манифесте
metallb.yaml я задал два диапазона IP-адресов: один для серверов 1С, другой для DNS. Диапазон для DNS состоит из одного адреса и имеет свойство autoAssign: false. Это нужно для того, чтобы этот адрес не назначался автоматом никуда, а использовался только публикации сервиса DNS.А вот о настройке CoreDNS + resolvctl и обо всем остальном я расскажу в следующих постах.
Кстати, я совсем забыл: куда же без базы данных? Предлагаю решить голосованием, какой вариант мне поднять - обычный контейнер с Postgres от 1C или сразу сloudnative-pg? Как говорится, чего мелочиться-то?
PS:
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
В прошлом посте и в опросе к нему я как-то на автомате написал "Postgres от 1С", имея в виду "Postgres Pro 1C".
Да, это разные сборки и между ними есть путаница. А ведь есть еще Tantor, Pangolin и Jatoba, но они хотя бы называются сильно по-разному.
Так вот, два самых популярных бесплатных варианта Postgres для 1С:
1️⃣ Сборка "PostgreSQL с патчем от 1С" - Postgres с патчами от фирмы 1С, публикуется на releases.1c.ru
2️⃣ Сборка "Postgres Pro 1С" - Postgres с патчами от Postgres Pro, публикуется на 1c.postgres.ru
Оба варианта официально поддерживаются платформой и оба можно использовать без ограничений, но для своих экспериментов я планировал задействовать вторую, которая "Postgres Pro 1С".
Fun fact: СУБД "Postgres Pro" - это не второе название "Postgres Pro 1С", а вообще отдельный продукт 😳 Он платный, у него есть редакции Standard (Certified), Enterprise (Certified), Enterprise для 1С и еще какие-то. В общем, нейминг для "бесплатных" вариантов получился не очень удачный, мягко говоря.
Опрос показал, что хотим развернуть именно вариант cloudnative-pg (далее - cnpg). Ну что ж, поехали!
cnpg - это оператор для Kubernetes с очень подробной документацией.
🟡 Что такое оператор?
Если очень упрощенно, то оператор - это такая программа, которая умеет управлять конкретным приложением и его жизненным циклом в кластере Kubernetes. Это некая прослойка между приложением и внутренним API Kubernetes.
🟡 Когда нужны операторы?
Стандартные возможности Kubernetes покрывают условно 99% ситуаций в жизненном цикле самых разных приложений. Однако, есть ряд особенных приложений (или приложений с особенностями 🤤), для которых встроенного API и абстракций Kubernetes недостаточно. Postgres как раз попадает в их число, из-за своей stateful природы а также из-за необходимости кластеризации, репликации, бекапирования и т.д. Угадайте, какая еще платформа подходит под этот профиль? 🤔
Kubernetes API — штука расширяемая, и большая часть операторов добавляет в Kubernetes свои кастомные ресурсы: то есть оператор может работать не только со встроенными объектами типа
Очень упрощенная аналогия с платформой 1С: представьте, если бы у обычного разработчика 1С была бы возможность создать новый вид объекта метаданных, полностью описать его поведение и взаимодействие с другими механизмами платформы, а затем пользоваться этим объектом наряду со стандартными? Так вот, Kubernetes позволяет делать подобные штуки!
Кстати, помимо cnpg есть и другие операторы Postgres, например, Zalando и Stolon. cnpg вроде как моложе их обоих, но имеет очень богатые возможности и в 2025 году он прямо-таки "выстрелил" в плане популярности 🚀
🟡 Установка cnpg
Простейшее развертывание cnpg заключается в установке оператора и применении манифеста вида "Cluster". Да, в кластере Kubernetes мы будем разворачивать кластер Postgres. А потом в кластере Kubernetes развернем и кластер 1С. В этом канале будет еще много про
Я дополнил лабу 03-kind-hello-world-1c инструкциями по разворачиванию cnpg.
Из интересного там:
1️⃣ я переопределил стандартный образ cnpg на образ от Егора Иванова, в нем установлена как раз сборка "Postgres Pro 1С".
2️⃣ при подготовке стенда я столкнулся с тем, что cnpg ожидает, что для postgres:postgres UID и GID будут равны
Кстати, я не уверен, что образ Егора прокатит для cnpg. Документация cnpg говорит, что официально поддерживаются только их родные образы. Но сейчас кластер инициировался успешно 👀
Да, это разные сборки и между ними есть путаница. А ведь есть еще Tantor, Pangolin и Jatoba, но они хотя бы называются сильно по-разному.
Так вот, два самых популярных бесплатных варианта Postgres для 1С:
Оба варианта официально поддерживаются платформой и оба можно использовать без ограничений, но для своих экспериментов я планировал задействовать вторую, которая "Postgres Pro 1С".
Fun fact: СУБД "Postgres Pro" - это не второе название "Postgres Pro 1С", а вообще отдельный продукт 😳 Он платный, у него есть редакции Standard (Certified), Enterprise (Certified), Enterprise для 1С и еще какие-то. В общем, нейминг для "бесплатных" вариантов получился не очень удачный, мягко говоря.
Опрос показал, что хотим развернуть именно вариант cloudnative-pg (далее - cnpg). Ну что ж, поехали!
cnpg - это оператор для Kubernetes с очень подробной документацией.
Если очень упрощенно, то оператор - это такая программа, которая умеет управлять конкретным приложением и его жизненным циклом в кластере Kubernetes. Это некая прослойка между приложением и внутренним API Kubernetes.
Стандартные возможности Kubernetes покрывают условно 99% ситуаций в жизненном цикле самых разных приложений. Однако, есть ряд особенных приложений (или приложений с особенностями 🤤), для которых встроенного API и абстракций Kubernetes недостаточно. Postgres как раз попадает в их число, из-за своей stateful природы а также из-за необходимости кластеризации, репликации, бекапирования и т.д. Угадайте, какая еще платформа подходит под этот профиль? 🤔
Kubernetes API — штука расширяемая, и большая часть операторов добавляет в Kubernetes свои кастомные ресурсы: то есть оператор может работать не только со встроенными объектами типа
StatefulSet, Service и т.д., но и добавляет свои виды объектов. Например, cnpg определяет такой объект как ScheduledBackup, с помощью него в cnpg можно декларативно управлять бекапами кластера. В Kubernetes такие определения называются "Custom Resource Definitions" или CRD.Очень упрощенная аналогия с платформой 1С: представьте, если бы у обычного разработчика 1С была бы возможность создать новый вид объекта метаданных, полностью описать его поведение и взаимодействие с другими механизмами платформы, а затем пользоваться этим объектом наряду со стандартными? Так вот, Kubernetes позволяет делать подобные штуки!
Кстати, помимо cnpg есть и другие операторы Postgres, например, Zalando и Stolon. cnpg вроде как моложе их обоих, но имеет очень богатые возможности и в 2025 году он прямо-таки "выстрелил" в плане популярности 🚀
Простейшее развертывание cnpg заключается в установке оператора и применении манифеста вида "Cluster". Да, в кластере Kubernetes мы будем разворачивать кластер Postgres. А потом в кластере Kubernetes развернем и кластер 1С. В этом канале будет еще много про
кластер x в кластере Kubernetes, привыкайте 😉Я дополнил лабу 03-kind-hello-world-1c инструкциями по разворачиванию cnpg.
Из интересного там:
26:26. Пришлось заглянуть в образ Егора, выяснить, что в нем эти значения равны 999:1000 (sic!) и переопределить их в манифесте, в полях spec.postgresUID, spec.postgresUID, а также указать spec.podSecurityContext.fsGroup: 999. Хорошо, что спецификация это позволяет, иначе пришлось бы пересобирать образ и устанавливать пресловутое 26:26 прямо в нем.Кстати, я не уверен, что образ Егора прокатит для cnpg. Документация cnpg говорит, что официально поддерживаются только их родные образы. Но сейчас кластер инициировался успешно 👀
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4❤1👍1
🪄 CoreDNS и systemd-resolved
Ух, пришлось сегодня изрядно помучиться и поломать голову насчет DNS.
В чем проблема?
Проблема в том, что центральный сервер 1С выдает клиенту адрес рабочего процесса в формате
Для этого я сделал 3 вещи:
1️⃣ прикинул, что в реестре кластера 1С все серверы должны быть зарегистрированы по имени службы, а не по имени хоста, иначе снаружи Kubernetes до них будет не достучаться
2️⃣ ночью чуть-чуть изменил гравитационное поле Земли добавил плагин k8s_external для CoreDNS в своем кластере Kubernetes, выставил сам CoreDNS наружу
3️⃣ настроил systemd-resolved на хосте так, чтобы запросы к зоне
Изи 🤓
Загвоздка тут в том, что серверы кластера 1С будут общаться друг с другом через этот же внешний IP-адрес балансировщика.
Что в этом плохого? Ну, во-первых, скорее всего будут лишние "хопы", соответственно, увеличатся задержки. Во-вторых, некоторые облачные провайдеры тарифицируют балансировщики не только по времени, но и по трафику.
Я думал, призывал на помощь ИИ и экспериментировал, но сделать так называемый Split-DNS в Kubernetes у меня пока не получилось. Split-DNS - это когда одно имя резволвится в один адрес при обращении к нему из одной сети, и в другой адрес при обращении из другой сети.
Однако, я обновил лабу 03-kind-hello-world-1c разделом с настройкой DNS как оно есть сейчас, а задачу по настройке Split-DNS отправил в бэклог.
Как же в тему сейчас этот стикер 👇
Ух, пришлось сегодня изрядно помучиться и поломать голову насчет DNS.
В чем проблема?
Проблема в том, что центральный сервер 1С выдает клиенту адрес рабочего процесса в формате
хост:порт. Чтобы начать работу в информационной базе, клиент должен установить TCP соединение с этим рабочим процессом. Я относительно легко смог сделать так, чтобы клиент, находящийся снаружи кластера Kubernetes, мог зарезолвить имя рабочего сервера в IP-адрес балансировщика. Для этого я сделал 3 вещи:
cluster.local шли на CoreDNS. Изи 🤓
Загвоздка тут в том, что серверы кластера 1С будут общаться друг с другом через этот же внешний IP-адрес балансировщика.
Что в этом плохого? Ну, во-первых, скорее всего будут лишние "хопы", соответственно, увеличатся задержки. Во-вторых, некоторые облачные провайдеры тарифицируют балансировщики не только по времени, но и по трафику.
Я думал, призывал на помощь ИИ и экспериментировал, но сделать так называемый Split-DNS в Kubernetes у меня пока не получилось. Split-DNS - это когда одно имя резволвится в один адрес при обращении к нему из одной сети, и в другой адрес при обращении из другой сети.
Однако, я обновил лабу 03-kind-hello-world-1c разделом с настройкой DNS как оно есть сейчас, а задачу по настройке Split-DNS отправил в бэклог.
Как же в тему сейчас этот стикер 👇
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3❤1👍1
🎉 TA-DAAAA!
Это самое долгожданное сообщение об ошибке лицензирования за всю мою карьеру 😅
В комментарии к этому посту еще выложу скринкаст с демонстрацией.
Помимо очевидного(отсутствия лицензии) , это сообщение означает, что сервер 1С размещен в Kubernetes так, что клиент не просто может подключиться к менеджеру кластера 1С извне, но еще и может установить соединение с рабочим процессом, который менеджер кластера выделил для него! 💪
Я сейчас перечитываю абзац выше и понимаю, что это звучит довольно просто. Но повозиться мне с этим пришлось знатно 😮💨
В следующих сериях:
📌 расскажу и покажу, как этого удалось достичь
📌 активирую коммюнити-лицензию, чтобы можно было работать с базой по-настоящему
Это самое долгожданное сообщение об ошибке лицензирования за всю мою карьеру 😅
В комментарии к этому посту еще выложу скринкаст с демонстрацией.
Помимо очевидного
Я сейчас перечитываю абзац выше и понимаю, что это звучит довольно просто. Но повозиться мне с этим пришлось знатно 😮💨
В следующих сериях:
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7❤1👍1
⚡️Подробности про установку 1С в кластер Kubernetes
Манифесты для серверов 1С у меня уже были подготовлены, поэтому после настройки DNS я просто применил их.
Два сервера 1С получили EXTERNAL-IP из того диапазона, который я ранее определил в
Для начала я попробовал создать информационную базу прямо с локальной машины, но столкнулся с тем, что СУБД должна быть с нее доступна 🤯. Я не публиковал ее наружу и не планировал, поэтому пришлось создавать базу изнутри контейнера.
Тут же обнаружилось несколько нюансов, связанных с cloudnative-pg: я взял 1С-совместимый образ, но совершенно забыл, что оператор cloudnative-pg переопределяет ENTRYPOINT. Это привело к двум проблемам:
1️⃣ стандартный пользователь тварью дрожащей учеткой без каких-либо привилегий и не может создавать БД
2️⃣ кластер Postgres инициализировался с локалью
Поэтому я почитал доку к cloudnative-pg(давно пора 😅) и немного дополнил манифест кластера Postgres в файле
Кстати, пароль от учётной записи
После всего этого база 1С создалась и я добавил ее в список баз на локальной машине, причем сервер 1С я указал как
❓Откуда
Дело в том, что менеджер кластера передает клиенту адрес рабочего процесса с тем именем сервера 1С, которое указано в реестре кластера. А какое имя указано в реестре кластера? Правильно - имя хоста, то есть пода, то есть
Я попробовал удалить кластер и создать его заново с помощью rac с правильным именем хоста, в моем случае это
Похоже, в платформе есть какая-то проверка на то, что создание кластера должно выполняться именно на localhost.
Как заставить систему думать, что некое имя ресурса это localhost? Самый простой способ - с помощью
А в шаблоне пода в StatefulSet для этого есть даже специальный параметр:
И это даже нельзя считать грязным хаком. Помните, в одном из прошлых постов я хотел, чтобы внутренний трафик ходил напрямую, а не через LoadBalancer? Короче, одним выстрелом двух зайцев, по крайней мере в рамках одного сервера 1С это будет работать. Получается, что Headless-сервисы пока мне не нужны.
Как обычно, дополнил и скорректировал лабу 03-kind-hello-world-1c.
Итогов года не будет, потому что канал я создал только в конце ноября. Но зато планы на 2026 год у меня большие! Перечислю несколько интересных задач:
🔸 активировать коммьюнити-лицензию на моем стенде
🔸 по-честному объединить несколько серверов 1С в кластер
🔸 добыть найти несколько серверных лицензий уровня КОРП для экспериментов
🔸 попробовать написать свой оператор для 1С (потихоньку уже изучаю go 😎)
🔸 проработать observability кластера: сбор метрик, ТЖ
Всех с наступающим!🎄
Спасибо, что следите за моим каналом!
Манифесты для серверов 1С у меня уже были подготовлены, поэтому после настройки DNS я просто применил их.
Два сервера 1С получили EXTERNAL-IP из того диапазона, который я ранее определил в
metallb.yaml, а имена соответствующих им LoadBalancer-ов успешно резолвились с моего хоста.Для начала я попробовал создать информационную базу прямо с локальной машины, но столкнулся с тем, что СУБД должна быть с нее доступна 🤯. Я не публиковал ее наружу и не планировал, поэтому пришлось создавать базу изнутри контейнера.
Тут же обнаружилось несколько нюансов, связанных с cloudnative-pg: я взял 1С-совместимый образ, но совершенно забыл, что оператор cloudnative-pg переопределяет ENTRYPOINT. Это привело к двум проблемам:
app по-умолчанию является en_EN.UTF-8 и с неправильным параметром --lc-collate=C, о чем платформа не постеснялась мне сообщить в консолиПоэтому я почитал доку к cloudnative-pg
cnpg.yaml.> ВАЖНО! Применение обновленного манифеста поверх имеющегося кластера вызовет его аварийную остановку. Поэтому лучше снести кластер и его PVC, а затем задеплоить по-новой.
Кстати, пароль от учётной записи
app задаётся в типичном для Kubernetes стиле - с использованием секретов (Secrets).После всего этого база 1С создалась и я добавил ее в список баз на локальной машине, причем сервер 1С я указал как
server1c-01-lb.default.cluster.local. Но при запуске в режиме конфигуратора меня ждала подстава в виде ошибки:Временный сбой в разрешении имен: server1c-01-0 и тд и тп
❓Откуда
server1c-01-0?Дело в том, что менеджер кластера передает клиенту адрес рабочего процесса с тем именем сервера 1С, которое указано в реестре кластера. А какое имя указано в реестре кластера? Правильно - имя хоста, то есть пода, то есть
server1c-01-0. А моя локальная машина ничего не знает об именах подов в Kubernetes, да и не должна знать. Выходит, нужно сделать так, чтобы платформа возвращала имя сервиса с типом LoadBalancer.Я попробовал удалить кластер и создать его заново с помощью rac с правильным именем хоста, в моем случае это
server1c-01-lb.default.cluster.local. Но rac выдал ошибку:Ошибка операции администрирования
Local host parameters are not found
command terminated with exit code 255
Похоже, в платформе есть какая-то проверка на то, что создание кластера должно выполняться именно на localhost.
Как заставить систему думать, что некое имя ресурса это localhost? Самый простой способ - с помощью
/etc/hosts!А в шаблоне пода в StatefulSet для этого есть даже специальный параметр:
...
spec:
hostAliases:
- ip: "127.0.0.1"
hostnames:
- "server1c-02-lb.default.cluster.local"
...
И это даже нельзя считать грязным хаком. Помните, в одном из прошлых постов я хотел, чтобы внутренний трафик ходил напрямую, а не через LoadBalancer? Короче, одним выстрелом двух зайцев, по крайней мере в рамках одного сервера 1С это будет работать. Получается, что Headless-сервисы пока мне не нужны.
Как обычно, дополнил и скорректировал лабу 03-kind-hello-world-1c.
Итогов года не будет, потому что канал я создал только в конце ноября. Но зато планы на 2026 год у меня большие! Перечислю несколько интересных задач:
Всех с наступающим!
Спасибо, что следите за моим каналом!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍2❤1
По многочисленным 😅 просьбам комментаторов в предыдущем посте, напишу, что у меня было самого интересного в 2025 году в профессиональном плане:
🔸 с начала года я стал членом программного комитета конференции по 1С от Онтико. Онтико организуют HighLoad++ и кучу других топовых не 1С-ных конференций. Конференция по 1С пока не состоялась, но опыт был интересный.
🔸 в марте выступил в Клубе Питерских Одинэсников с докладом про веб-сервисы и автономный сервер, запись вот тут.
🔸 весь год тащил на основной работе два проекта: первый - это перевод двух больших самописных конфигураций на Linux и Postgres, второй - разработка универсального CI/CD для 1С на базе GitLab. Плюс к этому была куча других задач по производительности и стабильности, ну и пресейлы, куда уж без них.
🔸 стал мейнтейнером одного из самых популярных проектов на OneScript - gitsync, заодно и gitsync-plugins. Перевел тестирование на Github Actions, исправил баги и выпустил по новому релизу и там, и там.
🔸 сдал экзамен "1С:Эксперт по технологическим вопросам"! Сертификат оказался с "выдержкой", ведь первая попытка сдачи была аж в 2015 году! 😳
🔸 в ходе подготовки к Эксперту наконец-то проникся ведением базы знаний в Obsidian. Без нее сдать экзамен было бы в разы сложнее! Теперь использую его для других задач, в том числе на своих проектах.
🔸 создал канал cloudnative-1c 🎉
🔸 дотянул до релиза свой очень старый PR в bsl-language-server.
🔸 прямо под елочку, 26 декабря, стал Decorated Certified DevOps Engineer по продукту VK Tax Compliance. Этот продукт состоит из 50+ микросервисов и разворачивается в кубере с помощью Terraform и ArgoCD.
Спасибо всем, с кем довелось поработать в 2025 году! Увидимся в 2026-ом! 💪
Спасибо всем, с кем довелось поработать в 2025 году! Увидимся в 2026-ом! 💪
Please open Telegram to view this post
VIEW IN TELEGRAM
1🎉7👍4❤3🤩1
Потихоньку вливаемся в рабочий режим!
На каникулах мне пришлось организовать переезд моей лаборатории. Я арендовал сервер на hostkey, все развернул по-новой и дошел до активации лицензии. Кстати, я шел по своим же шагам из лабораторных, поэтому заодно проверил их воспроизводимость.
Как водится, с активацией комьюнити-лицензий 1С не все просто. Загвоздка в том, что эта лицензия активируется строго интерактивно. Причем, если нужно активировать ее для сервера, то это надо делать на самом сервере, то есть, прямо в поде.
🤓 Вообще, правильно говорить не "в поде", а "в контейнере", но в моем случае без разницы, потому что в моем поде строго один контейнер.
Получается такой набор действий:
После активации комьюнити-лицензии в поде должен появиться файл
/var/1C/licenses/202601*.lic. Эта лицензия позволяет работать серверу 1С и еще четырем сеансам.Кстати, количество комьюнити-лицензий на один аккаунт ограничено, поэтому заодно я расширил спецификацию кластера 1С объектами
Persistent Volume и Persistent Volume Claim. Без них любое пересоздание пода приводило бы к потере файла с лицензией. А нам такое не надо.Мой коллега Олег подсказал мне пару ссылок на ИТС с документацией по фрешу, где есть почти все нужные команды для установки GUI + VNC.
Единственное, что ставить systemd в моем поде - это очень-очень большой overkill, поэтому запускать графический интерфейс и VNC я буду вручную.
Как водится, я обновил лабу 03-kind-hello-world-1c. Офигеть, какой развесистый hello-world получается!
Что получилось в итоге:
Почему? Там довольно интересная ситуация, мне пришлось даже пообщаться с поддержкой 1С. Обходной путь я нашел, но надеюсь, что у меня получится разобраться с этой проблемой как полагается. Об этом расскажу в следующих постах! 😅
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍5🙏3
Продолжаю переписываться с поддержкой 1С по поводу того, что сервер не выдает клиенту комьюнити-лицензию, если клиент расположен на другой машине. Выясняю все методично и дотошно, спасибо им большое за терпение 🙏
А сегодня с утра в рассылке OpenYellow обнаружил занятный проект onec-community-docker. В нем максимально автоматизировано получение и продление комьюнити-лицензий на сервере и на клиенте 1С внутри докер-контейнеров.
Связался с автором. Оказалось, что Александр вообще только осваивает разработку в 1С и сделал этот проект для погружения в предметную область. Мое почтение! 💪 Накидайте ему, пожалуйста,звездюлей звезд на гитхабе!
Конечно, я сразу захотел портировать эти наработки в onec-docker.
Александр мне скинул ссылки на публикации и обсуждения на Infostart, где утверждается, что сервер 1С с активированной комьюнити-лицензией не раздает эти лицензии клиентам, даже если флажок "Разрешать выдачу лицензий сервером 1С:Предприятия" установлен (см. также
Обидно. Досадно. Ноладно ничего не поделаешь: придется активировать две лицензии - одну на сервере, одну на клиенте.
Кстати, это тот самый "способ обхода", про который я говорил в прошлом посте. Получается, что никакой это не обход, а штатное поведение.
А теперь про другой интересный нюанс. Когда моя лаборатория переехала на новый абсолютно чистый VPS-сервер, то при подключении с этого хоста к серверу 1С в поде Kubernetes я внезапно стал получать такую ошибку:
WTF???
Оказалось, что с этого сервера мне стали доступны чьи-то чужие клиентские лицензии, аж 300 штук. Клиент 1С использовал их, а потом выдавал ошибку, потому что комьюнити-лицензии нельзя смешивать с обычными лицензиями (кроме строго одного случая).
Кстати, поддержка 1C сообщила, что до 8.3.24 это ограничение было только на бумаге, а в последующих версиях оно уже реализовано на уровне платформы.
А проблема решилась запретом на использование аппаратных лицензий.
Такие дела!
В следующий раз буду ручками собирать настоящий кластер 1С из двух серверов. Ожидаю, что после этого будет более-менее понятно, что должен уметь делать minimum viable оператор для 1С и какими ресурсами он должен управлять. О том, что такое операторы в Kubernetes я писал тут.
🏆 Мини-викторина: в каком случае разрешено совместное использование обычных лицензий и комьюнити-лицензий?
Пишите ваши варианты в комментариях, победителю поставлю красивую звездочку⭐️
Только чур никуда не подглядывать!
А сегодня с утра в рассылке OpenYellow обнаружил занятный проект onec-community-docker. В нем максимально автоматизировано получение и продление комьюнити-лицензий на сервере и на клиенте 1С внутри докер-контейнеров.
Связался с автором. Оказалось, что Александр вообще только осваивает разработку в 1С и сделал этот проект для погружения в предметную область. Мое почтение! 💪 Накидайте ему, пожалуйста,
Конечно, я сразу захотел портировать эти наработки в onec-docker.
Александр мне скинул ссылки на публикации и обсуждения на Infostart, где утверждается, что сервер 1С с активированной комьюнити-лицензией не раздает эти лицензии клиентам, даже если флажок "Разрешать выдачу лицензий сервером 1С:Предприятия" установлен (см. также
--license-distribution=allow).Обидно. Досадно. Но
Кстати, это тот самый "способ обхода", про который я говорил в прошлом посте. Получается, что никакой это не обход, а штатное поведение.
А теперь про другой интересный нюанс. Когда моя лаборатория переехала на новый абсолютно чистый VPS-сервер, то при подключении с этого хоста к серверу 1С в поде Kubernetes я внезапно стал получать такую ошибку:
Сервер 1С:Предприятия использует лицензию для разработчиков. Запуск клиентского приложения Конфигуратор с лицензией ПРОФ и КОРП запрещен. Обратитесь ...
WTF???
Оказалось, что с этого сервера мне стали доступны чьи-то чужие клиентские лицензии, аж 300 штук. Клиент 1С использовал их, а потом выдавал ошибку, потому что комьюнити-лицензии нельзя смешивать с обычными лицензиями (кроме строго одного случая).
Кстати, поддержка 1C сообщила, что до 8.3.24 это ограничение было только на бумаге, а в последующих версиях оно уже реализовано на уровне платформы.
А проблема решилась запретом на использование аппаратных лицензий.
Такие дела!
В следующий раз буду ручками собирать настоящий кластер 1С из двух серверов. Ожидаю, что после этого будет более-менее понятно, что должен уметь делать minimum viable оператор для 1С и какими ресурсами он должен управлять. О том, что такое операторы в Kubernetes я писал тут.
🏆 Мини-викторина: в каком случае разрешено совместное использование обычных лицензий и комьюнити-лицензий?
Пишите ваши варианты в комментариях, победителю поставлю красивую звездочку
Только чур никуда не подглядывать!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍7❤4🙏1
Вчера произошло столкновение моего стенда с чугунной жопой реальности 😁
Ничего особо страшного не случилось, просто после перезагрузки моего сервера все поды создались заново, а сохраненная конфигурация кластера 1С сбросилась в дефолт. Почему? А потому, что надо было не лениться и сразу создать volume для каталога кластера, также, как я это сделал для лицензий.
Но я не расстраиваюсь, потому что все равно хотел рассказать о хранении данных в Kubernetes подробнее. Теперь же для этого появился повод!
Итак, если поду нужно работать с файловой системой, то в его спецификации можно указать volumes и\или volumeMounts.
Типов volumes много, но они делятся на две больших группы: эфемерные (ephemeral) и постоянные (persistent). Эфемерные я сегодня не рассматриваю, потому что они удаляются сразу после перезапуска контейнера или после удаления пода (подов).
Кстати, можно сделать так, чтобы разные контейнерам внутри одного пода или вообще разные поды могли работать с одним и тем же volume совместно.
В Kubernetes есть статическая и динамическая модель организации хранения данных. Я опишу динамическую модель, потому что она удобнее и используется чаще всего.
Дано: на узлах кластера Kubernetes или где-то рядом с ними есть "диски" разных типов, например, HDD, SSD, iSCSI, и прочие.
Администратор создает в кластере объекты типа StorageClass. Например, под быстрые ssd-диски он создаст класс с именем
Разработчик приложения в спецификации своего StatefulSet перечисляет volumeClaimTemplates (некие шаблоны). Каждый из шаблонов определяет, какой объем из какого хранилища нужно выделить каждому поду. Например, нужно 1 ГБ на быстрых дисках и еще 500 МБ на медленных дисках. А в спецификации пода он указывает, по какому пути монтировать какое хранилище:
Когда Kubernetes будет планировать размещение пода из этого StatefulSet, то возможны два варианта:
1️⃣ в контейнер будет смонтирован созданный ранее volume (упрощенно)
2️⃣ кластер создаст новый PersistentVolume с указанными параметрами и монтирует его в файловую систему контейнера
Как кластер понимает, что PersistentVolume относится к конкретному поду?
Он понимает это с помощью уникальных имен подов в StatefulSet и с помощью объекта под названием PersistentVolumeClaim.
Стоп. А что такое PersistentVolumeClaim?
Объясню простыми словами: PersistentVolume - это ресурс, а PersistentVolumeClaim - заявка на выделение ресурса. В динамической модели PersistentVolume формируются кластером автоматически по "заявкам" в виде PersistentVolumeClaim.
В случае StatefulSet, в котором перечислены volumeClaimTemplates, жизненный цикл PersistentVolumeClaim не зависит от жизненного цикла пода: при удалении пода PersistentVolumeClaim остается, а раз есть PersistentVolumeClaim, то и volume удален не будет.
В статической модели администратор создает PersistentVolume заранее.
Это был супер-краткий экскурс в Kubernetes Storage #k8s_101 🎓
Манифесты в README в 03-kind-hello-world-1c обновлены.
Дополнительно указал:
🟡 как работать с кластером 1С в Kubernetes с локальной машины, если на нее установлен rac (спасибо @nixel2007, что обратил на это мое внимание)
🟡 как сделать так, чтобы настройки DNS на локальной машине переживали перезагрузку
В следующей серии наглядно покажу, как кластер 1С умеет переживать удаление пода. Он буквально возрождается из пепла, как феникс 🔥
Ничего особо страшного не случилось, просто после перезагрузки моего сервера все поды создались заново, а сохраненная конфигурация кластера 1С сбросилась в дефолт. Почему? А потому, что надо было не лениться и сразу создать volume для каталога кластера, также, как я это сделал для лицензий.
Но я не расстраиваюсь, потому что все равно хотел рассказать о хранении данных в Kubernetes подробнее. Теперь же для этого появился повод!
Итак, если поду нужно работать с файловой системой, то в его спецификации можно указать volumes и\или volumeMounts.
Типов volumes много, но они делятся на две больших группы: эфемерные (ephemeral) и постоянные (persistent). Эфемерные я сегодня не рассматриваю, потому что они удаляются сразу после перезапуска контейнера или после удаления пода (подов).
Кстати, можно сделать так, чтобы разные контейнерам внутри одного пода или вообще разные поды могли работать с одним и тем же volume совместно.
В Kubernetes есть статическая и динамическая модель организации хранения данных. Я опишу динамическую модель, потому что она удобнее и используется чаще всего.
Дано: на узлах кластера Kubernetes или где-то рядом с ними есть "диски" разных типов, например, HDD, SSD, iSCSI, и прочие.
Администратор создает в кластере объекты типа StorageClass. Например, под быстрые ssd-диски он создаст класс с именем
freaking-fast-ssd, а под hdd - horrifically-slow-hddРазработчик приложения в спецификации своего StatefulSet перечисляет volumeClaimTemplates (некие шаблоны). Каждый из шаблонов определяет, какой объем из какого хранилища нужно выделить каждому поду. Например, нужно 1 ГБ на быстрых дисках и еще 500 МБ на медленных дисках. А в спецификации пода он указывает, по какому пути монтировать какое хранилище:
...
kind: StatefulSet
...
spec:
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: freaking-fast-ssd
resources:
requests:
storage: 1Gi
- metadata:
name: logs
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: horrifically-slow-hdd
resources:
requests:
storage: 500Mi
template:
spec:
containers:
- name: app01
volumeMounts:
- name: data # имя совпадает с volumeClaimTemplate
mountPath: /opt/my-app/data
- name: logs # имя совпадает с volumeClaimTemplate
mountPath: /var/log/my-app
Когда Kubernetes будет планировать размещение пода из этого StatefulSet, то возможны два варианта:
Как кластер понимает, что PersistentVolume относится к конкретному поду?
Он понимает это с помощью уникальных имен подов в StatefulSet и с помощью объекта под названием PersistentVolumeClaim.
Стоп. А что такое PersistentVolumeClaim?
Объясню простыми словами: PersistentVolume - это ресурс, а PersistentVolumeClaim - заявка на выделение ресурса. В динамической модели PersistentVolume формируются кластером автоматически по "заявкам" в виде PersistentVolumeClaim.
В случае StatefulSet, в котором перечислены volumeClaimTemplates, жизненный цикл PersistentVolumeClaim не зависит от жизненного цикла пода: при удалении пода PersistentVolumeClaim остается, а раз есть PersistentVolumeClaim, то и volume удален не будет.
В статической модели администратор создает PersistentVolume заранее.
Это был супер-краткий экскурс в Kubernetes Storage #k8s_101 🎓
Манифесты в README в 03-kind-hello-world-1c обновлены.
Дополнительно указал:
В следующей серии наглядно покажу, как кластер 1С умеет переживать удаление пода. Он буквально возрождается из пепла, как феникс 🔥
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍5❤4
