Перейти к основному содержимому
Версия: 2.5

OpenSearch HA

Для организации отказоустойчивой конфигурации Opensearch необходимо переопределить сервисы в файле docker-compose.additional.yml:

Важно

Перед запуском контейнеров кластера требуется установить переменную PAMIR_SKIP_SECURITY_INIT в значение true для всех нод OS, кроме одного из менеджеров (нода с ролью manager). Это требуется для того, чтобы инициализация плагина security происходила только с одной ноды и конфигурация распространялась на весь кластер.

Для этого в файле .override.env прописать:

.override.env
PAMIR_SKIP_SECURITY_INIT=true

Для отдельного менеджера (например, сервиса opensearch-m-1) переопределяем переменную в false:

docker-compose.additional.yml
services:
opensearch-m-1:
environment:
PAMIR_SKIP_SECURITY_INIT: "false"

На разных узлах Docker Engine​

docker-compose.additional.yml
services:
opensearch:
profiles: [never]
opensearch-m-1:
extends:
file: docker-compose.deps.yml
service: opensearch
container_name: opensearch-m-1
environment:
network.host: 0.0.0.0 # слушать на всех интерфейсах контейнера
network.publish_host: <IP-адрес текущего узла Docker Engine> # этот адрес сообщать кластеру
network.transport.publish_port: 9301
node.name: opensearch-m-1
node.roles: cluster_manager
cluster.name: opensearch-cluster
discovery.seed_hosts: >-
opensearch-m-1:9300,
opensearch-m-2:9301,
opensearch-m-3:9301
cluster.initial_cluster_manager_nodes: >-
opensearch-m-1,
opensearch-m-2,
opensearch-m-3
path.data: /usr/share/opensearch/data
path.logs: /usr/share/opensearch/logs
PAMIR_SKIP_SECURITY_INIT: "false"
DISABLE_INSTALL_DEMO_CONFIG: "false"
PAMIR_MANAGER_HOSTS: >-
opensearch-m-1,
opensearch-m-2,
opensearch-m-3
PAMIR_DATA_HOSTS: >-
opensearch-d-1,
opensearch-d-2,
opensearch-d-3
extra_hosts:
# Имена соседних узлов → их внешние IP
- "opensearch-m-2:<IP-адрес узла Docker Engine c опубликованным наружу портом 9300>"
- "opensearch-m-3:<IP-адрес узла Docker Engine c опубликованным наружу портом 9300>"
- "opensearch-d-2:<IP-адрес узла Docker Engine c опубликованным наружу портом 9300>"
- "opensearch-d-3:<IP-адрес узла Docker Engine c опубликованным наружу портом 9300>"
ports:
- "9301:9300"
volumes:
- ./data/opensearch/opensearch.yml:/usr/share/opensearch/config/opensearch.yml:ro
- ./data/opensearch/demo-certs/root-ca.pem:/usr/share/opensearch/config/root-ca.pem:ro
- ./data/opensearch/demo-certs/esnode.pem:/usr/share/opensearch/config/esnode.pem:ro
- ./data/opensearch/demo-certs/esnode-key.pem:/usr/share/opensearch/config/esnode-key.pem:ro
- ./data/opensearch/demo-certs/kirk.pem:/usr/share/opensearch/config/kirk.pem:ro
- ./data/opensearch/demo-certs/kirk-key.pem:/usr/share/opensearch/config/kirk-key.pem:ro
- opensearch-m-1_data:/usr/share/opensearch/data

opensearch-d-1:
extends:
file: docker-compose.deps.yml
service: opensearch
container_name: opensearch-d-1
depends_on:
opensearch-m-1:
condition: service_started
environment:
network.host: 0.0.0.0 # слушать на всех интерфейсах контейнера
network.publish_host: <IP-адрес текущего узла Docker Engine> # этот адрес сообщать кластеру
network.transport.publish_port: 9302
node.name: opensearch-d-1
node.roles: data,ingest
cluster.name: opensearch-cluster
discovery.seed_hosts: >-
opensearch-m-1:9300,
opensearch-m-2:9301,
opensearch-m-3:9301
cluster.initial_cluster_manager_nodes: >-
opensearch-m-1,
opensearch-m-2,
opensearch-m-3
OPENSEARCH_JAVA_OPTS: "-Xms1g -Xmx1g"
extra_hosts:
# Имена соседних узлов → их внешние IP
- "opensearch-m-2:<IP-адрес узла Docker Engine c опубликованным наружу портом 9300>"
- "opensearch-m-3:<IP-адрес узла Docker Engine c опубликованным наружу портом 9300>"
- "opensearch-d-2:<IP-адрес узла Docker Engine c опубликованным наружу портом 9300>"
- "opensearch-d-3:<IP-адрес узла Docker Engine c опубликованным наружу портом 9300>"
ports:
- "9302:9300"
volumes:
- ./data/opensearch/opensearch.yml:/usr/share/opensearch/config/opensearch.yml:ro
- ./data/opensearch/demo-certs/root-ca.pem:/usr/share/opensearch/config/root-ca.pem:ro
- ./data/opensearch/demo-certs/esnode.pem:/usr/share/opensearch/config/esnode.pem:ro
- ./data/opensearch/demo-certs/esnode-key.pem:/usr/share/opensearch/config/esnode-key.pem:ro
- opensearch-d-1_data:/usr/share/opensearch/data

