MAATRIX / Блог / Как установить и настроить OpenSearch на VPS

Как установить и настроить OpenSearch на VPS

MAATRIX

Когда LIKE '%слово%' в SQL перестаёт справляться, а логи с десятка сервисов невозможно просмотреть глазами — нужен полнотекстовый поисковый движок. OpenSearch — форк Elasticsearch, который AWS выпустила после смены лицензии Elastic в 2021 году, и сегодня это один из самых распространённых вариантов для поиска и аналитики логов на своей инфраструктуре. Ниже — установка через официальный пакетный репозиторий (без Docker), настройка памяти, security plugin и политик хранения индексов, чтобы диск не забился логами за неделю.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Почему OpenSearch, а не голый Elasticsearch

В начале 2021 года Elastic перевела Elasticsearch и Kibana с Apache 2.0 на SSPL/Elastic License — закрыв бесплатное использование движка в конкурирующих managed-сервисах. AWS форкнула последнюю Apache-версию (7.10.2) и продолжила развивать её как OpenSearch с открытой лицензией. Практическая разница на уровне «поднять индекс и искать по нему» невелика: DSL-запросы, шардинг, маппинги работают похоже. Но если вы разворачиваете сервис для клиентов или встраиваете поиск в продукт, который продаёте, — лицензия имеет значение.

OpenSearch включает Dashboards (форк Kibana), security plugin и Index State Management (аналог ILM) из коробки, без отдельной подписки. Для VPS-инсталляции это удобно: не нужно докупать x-pack, чтобы получить ролевую модель доступа и ротацию индексов.

Требования к серверу и подготовка ОС

OpenSearch работает на JVM и заметно требовательнее к памяти, чем обычный веб-сервис:

РесурсМинимум (тест)Разумный старт (прод)
RAM4 GB8 GB и больше
CPU2 vCPU4 vCPU
ДискSSD, 20 GBNVMe, от 50 GB
ОСUbuntu 24.04 / Debian 12то же

Перед установкой поднимите системный лимит vm.max_map_count — без него OpenSearch откажется стартовать с ошибкой про memory-mapped файлы Lucene:

sudo sysctl -w vm.max_map_count=262144
echo 'vm.max_map_count=262144' | sudo tee -a /etc/sysctl.conf

И увеличьте лимиты на количество открытых файлов и блокировку памяти — пакет OpenSearch задаёт их в systemd-юните, но стоит перепроверить после установки командой systemctl show opensearch | grep -i limit.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Установка через официальный APT-репозиторий

Ставить будем нативным пакетом, а не через Docker Compose — так проще управлять systemd-юнитом и файлами конфигурации напрямую. Если вам, наоборот, нужнее контейнерный вариант со стеком OpenSearch + Dashboards в одном docker-compose.yml, у нас есть отдельный разбор — установка OpenSearch на VPS через Docker. Для нативной установки подключите GPG-ключ и репозиторий:

curl -o- https://artifacts.opensearch.org/publickeys/opensearch.pgp \
  | sudo gpg --dearmor --batch --yes -o /usr/share/keyrings/opensearch-keyring

echo "deb [signed-by=/usr/share/keyrings/opensearch-keyring] \
https://artifacts.opensearch.org/releases/bundle/opensearch/2.x/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/opensearch-2.x.list

sudo apt update

Пакет OpenSearch на этапе установки требует задать пароль администратора — если не задать его заранее переменной окружения, установщик спросит его интерактивно через debconf. Для автоматизации (Ansible, скрипт первичной настройки) экспортируйте пароль до apt install:

export OPENSEARCH_INITIAL_ADMIN_PASSWORD='Str0ng-Uniq-P@ssw0rd-2026!'
sudo -E apt install opensearch

Пароль должен быть достаточно сложным (длина, регистры, цифры, спецсимвол) — иначе установщик просто откажется его принять. После установки включите и запустите сервис:

sudo systemctl enable --now opensearch
sudo systemctl status opensearch

Первый старт занимает минуту-две — JVM инициализирует внутренние индексы security plugin. Логи — в /var/log/opensearch/, конфиги — в /etc/opensearch/.

Настройка opensearch.yml и памяти (heap)

Главное правило: JVM heap (-Xms/-Xmx) не должен превышать примерно 50% RAM сервера. Остальную память JVM оставляет операционной системе — она уходит на файловый кеш Lucene-индексов, и без него поиск начинает упираться в диск на каждом запросе. На VPS с 4 GB RAM heap стоит выставлять не выше 1.5–2 GB, оставляя запас под саму систему и агенты мониторинга.

