Рекомендации по кластеризации и повышению отказоустойчивости Консоли управления¶
В статье описаны подходы для повышения отказоустойчивости решения путем репликации базы данных MongoDB, кластеризации бэкенд-сервисов и настройки балансировщика нагрузки.
Шаг 1. Настройка репликации MongoDB¶
MongoDB является основным компонентом системы. Для обеспечения бесперебойной работы настройте кластер из трех нод в виде replica set.
-
Создайте на хостовой машине директорию и файл ключей для безопасного взаимодействия нод кластера:
mkdir ./keyfile-volume openssl rand -base64 756 > ./keyfile-volume/mongodb-keyfile -
Добавьте в файл docker-compose.yml два дополнительных сервиса для реплик MongoDB:
# Новые сервисы для реплик mongo-replica-1: image: mongo:8.0.5 container_name: api-fw-mongo-replica-1 restart: unless-stopped networks: - api-firewall-manager-network environment: MONGO_INITDB_ROOT_USERNAME: ${MONGO_LOGIN} MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWD} MONGO_INITDB_DATABASE: ${MONGO_INITDB} volumes: - ./keyfile-volume:/opt/mongo - ./mongo-data-replica-1:/data/db - ./mongo-config-replica-1:/data/configdb command: mongod --bind_ip_all --replSet rs0 --auth --keyFile /opt/mongo/mongodb-keyfile healthcheck: test: ["CMD", "mongosh", "--eval", "db.runCommand('ping').ok"] interval: 10s timeout: 5s retries: 5 start_period: 10s mongo-replica-2: image: mongo:8.0.5 container_name: api-fw-mongo-replica-2 restart: unless-stopped networks: - api-firewall-manager-network environment: MONGO_INITDB_ROOT_USERNAME: ${MONGO_LOGIN} MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWD} MONGO_INITDB_DATABASE: ${MONGO_INITDB} volumes: - ./keyfile-volume:/opt/mongo - ./mongo-data-replica-2:/data/db - ./mongo-config-replica-2:/data/configdb command: mongod --bind_ip_all --replSet rs0 --auth --keyFile /opt/mongo/mongodb-keyfile healthcheck: test: ["CMD", "mongosh", "--eval", "db.runCommand('ping').ok"] interval: 10s timeout: 5s retries: 5 start_period: 10s -
Настройте сервис инициализации
mongo-initдля автоматического добавления всех нод вreplica set:
-
Добавьте в секцию
depends_onзависимости с условиемservice_healthyдля всех сервисов MongoDB. -
Модифицируйте команду
rs.initiate(), указав в конфигурации имена всех трех сервисов ( например,api-fw-mongo,api-fw-mongo-replica-1иapi-fw-mongo-replica-2) в качестве хостов.mongo-init: image: mongo:8.0.5 networks: - api-firewall-manager-network volumes: - ./keyfile-volume:/opt/mongo depends_on: mongo: condition: service_healthy mongo-replica-1: condition: service_healthy mongo-replica-2: condition: service_healthy command: > mongosh "mongodb://${MONGO_LOGIN}:${MONGO_PASSWD}@api-fw-mongo:27017/?authSource=admin" --eval ' try { const status = rs.initiate({ _id: "rs0", members: [ { _id: 0, host: "api-fw-mongo:27017" }, { _id: 1, host: "api-fw-mongo-replica-1:27017" }, { _id: 2, host: "api-fw-mongo-replica-2:27017" } ] }); printjson(status); } catch (e) { if (e.codeName === "AlreadyInitialized") { print("Replica set is already initialized, skipping."); } else { printjson(e); throw e; } }' restart: "no"
-
Для сервисов
migrationsиmanager_backendизмените строку подключения к базе данных:migrations: ... environment: MONGO_URI: mongodb://apifw:${MONGO_PASSWD}@api-fw-mongo:27017,api-fw-mongo-replica-1:27017,api-fw-mongo-replica-2:27017/?replicaSet=rs0 manager_backend: ... environment: MONGO_URI: mongodb://apifw:${MONGO_PASSWD}@api-fw-mongo:27017,api-fw-mongo-replica-1:27017,api-fw-mongo-replica-2:27017/?replicaSet=rs0 ...
Шаг 2. Масштабирование сервиса manager_backend¶
-
Добавьте второй экземпляр сервиса
manager_backend: в файлеdocker-compose.ymlпродублируйте сервисmanager_backend(например, назовите егоmanager_backend_2). Во избежание конфликтов портов замените параметрportsнаexposeдля обоих экземпляровmanager_backend. Это откроет порты только внутри Docker-сети, а не на хост-машине.manager_backend_1: container_name: api-fw-manager-1 image: registry.webmonitorx.ru/api-firewall/apifw-manager:1.2.4 # grpc для безопасного соединения c ПроAPI Защита # volumes: # - ./gen_grpc_cert/server-cert.pem:/etc/ssl/certs/grpc-server-cert.pem # - ./gen_grpc_cert/server-key.pem:/etc/ssl/certs/grpc-server-key.pem environment: MONGO_URI: mongodb://${MONGO_LOGIN}:${MONGO_PASSWD}@api-fw-mongo:27017,api-fw-mongo-replica-1:27017,api-fw-mongo-replica-2:27017/?replicaSet=rs0 URL_MANAGER: ${URL_MANAGER} LICENSE_KEY: ${LICENSE_KEY} SET_REAL_IP_FROM: "0.0.0.0/0" NODES_DELETED_AFTER: "72h" # Удалять неактивные ноды через заданное время EVENTS_DELETED_AFTER: "720h" # Удалять события старше # GRPC_SERVER_CERT_FILE: /etc/ssl/certs/grpc-server-cert.pem # Путь до файла сертификата для настройки защищенного gRPC соединения Manager<>Node # GRPC_SERVER_KEY_FILE: /etc/ssl/certs/grpc-server-key.pem # Путь до файла закрытого ключа сертификата expose: - "8081" - "8082" depends_on: migrations: condition: service_completed_successfully mongo: condition: service_healthy networks: - api-firewall-manager-network manager_backend_2: container_name: api-fw-manager-2 image: registry.webmonitorx.ru/api-firewall/apifw-manager:1.2.4 # grpc для безопасного соединения c ПроAPI Защита # volumes: # - ./gen_grpc_cert/server-cert.pem:/etc/ssl/certs/grpc-server-cert.pem # - ./gen_grpc_cert/server-key.pem:/etc/ssl/certs/grpc-server-key.pem environment: MONGO_URI: mongodb://${MONGO_LOGIN}:${MONGO_PASSWD}@api-fw-mongo:27017,api-fw-mongo-replica-1:27017,api-fw-mongo-replica-2:27017/?replicaSet=rs0 URL_MANAGER: ${URL_MANAGER} LICENSE_KEY: ${LICENSE_KEY} SET_REAL_IP_FROM: "0.0.0.0/0" NODES_DELETED_AFTER: "72h" # Удалять неактивные ноды через заданное время EVENTS_DELETED_AFTER: "720h" # Удалять события старше # GRPC_SERVER_CERT_FILE: /etc/ssl/certs/grpc-server-cert.pem # Путь до файла сертификата для настройки защищенного gRPC соединения Manager<>Node # GRPC_SERVER_KEY_FILE: /etc/ssl/certs/grpc-server-key.pem # Путь до файла закрытого ключа сертификата expose: - "8081" - "8082" depends_on: migrations: condition: service_completed_successfully mongo: condition: service_healthy networks: - api-firewall-manager-network -
Настройте балансировщик нагрузки: добавьте в
docker-compose.ymlсервисnginx_lb, который будет распределять входящие запросы между двумя экземплярамиmanager_backend.
nginx_lb: image: nginx:latest container_name: api-fw-loadbalancer volumes: - ./files/nginx/balancer.conf:/etc/nginx/conf.d/balancer.conf # Файл конфигурации Nginx ports: - "8081:8081" - "8082:80" networks: - api-firewall-manager-network depends_on: - manager_backend_1 - manager_backend_2
upstream manager_backend_group { server api-fw-manager-1:8082 max_fails=3 fail_timeout=30s; server api-fw-manager-2:8082 max_fails=3 fail_timeout=30s; } server { listen 80; server_name _; location /api/ { # Проксирование трафика на группу бэкендов proxy_pass http://manager_backend_group/api/; # Стандартные заголовки proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } upstream manager_backend_grpc_group { server api-fw-manager-1:8081; server api-fw-manager-2:8081; } server { listen 8081 http2; server_name _; location / { # Проксирование на gRPC grpc_pass grpc://manager_backend_grpc_group; # Рекомендуемые заголовки для gRPC proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
Шаг 3. Настройка сервиса Manager UI¶
-
В сервисе manager_ui измените переменную окружения
API_BACKEND_URL. Теперь она должна указывать на адрес балансировщикаnginx_lb, а не на прямой адрес бэкенда.
manager_ui: container_name: manager_ui image: registry.webmonitorx.ru/api-firewall/apifw-manager-ui:1.2.2 volumes: - ./files/nginx/default.conf:/etc/nginx/conf.d/default.conf # Конфигурационный файл внутреннеего nginx-сервера - ./files/ssl/fullchain.pem:/etc/ssl/fullchain.pem # Сертификат для HTTPS - ./files/ssl/privkey.pem:/etc/ssl/privkey.pem # Сертификат для HTTPS - ./ssl/ssl-dhparams.pem:/etc/ssl/ssl-dhparams.pem # Сертификат для HTTPS environment: API_BASE_URL: ${API_BASE_URL} API_BACKEND_URL: http://api-fw-loadbalancer:80/api/ ports: - "8088:8088" - "443:443" networks: - api-firewall-manager-network depends_on: - manager_backend_1 - manager_backend_2 - nginx_lb -
Обновите монтируемый конфигурационный файл
default.confдляmanager_ui. В секцииlocation /apiукажите в качествеupstreamсервисnginx_lb.
location /api { proxy_pass http://api-fw-loadbalancer:80/api; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
Шаг 4. Настройка фильтрующих нод и отказоустойчивости (failover)¶
-
Запустите две фильтрующие ноды на разных портах.
-
Сконфигурируйте Angie/NGINX для проксирования трафика на ноды фильтрации.
# Группа апстрим для нескольких нод upstream apifw_node_group { server 172.17.0.3:8093; server 172.17.0.5:8094 backup; } server { listen 8443 ssl; listen [::]:8443 ssl; server_name домен_приложения; ssl_certificate /etc/angie/ssl/fullchain.pem; ssl_certificate_key /etc/angie/ssl/privkey.pem; # Проксирование API location /api/ { proxy_pass http://apifw_node_group/; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Authorization $http_authorization; proxy_connect_timeout 75s; proxy_send_timeout 75s; proxy_read_timeout 75s; }