opensearch-c-1:
extends:
file: docker-compose.deps.yml
service: opensearch
container_name: opensearch-c-1
depends_on:
opensearch-d-1:
condition: service_healthy
environment:
network.host: 0.0.0.0 # слушать на всех интерфейсах контейнера
network.publish_host: <IP-адрес текущего узла Docker Engine> # этот адрес сообщать кластеру
network.transport.publish_port: 9303
node.name: opensearch-c-1
node.roles: ""
cluster.name: opensearch-cluster
discovery.seed_hosts: >-
opensearch-m-1:9300,
opensearch-m-2:9301,
opensearch-m-3:9301
cluster.initial_cluster_manager_nodes: >-
opensearch-m-1,
opensearch-m-2,
opensearch-m-3
extra_hosts:
# Имена соседних узлов → их внешние IP
- "opensearch-m-2:<IP-адрес узла Docker Engine c опубликованным наружу портом 9300>"
- "opensearch-m-3:<IP-адрес узла Docker Engine c опубликованным наружу портом 9300>"
- "opensearch-d-2:<IP-адрес узла Docker Engine c опубликованным наружу портом 9300>"
- "opensearch-d-3:<IP-адрес узла Docker Engine c опубликованным наружу портом 9300>"
ports:
- "9200:9200"
- "9303:9300"
- "9600:9600"
volumes:
- ./data/opensearch/opensearch.yml:/usr/share/opensearch/config/opensearch.yml:ro
- ./data/opensearch/demo-certs/root-ca.pem:/usr/share/opensearch/config/root-ca.pem:ro
- ./data/opensearch/demo-certs/esnode.pem:/usr/share/opensearch/config/esnode.pem:ro
- ./data/opensearch/demo-certs/esnode-key.pem:/usr/share/opensearch/config/esnode-key.pem:ro
- opensearch-c-1_data:/usr/share/opensearch/data

volumes:
opensearch-m-1_data:
opensearch-d-1_data:
opensearch-c-1_data:
примечание

В вышеописанной конфигурации используется demo-конфигурация security с самоподписанными сертификатами.

warning

В production окружении сертификаты необходимо получить в доверенном корневом УЦ на каждую ноду Opensearch (esnode.pem и esnode-key.pem).

В root-ca.pem должна быть полная цепочка доверия сертификатов.

Сертификат администрирования (kirk.pem и kirk-key.pem) получается отдельно и подключается только к manager-нодам.

Использование демо-сертификатов настоятельно не рекомендуется.

Получить их можно следующими действиями:

  1. Запустить контейнер OS с пробросом директории локальной машины:

    export COMPOSE_ENV_FILES=.env,.deps.autogen
    mkdir -p data/opensearch/demo-certs
    docker-compose run --no-deps --rm -it \
    -v $(pwd)/data/opensearch/demo-certs:/usr/share/opensearch/demo-config \
    opensearch \
    bash
  2. Внутри контейнера выполнить команды:

    /usr/share/opensearch/plugins/opensearch-security/tools/install_demo_configuration.sh -y -i -s
    cp -p /usr/share/opensearch/config/root-ca.pem \
    /usr/share/opensearch/config/esnode.pem \
    /usr/share/opensearch/config/esnode-key.pem \
    /usr/share/opensearch/config/kirk.pem \
    /usr/share/opensearch/config/kirk-key.pem \
    /usr/share/opensearch/config/opensearch.yml \
    /usr/share/opensearch/demo-config/
    exit
  3. Файл opensearch.yml из data/opensearch/demo-certs переместить в data/opensearch/opensearch.yml.

  4. После чего проверить соответствие путей в docker-compose.additional.yml с путями файлов, и запустить сервисы.

Данную процедуру повторить на всех узлах, изменяя имя контейнера container_name и переменные окружения кластера в environment.

