Настройка 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 и открыть на редактирование

Выбор модуля btk

В открывшемся окне выбрать «Настройки для Quartz» и нажать на кнопку с тремя точками

Выбор "Настройки для 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 по умолчанию)

Пример конфигурации:

Пример конфигурации Quartz

По завершению конфигурации нажать зеленую стрелку, а затем операцию «Сохранить» в окне с настройками модуля 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 ключи из одной пары, либо сгенерируйте новую пару ключей (Генерация ключей шифрования)