Интерфейс системы развертывания клиентов
Определения
Среда клиента - совокупность docker-образа, сервиса k8s, записи обратного прокси сервера и двух баз clickhouse и postgres, необходимых для функционирования клиента в сервисе.
k8s - kubernetes - оркестратор развертывания сред клиентов
ingress - reverse-proxy сервер управляющий маршрутизацией запросов между экземплярами клиентских сред
Требования
- Система разрабатывается на базе платформы 1С
- Система должна хранить список клиентов:
- Идентификатор клиента формируется по шаблону C<Номер клиента>, например C42.
- Наименование организации клиента
- Контактные данные клиента:
- Контактные лица
- Номера телефонов
- Почтовые ящики
- Система взаимодействует с кластером k8s по rest-api(методы и шаблоны описаны ниже)
- Система должна хранить набор предопределенных шаблонов запросов, для взаимодействия с кластером k8s
- Шаблон запроса - текст в формате JSON с макросами, которые заменяются при исполнении запроса значениями определяющими среду клиента, например: идентификатор клиента, секретные ключи, образы docker и т.д. Все поля общие для каждого клиента указываются в шаблоне "как есть" в виде текста.
- Система должна хранить варианты настроек(справочники):
- Путь к образу сервиса
- Идентификатор пространства имен, в котором развертывается среда: [lms-dev, lms-prod]
- Корневой URL api кластера k8s
- Авторизационный токен для доступа к api кластера k8s
- Публичный адрес сервиса
- Секретный rsa-ключ среды клиента
- Система должна хранить набор переменных окружения для создания/обновления? среды клиента
- Система должна хранить системные параметры доступа для postgres и clickhouse
- Система должна предоставлять возможность создания нового клиента, в процессе которого выполняет запросы:
- Создание задания кластеру k8s на баз clickhouse и postgres
- Загрузка переменных окружения среды клиента в кластер k8s
- Загрузка секретов в кластер k8s
- Создание сервиса k8s и записи ingress
- Проверка статуса развертывания среды и вывод информации об успешности или не успешности развертывания
Доступ
- Доступ к api кластера k8s выполняется через rest-протокол. Корневой url: https://rancher.rarus.cloud/k8s/clusters/c-m4hlh/
- Сейчас доступна одно пространство имен lms-dev, но необходимо предусмотреть появление других в будущем
-
Доступ снаружи возможен только при условии добавления IP адреса с владельцами кластера. Соответственно, перед началом тестирования запросов нужно передать эту информацию ответственному со стороны ДОС.
Шаблоны запросов
Общие параметры
api-root-url | Корневой URL api кластера k8s | https://rancher.rarus.cloud/k8s/clusters/c-m4hlh/ |
namespace-id | Идентификатор пространства имен кластера | [ lms-dev, lms-prod ] |
client-id | Идентификатор среды клиента | Формируется системой по шаблону C<Номер среды> |
Ниже все значения параметров указаны для пространства имен lms-dev
Создание базы clickhouse
{
"apiVersion": "batch/v1",
"kind": "Job",
"metadata": {
"name": "clickhouse-setup-{{client-id}}",
"namespace": "{{namespace-id}}"
},
"spec": {
"template": {
"metadata": {
"labels": {
"job-name": "clickhouse-setup-{{client-id}}"
}
},
"spec": {
"containers": [
{
"args": [
"clickhouse-client --host $CLICKHOUSE_HOST --user $CLICKHOUSE_USER --password $CLICKHOUSE_PASSWORD --query \"CREATE DATABASE IF NOT EXISTS $USER_NAME;\"\nclickhouse-client --host $CLICKHOUSE_HOST --user $CLICKHOUSE_USER --password $CLICKHOUSE_PASSWORD --query \"CREATE USER IF NOT EXISTS $USER_NAME IDENTIFIED BY '$CH_PASSWORD';\"\nclickhouse-client --host $CLICKHOUSE_HOST --user $CLICKHOUSE_USER --password $CLICKHOUSE_PASSWORD --query \"GRANT ALL ON $USER_NAME.* TO $USER_NAME;\"\nclickhouse-client --host $CLICKHOUSE_HOST --user $CLICKHOUSE_USER --password $CLICKHOUSE_PASSWORD --query \"GRANT POSTGRES ON *.* TO $USER_NAME WITH GRANT OPTION;\"\nclickhouse-client --host $CLICKHOUSE_HOST --user $CLICKHOUSE_USER --password $CLICKHOUSE_PASSWORD --query \"GRANT CREATE TEMPORARY TABLE ON *.* TO $USER_NAME WITH GRANT OPTION;\"\n"
],
"command": [
"/bin/bash",
"-c"
],
"env": [
{
"name": "USER_NAME",
"value": "{{client-id}}"
},
{
"name": "CLICKHOUSE_PASSWORD",
"value": "{{clickhouse-admin-password}}"
},
{
"name": "CLICKHOUSE_USER",
"value": "{{clickhouse-admin-user}}"
},
{
"name": "CLICKHOUSE_HOST",
"value": "{{clickhouse-host}}"
},
{
"name": "CH_PASSWORD",
"value": "{{clickhouse-user-password}}"
}
],
"image": "yandex/clickhouse-client",
"imagePullPolicy": "Always",
"name": "clickhouse-setup"
}
],
"restartPolicy": "Never"
}
}
}
}
Параметры:
Имя параметра
|
Описание |
lms-dev
|
lms-prod |
clickhouse-host
|
Адрес сервера clickhouse |
10.66.139.55
|
|
clickhouse-admin-user
|
Администратор clickhouse | default | |
clickhouse-admin-password
|
Пароль администратора clickhouse |
ABWsBh+Q
|
|
clickhouse-user-password
|
Пароль пользователя базы клиента |
Генерируется системой
|
Создание базы postgres
Запрос : POST {{api-root-url}}/apis/batch/v1/namespaces/{{namespace-id}}/jobs
{
"apiVersion": "batch/v1",
"kind": "Job",
"metadata": {
"name": "postgres-setup-{{client-id}}",
"namespace": "{{namespace-id}}"
},
"spec": {
"template": {
"metadata": {
"labels": {
"job-name": "postgres-setup-{{client-id}}"
}
},
"spec": {
"containers": [
{
"args": [
"export PGPASSWORD=$PGPASSWORDADMIN\npsql -h $POSTGRES_HOST -U $POSTGRES_USER -c \"CREATE USER $USER_NAME WITH PASSWORD '\''$PG_PASSWORD'\'';\" || true\npsql -h $POSTGRES_HOST -U $POSTGRES_USER -c \"CREATE DATABASE $USER_NAME WITH OWNER $USER_NAME;\" || true\npsql -h $POSTGRES_HOST -U $POSTGRES_USER -c \"GRANT ALL PRIVILEGES ON DATABASE $USER_NAME TO $USER_NAME;\" || true\npsql -h $POSTGRES_HOST -U $POSTGRES_USER -c \"ALTER ROLE $USER_NAME SUPERUSER;\" || true\nexport PGPASSWORD=$PG_PASSWORD\npsql -h $POSTGRES_HOST -U $USER_NAME -c \"CREATE EXTENSION IF NOT EXISTS pgcrypto;\"\npsql -h $POSTGRES_HOST -U $USER_NAME -c \"CREATE EXTENSION IF NOT EXISTS \\\"uuid-ossp\\\";\"\nexport PGPASSWORD=$PGPASSWORDADMIN\npsql -h $POSTGRES_HOST -U $POSTGRES_USER -c \"ALTER ROLE $USER_NAME WITH NOSUPERUSER;\"\n"
],
"command": [
"/bin/bash",
"-c"
],
"env": [
{
"name": "PGPASSWORDADMIN",
"value": "{{postgres-admin-password}}"
},
{
"name": "USER_NAME",
"value": "{{client-id}}"
},
{
"name": "POSTGRES_USER",
"value": "{{postgres-admin-user}}"
},
{
"name": "POSTGRES_HOST",
"value": "{{postgres-host}}"
},
{
"name": "PG_PASSWORD",
"value": "{{postgres-user-password}}"
}
],
"image": "postgres:latest",
"imagePullPolicy": "Always",
"name": "postgres-client"
}
],
"restartPolicy": "Never"
}
}
}
}
Параметры:
Имя параметра
|
Описание |
lms-dev
|
lms-prod |
postgres-host
|
Адрес сервера postgres |
10.66.139.47
|
|
postgres-admin-user
|
Администратор postgres |
postgres
|
|
postgres-admin-password
|
Пароль администратора postgres |
8HgbfhiNFRstbC0NMtd
|
|
postgres-user-password
|
Пароль пользователя базы клиента |
Генерируется системой
|
Создание/изменение? конфигурации
Запрос : POST {{api-root-url}}/api/v1/namespaces/{{namespace-id}}/configmaps
{
"apiVersion": "v1",
"data": {
"LMS_CLIENT_ID": "{{client-id}}",
"LMS_SERVER_DEBUG": "true",
"LMS_SERVER_PORT": ":8080",
"LMS_SERVER_STATIC": "/mnt/image/static",
"LMS_KEYS_SECRET_SEED": "{{keys-secret-seed}}",
"LMS_KEYS_TOKEN_TTL_HOURS": "{{keys-token-ttl-hours}}",
"LMS_KEYS_PRIVATE_KEY_PATH": "{{keys-rsa-path}}"
"LMS_LOGS_DIRECTORY": "logs",
"LMS_LOGS_FILENAME": "log.log",
"LMS_LOGS_LOG_TO_FILE": "false",
"LMS_LOGS_MAX_AGE_DAY": "1",
"LMS_LOGS_MAX_BACKUPS": "3",
"LMS_LOGS_MAX_SIZE_MB": "1",
"LMS_NOTIFICATIONS_SMS4B_PASSCODE_LIFETIME": "{{sms4b-passcode-lifetime-seconds}}",
"LMS_NOTIFICATIONS_SMS4B_SENDER": "{{sms4b-sender}}",
"LMS_NOTIFICATIONS_SMS4B_TOKEN": "{{sms4b-token}}",
"LMS_STORAGE_CLICKHOUSE_DEMO": "internal/server/demodata/clickhouse",
"LMS_STORAGE_CLICKHOUSE_DSN": "clickhouse://{{client-id}}:{{clickhouse-user-password}}@{{clickhouse-host}}:9000/{{client-id}}",
"LMS_STORAGE_CLICKHOUSE_INTERVAL_MS": "100",
"LMS_STORAGE_CLICKHOUSE_MIGRATIONS": "file://internal/server/migrations/clickhouse",
"LMS_STORAGE_CLICKHOUSE_UPDATE_ATTEMPTS": "3",
"LMS_STORAGE_POSTGRES_DEMO": "internal/server/demodata/postgres",
"LMS_STORAGE_POSTGRES_DSN": "postgres://{{client-id}}:{{postgres-user-password}}@{{postgres-host}}:5432/{{client-id}}?sslmode=disable",
"LMS_STORAGE_POSTGRES_INTERVAL_MS": "100",
"LMS_STORAGE_POSTGRES_MIGRATIONS": "file://internal/server/migrations/postgres",
"LMS_STORAGE_POSTGRES_UPDATE_ATTEMPTS": "3"
},
"kind": "ConfigMap",
"metadata": {
"name": "lms-config-{{client-id}}",
"namespace": "{{namespace-id}}"
}
}
Параметры:
Имя параметра
|
Описание |
lms-dev
|
lms-prod |
keys-secret-seed
|
Ключ для формирования подписи токенов авторизации. Геренируется системой как 64-байтная последовательность записанная в шестнадцатиричной системе | Генерируется для каждого клиента | Генерируется для каждого клиента |
keys-token-ttl-hours
|
Время жизни токена доступа пользователя | 8 часов | 8 часов |
sms4b-passcode-lifetime-seconds
|
Время жизни временного кода подтверждения телефона клиента | 120 | Зависит от пожеланий клиента |
sms4b-sender
|
Отправитель сервисных смс-сообщений | 1C-RARUS | ? |
sms4b-token
|
Токен доступа к api sms4b | В личном кабинете sms4b | В личном кабинете sms4b |
keys-rsa-path
|
Путь к файлу закрытого ключа среды клиента |
/etc/lms/rsa_key
|
/etc/lms/rsa_key
|
Создание закрытого ключа среды клиента
Запрос : POST {{api-root-url}}/api/v1/namespaces/{{namespace-id}}/secrets
{
"apiVersion": "v1",
"data": {
"rsa_key": "{{rsa-content}}"
},
"kind": "Secret",
"metadata": {
"name": "rsa-secret-{{client-id}}",
"namespace": "{{namespace-id}}"
},
"type": "Opaque"
}
Параметры:
Имя параметра
|
Описание |
lms-dev
|
lms-prod |
rsa-content
|
2048-байтный rsa-ключ в кодировке base64 | Генерируется для каждого клиента |
Генерируется для каждого клиента |
Создание сервиса
Запрос : POST {{api-root-url}}/api/v1/namespaces/{{namespace-id}}/services
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "lms-service-{{client-id}}",
"namespace": "{{namespace-id}}"
},
"spec": {
"ports": [
{
"port": 8080,
"protocol": "TCP",
"targetPort": 8080
}
],
"selector": {
"app": "{{client-id}}-lms"
},
"type": "ClusterIP"
}
}
Создание записи ingress
Запрос : POST {{api-root-url}}/apis/networking.k8s.io/v1/namespaces/{{namespace-id}}/ingresses
{
"apiVersion": "networking.k8s.io/v1",
"kind": "Ingress",
"metadata": {
"annotations": {
"nginx.ingress.kubernetes.io/configuration-snippet": "add_header '\''Access-Control-Allow-Methods'\'' '\''GET, PUT, POST, OPTIONS, DELETE'\'';\nadd_header '\''Access-Control-Allow-Headers'\'' '\''DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'\'';\nadd_header '\''Access-Control-Expose-Headers'\'' '\''Content-Length,Content-Range'\'';",
"nginx.ingress.kubernetes.io/enable-cors": "true",
"nginx.ingress.kubernetes.io/rewrite-target": "/$1"
},
"name": "client-lms-ingress-{{client-id}}",
"namespace": "{{namespace-id}}"
},
"spec": {
"rules": [
{
"host": "{{public-dns}}",
"http": {
"paths": [
{
"backend": {
"service": {
"name": "lms-service-{{client-id}}",
"port": {
"number": 8080
}
}
},
"path": "/{{client-id}}/(.*)",
"pathType": "Prefix"
}
]
}
}
],
"tls": [
{
"hosts": [
"{{public-dns}}"
],
"secretName": "tls"
}
]
}
}
Параметры:
Имя параметра
|
Описание |
lms-dev
|
lms-prod |
public-dns
|
Публичное имя сервиса |
backend.lms-dev.rarus-cloud.ru
|
? |
Создание развертывания
Запрос : POST {{api-root-url}}/apis/apps/v1/namespaces/{{namespace-id}}/deployments
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"labels": {
"app": "{{client-id}}-lms"
},
"name": "lms-deployment-{{client-id}}",
"namespace": "{{namespace-id}}"
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"app": "{{client-id}}-lms"
}
},
"strategy": {
"rollingUpdate": {
"maxSurge": 1,
"maxUnavailable": 1
},
"type": "RollingUpdate"
},
"template": {
"metadata": {
"labels": {
"app": "{{client-id}}-lms"
}
},
"spec": {
"affinity": {
"nodeAffinity": {
"requiredDuringSchedulingIgnoredDuringExecution": {
"nodeSelectorTerms": [
{
"matchExpressions": [
{
"key": "rarus",
"operator": "In",
"values": [
"lms"
],
"containers": [
{
"envFrom": [
{
"configMapRef": {
"name": "lms-config-{{client-id}}"
}
}
],
"image": "{{docker-image}}",
"imagePullPolicy": "Always",
"name": "{{client-id}}",
"ports": [
{
"containerPort": 8080,
"name": "8080tcp",
"protocol": "TCP"
}
],
"volumeMounts": [
{
"mountPath": "/etc/lms",
"name": "key"
},
{
"mountPath": "/mnt/image/static",
"name": "data",
"subPath": "{{client-id}}"
}
]
}
],
"imagePullSecrets": [
{
"name": "repository-token"
}
],
"restartPolicy": "Always",
"volumes": [
{
"name": "data",
"nfs": {
"path": "/mnt/nfs",
"server": "{{nfs-server}}"
}
},
{
"name": "key",
"secret": {
"defaultMode": 511,
"secretName": "rsa-secret-{{client-id}}"
}
}
]
}
}
}
}
Параметры:
Имя параметра
|
Описание |
lms-dev
|
lms-prod |
docker-image
|
docker-образ, из которого будут разворачиваться новые среды клиентов |
registry.gitlab.corp.rarus.cloud/rarus-lms/backend:dev
|
? |
nfs-server
|
Сервер сетевой файловой системы |
10.66.139.73
|
? |
Мониторинг pod-а
Запрос : GET {{api-root-url}}/api/v1/namespaces/{{namespace-id}}/pods?labelSelector=app={{client-id}}-lms
В зависимости от статуса в ответе будет структура state, по которой нужно анализировать статус pod-а
No Comments