Интеграция с API Gateway​

В этой схеме API Gateway на узле Памир не видит контейнер opensearch-dashboards, поэтому динамическая конфигурация на основе лейблов не работает — нужен статический конфиг nginx (общая схема описана в разделе Сценарий 2: кластер OpenSearch на смежных серверах).

Шаг 1. Отключить локальный opensearch-dashboards на узле с API Gateway и переопределить адрес кластера в env-файле для внутренних сервисов Памир (миграция индексов, провижининг ролей):

docker-compose.additional.yml
services:
opensearch-dashboards:
profiles: !override [never]
.override.env
OPENSEARCH_MIGRATOR_PASSWORD=<пароль_пользователя_pamir-migrator-user>
OPENSEARCH_HOST=https://pamir-migrator-user:$OPENSEARCH_MIGRATOR_PASSWORD@<IP-координатора>:9200

Шаг 2. Смонтировать статические конфиги в контейнер frontend:

docker-compose.additional.yml
services:
frontend:
volumes:
- ./data/nginx/conf.d/opensearch-cluster.conf:/etc/nginx/conf.d/opensearch-cluster.conf:ro
- ./data/nginx/vhost/backend:/etc/nginx/vhost.d/backend:ro

Шаг 3. Описать upstream-блок в data/nginx/conf.d/opensearch-cluster.conf — указывает на узел с Dashboards:

data/nginx/conf.d/opensearch-cluster.conf
upstream opensearch-dashboards {
server <IP-узла-dashboards>:5601;
keepalive 4;
}

Шаг 4. Описать location в data/nginx/vhost/backend с пробросом auth-заголовков пользователя:

data/nginx/vhost/backend
location ^~ /os_dashboards/ {
auth_request /_pamir_auth;

# Извлечь идентификационные заголовки из ответа auth-сервиса
auth_request_set $p_user $upstream_http_x_user_login;
auth_request_set $p_roles $upstream_http_x_user_opensearch_role;

# Пробросить в Dashboards для авторизации в OpenSearch
proxy_set_header X-User-Login $p_user;
proxy_set_header X-User-Opensearch-Role $p_roles;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_pass http://opensearch-dashboards/;
}

Проброс X-User-Login / X-User-Opensearch-Role обязателен для авторизации пользователя в OpenSearch по принципу single sign-on (подробнее — в Ролевой модели OpenSearch).

На одном узле Docker Engine​

Также возможен запуск нескольких экземпляров нод Opensearch.

Конфигурация запуска аналогична вышеописанной, за исключением некоторых моментов:

  1. Убрать extra_hosts из всех сервисов (т.к. ноды будут в одной сети Docker).
  2. Убрать network.publish_host, network.transport.publish_port и network.host из environment из всех сервисов (аналогично пункту выше).
  3. В discovery.seed_hosts убрать порты после адреса менеджера (т.к. маппинга портов нет).

Интеграция с API Gateway​

Если кластер OpenSearch запущен на одном узле с Памир, по умолчанию opensearch-dashboards и внутренние сервисы (миграция индексов, провижининг ролей) обращаются к single-node контейнеру opensearch:9200. В кластерной конфигурации этого контейнера нет — обращения нужно перенаправить на координирующую ноду (opensearch-c-1).

Для этого в .override.env (или другом env-файле) переопределите переменные окружения:

.override.env
OPENSEARCH_MIGRATOR_PASSWORD=<пароль_пользователя_pamir-migrator-user>
OPENSEARCH_HOST=https://pamir-migrator-user:$OPENSEARCH_MIGRATOR_PASSWORD@opensearch-c-1:9200
OPENSEARCH_HOSTS='["https://opensearch-c-1:9200"]'

где:

  • OPENSEARCH_HOST — используется внутренними сервисами Памир с правами пользователя pamir-migrator-user;
  • OPENSEARCH_HOSTS — используется opensearch-dashboards (формат — JSON-массив строк, как требует OpenSearch Dashboards).

Если координирующих нод несколько, в OPENSEARCH_HOSTS можно перечислить их через запятую внутри массива (например, '["https://opensearch-c-1:9200","https://opensearch-c-2:9200"]') — Dashboards будет балансировать запросы между ними.

Подробности по самой схеме проксирования Dashboards через API Gateway — в разделе Настройка API Gateway. :::

к сведению

Применение всех внесенных параметров в файлы docker-compose.additional.yml, либо другие env-файлы осуществляется командой:

pamirctl start # Можно указать конкретные сервисы через пробел, в таком случае будут перезапущены только указанные сервисы.

Связанные разделы​