Не редактируйте jvm.options напрямую — правильный способ задать heap в новых версиях OpenSearch — файл в каталоге jvm.options.d:

sudo nano /etc/opensearch/jvm.options.d/heap.options
-Xms2g
-Xmx2g

Значения -Xms и -Xmx должны совпадать — это исключает изменение размера кучи в рантайме, которое дорого стоит по производительности. Второе правило — не задирайте heap выше примерно 30-32 GB, даже если памяти много: после этого порога JVM теряет оптимизацию compressed oops. Для одной VPS-ноды этот потолок редко актуален.

После правки перезапустите сервис: sudo systemctl restart opensearch.

Второй файл, который стоит настроить сразу, — основной конфиг /etc/opensearch/opensearch.yml. Для одиночной ноды на VPS минимально нужно задать имя кластера, сетевой интерфейс и режим discovery:

# /etc/opensearch/opensearch.yml
cluster.name: maatrix-search
node.name: node-1

# слушаем только приватный интерфейс/localhost, не 0.0.0.0 без причины
network.host: 127.0.0.1

discovery.type: single-node

path.data: /var/lib/opensearch
path.logs: /var/log/opensearch

# для снапшотов на файловую систему (см. ниже)
path.repo: ["/mnt/opensearch-backups"]

Если к OpenSearch обращаются другие сервисы на том же VPS, 127.0.0.1 достаточно — трафик не выходит за пределы хоста. Если нужен доступ извне или с других серверов в приватной сети, укажите конкретный приватный IP, а не 0.0.0.0, и закройте порт 9200 файрволом. Публиковать OpenSearch напрямую в интернет без reverse proxy — частая причина утечек данных из открытых Elasticsearch/OpenSearch кластеров. Для внешнего доступа поставьте перед кластером nginx как reverse proxy с TLS-терминацией и ограничением по IP.

Security plugin: пароли, роли, свои сертификаты

Security plugin включён по умолчанию и поднимает TLS с самоподписанным демо-сертификатом сразу после установки — этого достаточно для теста, но не для прода. Проверить, что кластер жив и требует авторизации:

curl -k -u admin:'Str0ng-Uniq-P@ssw0rd-2026!' \
  https://localhost:9200/_cluster/health?pretty

Ожидаемый ответ — JSON со статусом green или yellow (для одной ноды yellow нормален — реплики шардов физически негде размещать):

{
  "cluster_name" : "maatrix-search",
  "status" : "yellow",
  "number_of_nodes" : 1
}

Для прода замените демо-сертификаты на свои: файлы esnode.pem, esnode-key.pem, root-ca.pem в /etc/opensearch/ подставьте на сертификаты вашего CA и укажите пути в блоке plugins.security.ssl внутри opensearch.yml.

Если нужны отдельные роли — сервисный аккаунт только на запись логов, read-only пользователь для Dashboards, — они настраиваются в internal_users.yml и roles_mapping.yml внутри /etc/opensearch/opensearch-security/. Пароль хешируется утилитой hash.sh, хеш вставляется в internal_users.yml, изменения применяются через securityadmin.sh -cd /etc/opensearch/opensearch-security/ -icl -nhnv с указанием CA и клиентского сертификата. Держите пароли и ключи вне git — тот же принцип, что в статье про управление паролями через Docker secrets: секреты в переменных окружения хоста, а не в репозитории.

Индексы для логов: шаблоны и ISM-политики хранения

Если задача — аналитика логов, писать всё в один растущий индекс плохая идея: со временем поиск и индексация замедляются, а старые данные никто не чистит. Стандартный подход — rollover-индексы с алиасом на запись плюс политика Index State Management, которая переключает индекс и удаляет старые данные автоматически.

Индекс-шаблон с алиасом для записи:

curl -k -u admin:'...' -X PUT "https://localhost:9200/_index_template/logs-template" \
  -H 'Content-Type: application/json' -d '{
    "index_patterns": ["logs-*"],
    "template": {
      "settings": {
        "number_of_shards": 1,
        "number_of_replicas": 0,
        "plugins.index_state_management.rollover_alias": "logs-write"
      }
    }
  }'

curl -k -u admin:'...' -X PUT "https://localhost:9200/%3Clogs-%7Bnow%2Fd%7D-000001%3E" \
  -H 'Content-Type: application/json' -d '{
    "aliases": { "logs-write": { "is_write_index": true } }
  }'

