Настройка GlobalScheduler
Contents
Настройка GlobalScheduler#
Генерация ключей шифрования#
Генерация ключей в системе Global#
Генерацию ключей можно выполнить с помощью системы Global.
Для этого в приложении «Настройки системы» необходимо открыть меню Настройки и сервисы | Менеджер заданий
В открывшемся окне выполнить операцию «Сгенерировать открытый и закрытый ключ»
В результате выполнения операции на компьютер пользователя будут скачаны два файла: quartz.publickey.txt (открытый ключ) и quartz.privatekey.txt (закрытый ключ).
Генерация ключей сторонними утилитами#
Допускается генерация ключей допускается сторонними утилитами.
Внимание
Открытый ключ, как и закрытый, должен содержать в себе только массив байт, созданный по алгоритму RSA
, с размером 2048 бит, и закодированный в Base64
.
Пример создания ключей с помощью криптографической библиотеки OpenSSL:
# Генерация приватного ключа в стандартном формате
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048; \
# Генерация публичного ключа в стандартном формате
openssl rsa -in private.pem -outform PEM -pubout -out public.pem; \
# Форматирование ключей для работы с Global
sed '/-----.*-----/d' ./private.pem | tr -d '\n' > quartz.private.pem; \
sed '/-----.*-----/d' ./public.pem | tr -d '\n' > quartz.public.pem; \
# Конвертация ключа в base64 для использования в секрете kubernetes (не требуется при использовании Global в автономном режиме)
base64 -w 0 ./quartz.private.pem > ./b64.private.pem
Убедиться, что сгенерированный вами ключ был создан в подходящем для Globalscheduler формате можно при помощи следующей команды:
base64 -d ./quartz.private.pem | openssl asn1parse -inform DER | grep -q rsaEncryption && echo "Ключ верного формата" || echo "Ключ неподходящего формата"
Конфигурация GlobalScheduler и установка приватного ключа#
Автономный режим#
Настройка конфигурационных файлов#
Расположение основного файла конфигурации: /opt/global/globalserver/application/config/tools/scheduler/quartz.properties
Создайте файл конфигурации планировщика
sudo mkdir -p /opt/global/globalserver/application/config/tools/scheduler
sudo touch /opt/global/globalserver/application/config/tools/scheduler/quartz.properties
Вставьте содержимое
org.quartz.scheduler.instanceName = PostgresScheduler
org.quartz.scheduler.instanceId = AUTO
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 500
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.dataSource = quartzDS
org.quartz.jobStore.dontSetAutoCommitFalse=false
org.quartz.dataSource.quartzDS.driver = org.postgresql.Driver
org.quartz.dataSource.quartzDS.URL = jdbc:postgresql://<DBHOST>:5432/<DBNAME>?ApplicationName=Global-Scheduler
org.quartz.dataSource.quartzDS.user = <DBUSER>
org.quartz.dataSource.quartzDS.password = <DBPASS>
org.quartz.jobStore.tablePrefix=btk_qrtz_
org.terracotta.quartz.skipUpdateCheck=true
Где
<DBHOST> - адрес сервера postgres
<DBNAME> - имя БД
<DBUSER> - пользователь БД
<DBPASS> - пароль пользователя БД
Создайте файл конфигурации лога планировщика
sudo touch /opt/global/globalserver/application/config/tools/scheduler/logback.xml
Вставьте содержимое
<configuration>
<appender name="STDOUT_DEFAULT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>[%-5level] %d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %logger - %msg%n</pattern>
</encoder>
</appender>
<appender name="OUT_SSH" class="ru.bitec.engine.core.logging.SshConsoleAppender">
<encoder>
<!--<pattern>[%-5level] %d{HH:mm:ss.SSS} [%thread]:%X{USER} - %msg - %logger%n</pattern>-->
<pattern>[%-5level] %d{dd-MM-yyyy HH:mm:ss.SSS} - %msg</pattern>
</encoder>
</appender>
<appender name="FILEOUT" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${G3_HOME}\logs\global3.%d{yyyy-MM-dd_HH}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %logger - %msg%n</pattern>
</encoder>
</appender>
<!--
Возможные значения параметра "level" в порядке приоритета важности
OFF
ERROR
WARN
INFO
DEBUG
TRACE
ALL
-->
<root level="INFO">
<appender-ref ref="STDOUT_DEFAULT"/>
<appender-ref ref="OUT_SSH"/>
<appender-ref ref="FILEOUT"/>
</root>
<!-- Для логирования SQL вызовов переключите в режим INFO или ниже-->
<!-- Текущие значения не менять, тк: -->
<!-- Установка уровня логирования на сервере задается через фильтр в начале файла.-->
<!-- Установка уровня логирования на клиенте задается через общий файл конфигурации и\или выставляется клиентом.-->
<logger name="jdbc" level="off" additivity="false"/>
<!-- Выводит SQL-текст, значения IN\OUT параметров -->
<!--<logger name="jdbc.audit" level="info"/>-->
<!-- Выводит текст SQL - вызова.
Переведено в режим OFF, что бы не дублировать вывод SQL-текста-->
<logger name="jdbc.sqlonly" level="OFF"/>
<!-- Выводит текст SQL - вызова с временем выполнения.
Переведено в режим OFF, что бы не дублировать вывод SQL-текста -->
<logger name="jdbc.sqltiming" level="OFF"/>
<logger name="net.sf.log4jdbc" level="warn">
<appender-ref ref="STDOUT_DEFAULT"/>
</logger>
<!-- Sbt -->
<!-- info - общие сообщения о действиях менеджера-->
<!-- debug - "+" весь вывод SBT, обновляемые файлы-->
<!-- trace - "+" все события DirWatcher'a-->
<logger name="ru.bitec.engine.sbt" level="info"/>
<!--<logger name="ru.bitec.engine.session" level="trace"/>-->
<!--<logger name="ru.bitec.common.rpc" level="trace"/>-->
</configuration>
Настройка сервиса globalscheduler#
Для настройки сервиса нужно скопировать файл /opt/global/globalserver/admin/linux/scheduler/globalscheduler.service.origin
в каталог /lib/systemd/system
и переименовать globalscheduler.service
sudo cp /opt/global/globalserver/admin/linux/scheduler/globalscheduler.service.origin /lib/systemd/system/globalscheduler.service
или создать новый файл
sudo touch /usr/lib/systemd/system/globalscheduler.service
Содержимое
[Unit]
Description=Менеджер заданий Global SE Postgres
After=multi-user.target
[Service]
Type=idle
WorkingDirectory=/opt/global/globalserver
ExecStart=/opt/global/globalserver/globalscheduler.sh
TimeoutStopSec=110
[Install]
WantedBy=multi-user.target
Разрешите автозагрузку сервиса
sudo systemctl daemon-reload
sudo systemctl enable globalscheduler
Установка приватного ключа#
В основном файле конфигурации планировщика quartz.properties
требуется указать путь до файла с закрытым ключом шифрования (quartz.privatekey.txt/quartz.private.pem) в параметре
ru.bitec.jobscheduler.privatekey.path = /some/path/to/file
Пример конфигурации:
ru.bitec.jobscheduler.privatekey.path = /opt/global/globalserver/application/config/tools/scheduler/quartz.private.pem
Примечание
Если в пути до файла используются символ \ (обратный слеш), то его требуется экранировать вторым слешем. Пример пути:
ru.bitec.jobscheduler.privatekey.path=C:\\some\\path\\to\\file
Этот ключ будет использоваться для подписания токена авторизации для пользователя, который является исполнителем задачи планировщика.
Для применения конфигурации перезапустите сервис globalscheduler:
sudo systemctl restart globalscheduler.service
Kubernetes#
В случае, если вы сгенерировали ключи при помощи системы Global, необходимо дополнительно зашифровать закрытый ключ в base64. Для этого можно воспользоваться следующей командой, находясь в директории с ключом:
base64 -w 0 ./quartz.private.key > ./b64.private.pem
Создайте секрет с токеном планировщика, заменив значение namespace на название пространства имен Global, и значение шаблона <b64_key> на содержимое файла b64.private.pem
apiVersion: v1
kind: Secret
metadata:
name: scheduler-token-secret
namespace: gs-cluster-k8s
data:
private.key: <b64_key>
cat <<EOF | tee ~/nscli/workspace/scheduler-token-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: scheduler-token-secret
namespace: gs-cluster-k8s
data:
private.key: <b64_key>
EOF
kubectl apply -f ~/nscli/workspace/scheduler-token-secret.yaml
Установка публичного ключа и настроек Quartz#
Для указания открытого ключа для проверки токена авторизации планировщика заданий необходимо открыть приложение «Настройка системы».
Открыть меню: Настройки и сервисы > Настройки модулей системы > Общие настройки модулей
В списке выбрать модуль btk и открыть на редактирование
В открывшемся окне выбрать «Настройки для Quartz» и нажать на кнопку с тремя точками
В открывшемся окне задать следующие значения:
База данных: alias базы данных из файла global3.config.xml
HTTPS включён: в зависимости от того, используется ли https в Global, включить данную опцию
Логин: логин проьзователя scheduler в Global (scheduler по умолчанию)
Пароль: пароль пользователя scheduler в Global
Публичный ключ: открытый ключ (содержимое файла quartz.publickey.txt/quartz.public.pem)
Soap хост: домен/IP адрес, на котором доступен Global
Soap порт: порт, на котором доступен Global (8080 по умолчанию)
Пример конфигурации:
По завершению конфигурации нажать зеленую стрелку, а затем операцию «Сохранить» в окне с настройками модуля btk.
Частые проблемы#
algid parse error, not a sequence#
При запуске globalscheduler в логах может возникнуть ошибка следующего вида:
Job Default.22 threw a JobExecutionException: org.quartz.JobExecutionException: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
Чаще всего данная проблема связана с некорректным форматом приватного ключа. Для работы с Globalscheduler требуется 2048-битный ключ RSA формата PKCS#8. Ключи формата PKCS#1 не подходят для работы c Globalscheduler.
Чтобы убедиться, что ваш ключ верного формата, проверьте, что сгенерированный вами неотформатированный приватный ключ (quartz.privatekey.txt/quartz.private.pem) начинается со следующей строки:
-----BEGIN PRIVATE KEY-----
В случае, если ваш ключ неверного формата (PKCS#1), он будет начинаться со следующей строки:
-----BEGIN RSA PRIVATE KEY-----
Также проверить формат ключа можно при помощи openssl, что может быть полезно, если ключ доступен только в отформатированном для Globalscheduler виде (quartz.private.txt/quarz.private.pem), и не содержит заголовков
Для этого используйте следующую команду, заменив значение <key_path> на путь до приватного ключа:
base64 -d <key_path> | openssl asn1parse -inform DER | grep -q rsaEncryption && echo "Ключ верного формата" || echo "Ключ неподходящего формата"
Чтобы сгенерировать ключ подходящего формата, воспользуйтесь генерацией пары ключей в системе Global, или следующей командой:
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
Illegal base64 character#
В случае возникновения ошибки «Illegal base64 character» убедитесь, что ключи верно отформатированы. Ключи, используемые Globalscheduler, не должны содержать заголовков (—–BEGIN PUBLIC KEY—–, —–END PUBLIC KEY—– и пр.) и знаков переноса строки.
Если вы используете kubernetes, убедитесь, что в секрете используется ключ, дополнительно закодированный в base64 (b64.private.pem).
Для этого проверьте, что файл ~/globalserver/workspace/mnt/secret/scheduler/private.key внутри контейнера Globalscheduler содержит приватный ключ в читаемом формате.
Error 401 JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.#
Данная ошибка связана с тем, что установленный публичный ключ не подходит к установленному приватному ключу. Убедитесь, что установленные в Globalscheduler ключи из одной пары, либо сгенерируйте новую пару ключей (Генерация ключей шифрования)