OpenSearch
В Памир журналы и связанные с ними индексы хранятся в OpenSearch, запущенном
в контейнере Docker (сервис opensearch). OpenSearch может работать как в режиме
single-node, так и в виде кластера на нескольких
узлах Docker Engine.
Для OpenSearch рекомендуется механизм снапшотов (snapshots) с записью в репозиторий резервных копий. Репозиторий располагается на внешнем хранилище, подключённом в контейнер:
- общий каталог по NFS (тип репозитория
fs) — основной поддерживаемый вариант.
Снапшоты инкрементальны: каждый последующий снапшот в том же репозитории сохраняет только изменившиеся сегменты.
Параметры подключения
| Параметр | Значение |
|---|---|
| Сервис / контейнер | opensearch |
| REST API | https://opensearch:9200 (TLS, по умолчанию самоподписанный сертификат) |
| Каталог данных | /usr/share/opensearch/data (том pamir_opensearch-data) |
| Пользователь для резервного копирования | pamir-backup-user (роль pamir_backup) |
Для всех операций со снапшотами используется специальный пользователь pamir-backup-user
с ролью pamir_backup. Эта роль обладает минимально необходимыми правами:
управление репозиторием, создание и восстановление снапшотов (включая пересоздание
индексов и восстановление глобального состояния). При этом роль не имеет доступа на
чтение содержимого индексов и не может удалять индексы.
Обычные административные роли для этого не подходят: pamir_admin умеет создавать снапшоты,
но не имеет прав на создание индексов при восстановлении, а pamir_root (all_access)
избыточен по правам.
Плагин безопасности OpenSearch включён, REST API работает по HTTPS. В примерах ниже
используется HTTP Basic-аутентификация и флаг curl -k (не проверять самоподписанный
сертификат). Пароль пользователя pamir-backup-user задаётся в security-конфигурации
(internal_users.yml) на этапе сборки образа; подставьте его вместо <пароль>. Подробнее
о пользователях и ролях — в разделе
Ролевая модель OpenSearch.
Все команды выполняются из каталога приложения ($HOME/.pamir или /opt/pamir).
Подготовка репозитория снапшотов (NFS)
Контейнер opensearch запускается в режиме read_only, поэтому каталог репозитория
должен быть подключён как отдельный том (bind mount) на внешнее NFS-хранилище, а путь
к нему — объявлен в настройке path.repo.
Шаг 1. Смонтируйте NFS-каталог на хост (пример для /mnt/os-snapshots) и переопределите
сервис opensearch в docker-compose.additional.yml:
services:
opensearch:
environment:
path.repo: /mnt/snapshots
volumes:
- type: bind
source: /mnt/os-snapshots # точка монтирования NFS на хосте
target: /mnt/snapshots # путь внутри контейнера = path.repo
Процесс OpenSearch в контейнере работает от пользователя opensearch (uid 1000).
Каталог репозитория (NFS-экспорт или локальный каталог) должен быть доступен на запись
этому uid, иначе создание снапшота завершится ошибкой. Настройте владельца/права
соответствующим образом (например, chown 1000:1000 на каталог или экспорт NFS с записью
для uid 1000).
В кластерной конфигурации репозиторий снапшотов
должен быть доступен по одному и тому же пути на всех узлах (manager и data).
Подключите одно и то же NFS-хранилище в каждый контейнер opensearch-* на каждом узле
Docker Engine с идентичным path.repo.
Шаг 2. Примените изменения:
cd "$HOME/.pamir"
pamirctl start opensearch
Шаг 3. Зарегистрируйте репозиторий через REST API (однократно):
docker compose exec -it opensearch curl -k \
-u pamir-backup-user:<пароль> \
-X PUT "https://localhost:9200/_snapshot/pamir_fs" \
-H 'Content-Type: application/json' -d '{
"type": "fs",
"settings": { "location": "/mnt/snapshots", "compress": true }
}'
Проверка регистрации:
docker compose exec -it opensearch curl -k \
-u pamir-backup-user:<пароль> \
-X POST "https://localhost:9200/_snapshot/pamir_fs/_verify"
Резервное копирование (создание снапшота)
Создание снапшота со всеми индексами и ожиданием завершения:
cd "$HOME/.pamir"
SNAP="snap-$(date +%F-%H%M)"
docker compose exec -it opensearch curl -k \
-u pamir-backup-user:<пароль> \
-X PUT "https://localhost:9200/_snapshot/pamir_fs/${SNAP}?wait_for_completion=true" \
-H 'Content-Type: application/json' -d '{
"indices": "*",
"include_global_state": true
}'
где:
indices: "*"— включить все индексы (можно указать шаблон, напримерpamir-*);include_global_state: true— сохранить состояние кластера (шаблоны, настройки).
Снапшот физически записывается в каталог path.repo (на NFS), поэтому именно содержимое
NFS-хранилища является резервной копией.
Восстановление
Перед восстановлением индекса его необходимо закрыть или удалить — OpenSearch не восстанавливает поверх открытого индекса с тем же именем.
Шаг 1. Просмотрите доступные снапшоты:
docker compose exec -it opensearch curl -k \
-u pamir-backup-user:<пароль> \
-X GET "https://localhost:9200/_snapshot/pamir_fs/_all?pretty"
Шаг 2. Закройте восстанавливаемые индексы (пример для всех):
docker compose exec -it opensearch curl -k \
-u pamir-backup-user:<пароль> \
-X POST "https://localhost:9200/_all/_close"
Если индексы были удалены (а не закрыты), шаг 2 не нужен — _restore создаст их заново.
Шаг 3. Запустите восстановление:
docker compose exec -it opensearch curl -k \
-u pamir-backup-user:<пароль> \
-X POST "https://localhost:9200/_snapshot/pamir_fs/snap-2026-06-08-0200/_restore?wait_for_completion=true" \
-H 'Content-Type: application/json' -d '{
"indices": "*",
"include_global_state": true
}'
Проверка резервных копий
Поверхностная проверка состояния и размера снапшотов:
# Статус и список снапшотов через API
docker compose exec -it opensearch curl -k \
-u pamir-backup-user:<пароль> \
-X GET "https://localhost:9200/_snapshot/pamir_fs/_all?pretty" | head -40
# Детальный статус (фаза, число шардов)
docker compose exec -it opensearch curl -k \
-u pamir-backup-user:<пароль> \
-X GET "https://localhost:9200/_snapshot/pamir_fs/_status?pretty"
# Размер и дата файлов репозитория на NFS (с хоста)
ls -lh /mnt/os-snapshots/
du -sh /mnt/os-snapshots/
Снапшот считается корректным, если в ответе API state равен SUCCESS,
а failures пуст.
Автоматизация (systemd timer)
Скрипт ~/.local/bin/pamir-backup-opensearch.sh (подставьте пароль pamir-backup-user
или передавайте его из защищённого источника):
#!/usr/bin/env bash
set -euo pipefail
cd "$HOME/.pamir"
OS_USER="pamir-backup-user"
OS_PASS="<пароль>"
REPO="pamir_fs"
SNAP="snap-$(date +%F-%H%M)"
docker compose exec -T opensearch curl -k -sf \
-u "${OS_USER}:${OS_PASS}" \
-X PUT "https://localhost:9200/_snapshot/${REPO}/${SNAP}?wait_for_completion=true" \
-H 'Content-Type: application/json' \
-d '{"indices":"*","include_global_state":true}'
chmod +x ~/.local/bin/pamir-backup-opensearch.sh
Служба и таймер:
[Unit]
Description=Pamir OpenSearch snapshot
[Service]
Type=oneshot
ExecStart=%h/.local/bin/pamir-backup-opensearch.sh
[Unit]
Description=Pamir OpenSearch snapshot daily at 02:00
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
Активация:
systemctl --user daemon-reload
systemctl --user enable --now pamir-backup-opensearch.timer
loginctl enable-linger "$USER"
systemctl --user list-timers pamir-backup-opensearch.timer
Для автоматического удаления устаревших снапшотов по расписанию можно использовать штатный механизм Snapshot Management (SM) OpenSearch — он создаёт снапшоты и применяет политику хранения без внешнего планировщика.