Политика ISM, которая ротирует индекс при достижении 5 GB или 7 дней возраста, а через 30 дней удаляет:

curl -k -u admin:'...' -X PUT "https://localhost:9200/_plugins/_ism/policies/logs-policy" \
  -H 'Content-Type: application/json' -d '{
    "policy": {
      "description": "Ротация и удаление логов",
      "default_state": "hot",
      "states": [
        {
          "name": "hot",
          "actions": [{ "rollover": { "min_size": "5gb", "min_index_age": "7d" } }],
          "transitions": [{ "state_name": "delete", "conditions": { "min_index_age": "30d" } }]
        },
        { "name": "delete", "actions": [{ "delete": {} }] }
      ],
      "ism_template": { "index_patterns": ["logs-*"], "priority": 100 }
    }
  }'

Это избавляет от ручной чистки индексов — идея та же, что в статье про ротацию логов, чтобы не забивался диск, только на уровне OpenSearch, а не файловой системы. Для доставки логов в кластер ставят Fluent Bit или Data Prepper на источниках — они пишут напрямую в алиас logs-write.

Мониторинг диска, снапшоты и типичные проблемы

OpenSearch чувствителен к нехватке места на диске сильнее, чем большинство сервисов: при достижении порога flood_stage (по умолчанию 95% занятого диска) кластер переводит все индексы в режим только для чтения — запись останавливается целиком, включая новые логи. Проверить текущие пороги:

curl -k -u admin:'...' https://localhost:9200/_cluster/settings?include_defaults=true \
  | grep -A3 watermark

Если это уже случилось и место освобождено, кластер не снимет блокировку сам — нужно явно её убрать:

curl -k -u admin:'...' -X PUT "https://localhost:9200/_all/_settings" \
  -H 'Content-Type: application/json' \
  -d '{"index.blocks.read_only_allow_delete": null}'

Поэтому мониторинг свободного места — не опция, а необходимость; проще настроить алерт заранее, чем разбирать read-only кластер ночью. Подойдёт связка из статьи про мониторинг диска на VPS, а для метрик самого OpenSearch (heap usage, latency, число активных шардов) — Grafana и Prometheus с exporter'ом, снимающим данные через _nodes/stats API.

Для резервных копий индексов используйте snapshot API на путь, указанный в path.repo:

curl -k -u admin:'...' -X PUT "https://localhost:9200/_snapshot/backup_repo" \
  -H 'Content-Type: application/json' \
  -d '{"type": "fs", "settings": {"location": "/mnt/opensearch-backups"}}'

curl -k -u admin:'...' -X PUT "https://localhost:9200/_snapshot/backup_repo/snapshot-1?wait_for_completion=true"

Снапшоты инкрементальны — повторные запуски копируют только изменившиеся сегменты. Каталог path.repo стоит выносить на отдельный диск или в объектное хранилище через rclone, чтобы бэкап не зависел от того же тома, где живут индексы.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

OpenSearch и Elasticsearch совместимы по API?

В целом да для базовых операций — индексация, поиск, DSL-запросы — так как OpenSearch форкнулся от Elasticsearch 7.10.2 с высокой совместимостью. Но версии расходятся дальше, и на сложных фичах (некоторые агрегации, ML-модули) совместимость не гарантирована — проверяйте документацию под конкретную версию.

Обязательно ли использовать Dashboards?

Нет, это отдельный опциональный компонент. Если вам нужен только программный доступ через REST API (например, поиск из бэкенда приложения), Dashboards можно не устанавливать вообще и сэкономить память — это ещё один процесс на JVM/Node.js поверх самого кластера.

Что делать, если сервис не стартует с ошибкой про max_map_count?

Это лимит ядра хоста, а не приложения — примените sysctl -w vm.max_map_count=262144 и закрепите его в /etc/sysctl.conf, иначе после перезагрузки VPS настройка слетит.

Сколько диска реально нужно под индексы?

Зависит от схемы полей и включённых анализаторов, но как грубый ориентир — инвертированный индекс Lucene обычно занимает сопоставимый или чуть больший объём, чем исходные данные. Закладывайте запас от 1.5 до 2 объёмов сырых логов и уточняйте на своих реальных данных, а не на чужих бенчмарках.

Нужен ли кластер из нескольких нод на старте?

Почти всегда нет. Несколько нод на одном физическом VPS не защищают от отказа диска или сети самой машины — реальный смысл появляется только при нодах на разных серверах. Начинайте с одной ноды и discovery.type: single-node, расширяйтесь по факту роста нагрузки.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →