name: mariadb service_id: 115 service_display_name: Mariadb service_short_name: mariadb service_man: '# Инструкция по развертыванию MariaDB через платформу

## 1. Общая информация

MariaDB — реляционная база данных, совместимая с MySQL. Разворачивается через `mariadb-operator` в Kubernetes.

### Доступные операции с кластером

* **create** — создание кластера
* **delete** — удаление кластера
* **suspend** — остановка кластера (под реально останавливается, ресурсы не потребляются)
* **resume** — запуск ранее остановленного кластера
* **modify** — изменение параметров кластера
* **reconcile** — синхронизация состояния инстанса с платформой

### Доступные операции с базами данных

* **create_database** — создание базы данных
* **delete_database** — удаление базы данных

### Доступные операции с пользователями

* **create_user** — создание пользователя
* **delete_user** — удаление пользователя

---

## 2. Параметры создания кластера

### Платформа для развертывания (`startupConfiguration.resourceRealm`)

Среда, в которой будет развёрнут кластер.

### Конфигурация ресурсов (`clusterConfiguration`)

JSON-объект:
* `cpu` — квота CPU пода в миликорах (1000 = 1 vCPU). Пример: `500`
* `memory` — квота памяти пода в мегабайтах. Пример: `512`
* `disk` — размер диска в гигабайтах. Пример: `10`
* `replicas` — количество реплик. Сервис работает в режиме одного primary-узла (Galera выключена), значение `0` эквивалентно остановке кластера.

### Версия MariaDB (`mariadbConfiguration.version`)

Поддерживаются только две версии: `8.4.0` и `9.4.0`.

### Внешний доступ (`accessConfiguration`)

JSON-объект:
* `masterIpSpace` — имя ipSpace для выделения внешнего IP. Укажите `no-needed`, если внешний адрес не требуется.
* `masterAccessList` — список IP/подсетей, которым разрешён доступ к порту 3306 снаружи. Пустой список — доступ не ограничен на уровне firewall (в рамках выделенного ipSpace).

### Резервное копирование (`backupConfiguration`)

JSON-объект:
* `s3Uid` — идентификатор S3-пользователя/квоты для бэкапов.
* `schedule` — cron-выражение расписания бэкапов. По умолчанию `0 0 * * *` (раз в сутки в полночь).
* `retain` — время хранения бэкапов **в часах** (не в днях!). По умолчанию `7` — то есть 7 часов. При суточном расписании этого значения обычно недостаточно, чтобы между двумя бэкапами всегда оставалась хотя бы одна валидная копия — рекомендуется указывать `retain` явно, с запасом (например `720` = 30 суток).

> **Важно:** расписание и срок хранения бэкапов задаются **только при создании кластера**. Оператор MariaDB не позволяет изменить cron-расписание бэкапа после создания (поле `spec.schedule.cron` неизменяемо на уровне admission-вебхука самого оператора) — поэтому эти параметры недоступны для изменения через `modify`.

> **Восстановление из бэкапа пока не реализовано как самостоятельная операция платформы.** Бэкапы физически хранятся в S3-бакете инстанса (`technicals3backup-`, префикс `mariadb/backups/`). Если нужно восстановить данные из бэкапа — бэкап нужно **скачать из S3 и применить к базе вручную** (например через `mariabackup`/`mariadb-backup` restore или соответствующий инструмент).

### Автомасштабирование диска (`autoscaleConfiguration`)

JSON-объект:
* `enabled` — включить автоматическое расширение диска при исчерпании места.
* `quota` — максимальный размер диска, до которого разрешено автоматическое расширение (не может быть меньше `clusterConfiguration.disk`).
* `percent`, `schedule` — параметры триггера автомасштабирования.

---

## 3. Параметры модификации кластера

Все параметры модификации, кроме версии, можно как увеличивать, так и уменьшать (кроме диска — см. ниже) — система подставит текущие сохранённые значения, если их не менять.

### Конфигурация ресурсов (`clusterConfiguration`)

* `cpu`, `memory` — можно менять в любую сторону.
* `disk` — можно **только увеличивать**, уменьшение уже выделенного размера не поддерживается.
* `replicas` — `0` останавливает кластер тем же образом, что и `suspend` (альтернативный способ временной остановки через `modify`).

### Версия MariaDB (`mariadbConfiguration.version`)

Можно только повышать версию (`8.4.0 → 9.4.0`). Попытка понизить версию будет отклонена с явной ошибкой ещё до применения изменений.

### Внешний доступ (`accessConfiguration`)

Можно включить внешний доступ (было `no-needed` → указали реальный `masterIpSpace`), изменить список разрешённых IP, либо полностью отключить внешний доступ (`masterIpSpace: no-needed`) — в этом случае внешний Service, DNS-запись и правило firewall будут корректно откреплены и удалены.

### Резервное копирование

Не передаётся при модификации — расписание и срок хранения бэкапов фиксируются на этапе `create` (см. п.2).

---

## 4. Параметры создания базы данных (`create_database`)

### Имя базы данных (`dbName`)

Строка с именем новой базы. Не может совпадать с зарезервированными системными именами: `mysql`, `sys`, `information_schema`, `performance_schema`. База с таким же именем не должна уже существовать в кластере.

---

## 5. Параметры удаления базы данных (`delete_database`)

### Имя базы данных (`dbName`)

База должна существовать в кластере. Удаление будет отклонено, если к базе всё ещё привязаны пользователи — сначала нужно снять доступ (`delete_user`) у всех пользователей, ссылающихся на эту базу.

---

## 6. Параметры создания пользователя (`create_user`)

### Имя пользователя (`username`)

Не может быть `root`, `healthcheck` или `mariadb.sys` — эти имена зарезервированы платформой/оператором.

### Пароль (`password`)

Пароль для подключения от имени создаваемого пользователя.

### Базы данных (`dbName`)

JSON-массив вида `[{"dbname": "имя_базы"}]` — список баз, к которым выдаётся полный доступ (`ALL PRIVILEGES`). Все перечисленные базы должны уже существовать в кластере (создать заранее через `create_database`).

### Разрешённые хосты (`accessHosts`)

MySQL host-паттерн, с которого разрешено подключение под этим пользователем (например `%` — без ограничений, или конкретная подсеть). Определяет `user@host` в самой MariaDB — если указать слишком узкое значение, подключение снаружи ожидаемого диапазона будет отклонено сервером на уровне аутентификации, даже если сеть/firewall пропускают трафик.

---

## 7. Параметры удаления пользователя (`delete_user`)

### Имя пользователя (`username`)

Пользователь должен существовать в кластере. `root`/`healthcheck`/`mariadb.sys` удалить нельзя.

---

## 8. Выходные параметры

### internalConnect

Внутренний адрес для подключения из сервисов, работающих в том же кластере Kubernetes:
```json
{
"master": {
"dns": "..svc.",
"ip": null,
"port": 3306
}
}
```

### externalConnect

Присутствует в выходных данных, **только если** был запрошен внешний доступ (`accessConfiguration.masterIpSpace` отличен от `no-needed`). Если внешний доступ не запрошен или был отключён через `modify` — этого блока не будет вовсе (пустой блок в состояние не пишется):
```json
{
"master": {
"dns": "write..",
"ip": "<внешний IP>",
"port": 3306
}
}
```

---

## 9. Пример подключения

### 9.1 Изнутри кластера / того же namespace

```bash
mariadb -h -P 3306 -u -p
```

### 9.2 Через port-forward

```bash
kubectl port-forward svc/ 3306:3306 -n
```

**Важно:** после `port-forward` подключайтесь именно по `127.0.0.1`, а не `localhost`:

```bash
mariadb -h 127.0.0.1 -P 3306 -u -p
```

Клиент `mysql`/`mariadb` при указании `-h localhost` **игнорирует TCP/порт** и всегда пытается подключиться через локальный unix-сокет (`/var/lib/mysql/mysql.sock`), которого на вашей машине нет — подключение упадёт с `ERROR 2002 (HY000): Can''t connect to local server through socket`. `127.0.0.1` форсирует реальное TCP-подключение. Также не забывайте `-P` (порт) с заглавной буквы — строчная `-p` относится к паролю.

### 9.3 Снаружи (внешний адрес)

```bash
mariadb -h -P 3306 -u -p
```

Доступно только если при создании/модификации был указан реальный `masterIpSpace` и подключающийся IP входит в `accessConfiguration.masterAccessList` (или список пуст).

Где:
* `` — имя пользователя
* `` — пароль пользователя

---

## 10. Дополнительная информация

* Расписание бэкапов (`backupConfiguration.schedule`/`retain`) задаётся один раз при создании и не может быть изменено позже — ограничение самого `mariadb-operator`, а не платформы.
* Версию MariaDB можно только повышать, откат на более старую версию не поддерживается.
* Размер диска можно только увеличивать.
* `suspend` реально останавливает под (масштабирование StatefulSet в 0 реплик), а не просто помечает кластер как приостановленный — расход ресурсов CPU/RAM/диска (кроме уже занятого диска) прекращается.
* При отключении внешнего доступа через `modify` (`masterIpSpace: no-needed`) внешний Service, DNS-запись и правило firewall удаляются, а `externalConnect` пропадает из выходных данных.
* Самостоятельного восстановления из бэкапа (операции `restore`) пока нет. Бэкапы лежат в S3 инстанса — восстановление данных в существующий кластер выполняется вручную, скачиванием и применением бэкапа самим владельцем инстанса.' lifecycle: suspendOnDestroyDefault: true adoptExistingOnCreateDefault: false operations: - svcOperationId: 138 operation: create kind: instance action: create - svcOperationId: 242 operation: create_database kind: subresource action: create - svcOperationId: 243 operation: create_user kind: subresource action: create - svcOperationId: 139 operation: delete kind: instance action: delete - svcOperationId: 248 operation: delete_database kind: subresource action: delete - svcOperationId: 247 operation: delete_user kind: subresource action: delete - svcOperationId: 142 operation: modify kind: instance action: modify - svcOperationId: 287 operation: reconcile kind: action action: reconcile - svcOperationId: 141 operation: resume kind: instance action: resume - svcOperationId: 140 operation: suspend kind: instance action: suspend stateOut: databases: {} users: {} cfsParams: - svcOperationCfsParamId: 877 svcOperationCfsParam: startupConfiguration dataType: map-fixed isRequired: true defaultValue: '' isModifiable: false dataDescriptor: resourceRealm: dataType: string defaultValue: k8s-4-ext-nubes-ru isRequired: true isModifiable: false valueList: - k8s-4-ext-nubes-ru - svcOperationCfsParamId: 878 svcOperationCfsParam: clusterConfiguration dataType: map-fixed isRequired: true defaultValue: '' isModifiable: true dataDescriptor: cpu: dataType: integer > 0 defaultValue: '500' isRequired: true isModifiable: false memory: dataType: integer > 0 defaultValue: '512' isRequired: true isModifiable: false replicas: dataType: integer > 0 defaultValue: '1' isRequired: true isModifiable: false valueList: - '1' disk: dataType: integer > 0 defaultValue: '10' isRequired: true isModifiable: false - svcOperationCfsParamId: 879 svcOperationCfsParam: accessConfiguration dataType: map-fixed isRequired: true defaultValue: '' isModifiable: true dataDescriptor: masterIpSpace: dataType: string defaultValue: '' isRequired: true isModifiable: false masterAccessList: dataType: json defaultValue: '[]' isRequired: true isModifiable: false - svcOperationCfsParamId: 880 svcOperationCfsParam: mariadbConfiguration dataType: map-fixed isRequired: true defaultValue: '' isModifiable: true dataDescriptor: version: dataType: string defaultValue: 9.4.0 isRequired: true isModifiable: false valueList: - 8.4.0 - 9.4.0 - svcOperationCfsParamId: 881 svcOperationCfsParam: backupConfiguration dataType: map-fixed isRequired: true defaultValue: '' isModifiable: false dataDescriptor: s3Uid: dataType: uuid defaultValue: '' isRequired: true isModifiable: false retain: dataType: integer > 0 defaultValue: '720' isRequired: true isModifiable: false schedule: dataType: string defaultValue: 0 0 * * * isRequired: true isModifiable: false - svcOperationCfsParamId: 882 svcOperationCfsParam: autoscaleConfiguration dataType: map-fixed isRequired: true defaultValue: '' isModifiable: true dataDescriptor: enabled: dataType: boolean defaultValue: 'false' isRequired: true isModifiable: false valueList: - 'false' - 'true' schedule: dataType: integer >= 0 defaultValue: '0' isRequired: true isModifiable: false valueList: - '0' - '5' - '12' - '23' quota: dataType: integer > 0 defaultValue: '100' isRequired: true isModifiable: false percent: dataType: integer > 0 defaultValue: '10' isRequired: true isModifiable: false valueList: - '10' - '15' - '20' - svcOperationCfsParamId: 734 svcOperationCfsParam: dbName dataType: string isRequired: true defaultValue: db-wpm05duv isModifiable: false - svcOperationCfsParamId: 735 svcOperationCfsParam: username dataType: string isRequired: true defaultValue: userhucihd6b isModifiable: false - svcOperationCfsParamId: 736 svcOperationCfsParam: password dataType: string isRequired: true defaultValue: oe063z3u isModifiable: false - svcOperationCfsParamId: 737 svcOperationCfsParam: dbName dataType: array-map-fixed isRequired: true defaultValue: '[{}]' isModifiable: false dataDescriptor: dbname: dataType: string defaultValue: '' isRequired: true isModifiable: false - svcOperationCfsParamId: 738 svcOperationCfsParam: accessHosts dataType: string isRequired: true defaultValue: '%' isModifiable: false - svcOperationCfsParamId: 456 svcOperationCfsParam: deleteS3Bucket dataType: boolean isRequired: true defaultValue: 'true' isModifiable: true valueList: - 'false' - 'true' - svcOperationCfsParamId: 745 svcOperationCfsParam: dbName dataType: string isRequired: true defaultValue: '' isModifiable: true - svcOperationCfsParamId: 744 svcOperationCfsParam: username dataType: string isRequired: true defaultValue: '' isModifiable: true - svcOperationCfsParamId: 883 svcOperationCfsParam: clusterConfiguration dataType: map-fixed isRequired: true defaultValue: '' isModifiable: true dataDescriptor: cpu: dataType: integer > 0 defaultValue: '' isRequired: true isModifiable: false memory: dataType: integer > 0 defaultValue: '' isRequired: true isModifiable: false replicas: dataType: integer > 0 defaultValue: '' isRequired: true isModifiable: false valueList: - '1' disk: dataType: integer > 0 defaultValue: '' isRequired: true isModifiable: false - svcOperationCfsParamId: 884 svcOperationCfsParam: accessConfiguration dataType: map-fixed isRequired: true defaultValue: '' isModifiable: true dataDescriptor: masterIpSpace: dataType: string defaultValue: '' isRequired: true isModifiable: false masterAccessList: dataType: json defaultValue: '' isRequired: true isModifiable: false - svcOperationCfsParamId: 885 svcOperationCfsParam: mariadbConfiguration dataType: map-fixed isRequired: true defaultValue: '' isModifiable: true dataDescriptor: version: dataType: string defaultValue: '' isRequired: true isModifiable: false valueList: - 8.4.0 - 9.4.0 - svcOperationCfsParamId: 887 svcOperationCfsParam: autoscaleConfiguration dataType: map-fixed isRequired: true defaultValue: '' isModifiable: true dataDescriptor: enabled: dataType: boolean defaultValue: '' isRequired: true isModifiable: false valueList: - 'false' - 'true' schedule: dataType: integer >= 0 defaultValue: '' isRequired: true isModifiable: false valueList: - '0' - '5' - '12' - '23' quota: dataType: integer > 0 defaultValue: '' isRequired: true isModifiable: false percent: dataType: integer > 0 defaultValue: '' isRequired: true isModifiable: false valueList: - '10' - '15' - '20' cfsParamsByOp: 138: - 877 - 878 - 879 - 880 - 881 - 882 242: - 734 243: - 735 - 736 - 737 - 738 139: - 456 248: - 745 247: - 744 142: - 883 - 884 - 885 - 887 287: [] 141: [] 140: [] stateParams: startupConfiguration: '{"resourceRealm": "k8s-4-ext-nubes-ru"}' clusterConfiguration: '{"cpu": 500, "memory": 512, "replicas": 1, "disk": 10}' accessConfiguration: '{"masterIpSpace": "", "masterAccessList": "[]"}' mariadbConfiguration: '{"version": "9.4.0"}' backupConfiguration: '{"s3Uid": "", "retain": 720, "schedule": "0 0 * * *"}' autoscaleConfiguration: '{"enabled": false, "schedule": 0, "quota": 100, "percent": 10}'