小九博客

  • 首页
  • 编程开发
  • 信息安全
  • 工具资源
  • 随笔
  • 在线工具
    • 在线图片水印
    • Json解析
    • JavaRuntimeExec
    • 加解密/编码工具集
  • 关于
小九博客
Hack The World!
  1. 首页
  2. 编程开发
  3. 正文

OpenSearch集群部署

2024年01月12日

OpenSearch集群部署

OpenSearch 项目是ElasticSearch 7.10.2版本的一个分支而发展来的,包括企业安全、告警、机器学习、SQL、索引状态管理等功能。OpenSearch 项目中的所有软件均采用了 Apache License 2.0 开源许可协议。

ElasticSearch中的身份验证、授权、索引管理、告警等功能是付费订阅中的功能。尽管后续开放并免费提供基本的安全认证功能,但如果需要保障更多的安全性和管理易用性,免费版本仍然不足以支撑,因此本项目选用了OpenSearch。

1.概述

本次目标是部署一个跨主机的高可用OpenSearch小集群,根据官方提供的文档,最终采用了3个OpenSearch节点,2台服务器进行部署。以下内容均根据该目标进行设计,环境信息如下:

主机IP 配置 OS 用途
192.168.1.2 8核心16G内存 Ubuntu22.04 LTS jammy 用于部署1个OpenSearch节点和1个OpenSearch面板(类Kibana)
192.168.1.3 8核心16G内存 Ubuntu22.04 LTS jammy 用于部署2个OpenSearch节点

因为涉及跨主机网络通信,根据自身技术栈选择了Docker Swarm作为了集群管理和编排工具。

3节点集群建设时,根据官方文档提供的建议主要包括以下几点:

  • 建议3节点都为数据节点
  • 建议每个索引均不是 可搜索快照(searchable snapshot index)索引
  • 建议将3节点都配置允许成为Master节点(Master-eligible node)

注:文章中可能同时出现了OpenSearch、ElasticSearch,你没有看错,这不是笔误,而是两边的文档需要同时参考,互为补充..

本文实际搭建时采用OpenSearch2.6版本。

主要参考如下版本的文档:

https://opensearch.org/docs/2.6/

https://www.elastic.co/guide/en/elasticsearch/reference/7.10/index.html

1.1 .本章概念解释及参考引用

1.1.1 Master Node/Master-eligible node概念及区别

节点具有一个或多个角色(Role),角色包括以下几种

  • master
  • data
  • data_content
  • data_hot
  • data_warm
  • data_cold
  • data_frozen
  • ingest
  • ml
  • remote_cluster_client
  • transform

当一个节点(Node)被赋予master角色时,并不代表其一定是Master主节点,而是赋予了其被选举权,也就是Master-eligible node。

如果集群只有1个节点 Role为master,那么其一定是master节点。

如果集群中有2个节点,全部设置为master,当任意节点不可用时,选举将失败,如果两个节点能够进行独立选举,失去连接会导致脑裂问题,导致数据丢失。Elasticsearch避免了这种情况来保护数据,它不选择任何一个节点作为主节点,直到该节点能够确定它拥有最新的集群状态,并且集群中没有其他主节点。这可能会导致集群没有master,直到连接恢复。

如果集群中有3个节点,全部设置为master,则集群允许单个节点丢失。

1.1.2 引用

ElasticNode概念及说明: https://www.elastic.co/guide/en/elasticsearch/reference/7.10/modules-node.html

3节点高可用集群设计: https://www.elastic.co/guide/en/elasticsearch/reference/7.10/high-availability-cluster-small-clusters.html#high-availability-cluster-design-three-nodes

脑裂问题: https://en.wikipedia.org/wiki/Split-brain_(computing)

2.安装部署

部署前解释下为什么要采用Docker Swarm,在部署OpenSearch集群时,有多个配置需要指定集群中节点的IP,以快速服务发现来实现节点通信。

但问题在于如果节点IP使用非标准端口,那么就需要在修改对应配置,特别是transport.port他的默认端口是9300-9400的范围IP。在配置环境变量时,如果对于这些端口不熟悉,很容易错误使用,特别是在第一次完成Docker部署OpenSearch后出现了9200、9300、9301、9600等端口。

为了解决以上问题,通过Docker Swarm构建一个跨主机的虚拟网络,对于每个容器便拥有了虚拟网络中的独立IP,不会出现标准端口占用问题,在配置环境变量或者OpenSearch配置时,可直接使用容器的ServiceName作为Hostname直接进行通信,而无需配置额外的端口。

2.1 Docker Swarm跨主机部署

2.1.1 修改主机名

修改主机名以用于区分不同主机

该步骤为前期部署k8s的必要操作,Docker swarm集群暂未去了解是否必须该步骤,建议修改,便于在集群管理器中方便的识别对应主机。

将主机192.168.1.2设置为db-1,主机192.168.1.3设置为db-2,在不同主机编辑/etc/hostname,重启服务器即可。

1
2
sudo vim /etc/hostname
reboot

2.1.2 创建Swarm集群

1.在主机192.168.1.2创建swarm管理节点
1
docker swarm init --advertise-addr=192.168.1.2

得到如下提示

1
2
3
4
5
6
7
8
9
Swarm initialized: current node (bvz81updecsj6wjz393c09vti) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join \
--token SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-1awxwuwd3z9j1z3puu7rcgdbx \
192.168.1.2:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

提示中出现了两个命令,docker swarm join ...和docker swarm join-token manager,区分见概念解释,默认显示的是以worker角色加入集群的命令。

1
2
3
docker swarm join \
--token SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-1awxwuwd3z9j1z3puu7rcgdbx \
192.168.1.2:2377
2.在主机192.168.1.3中执行docker swarm join 加入swarm集群。
1
2
3
docker swarm join \
--token SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-1awxwuwd3z9j1z3puu7rcgdbx \
192.168.1.2:2377
3.为节点增加标签

在编写部署文件时,可以通过标签来让服务(Service)部署在指定的节点(Docker Node)中。

1
docker node update --label-add db-node=2 un5y8qe03ehgy1i5b7ao6kk8y
1
docker node update --label-add db-node=1 fp6zni42p2iz319qihx0oek57

这样192.168.1.2的swarm node节点就有了标签db-node,值为1

192.168.1.3的swarm node节点就有了标签db-node,值为2

可通过docker inspect un5y8qe03ehgy1i5b7ao6kk8y -f "{{json .Spec.Labels}}"查看节点的标签

4.创建Swarm Overlay网络
1
docker network create --driver overlay  --attachable db-cluster

查看网络信息

1
docker network inspect db-cluster
5.编写部署compose文件

该compose文件配置了3个opensearch数据节点,自动选举主节点。将下面的完整compose文件内容保存为docker-compose-cluster.yml即可。

注⚠️:本文件禁用了安全插件和默认的参数配置,安全方面主要体现在各个节点没有密码,没有通过SSL进行通讯,并且暴露了每个节点的端口,存在安全风险,请勿在生产环境中使用!!!安全配置将在后续章节中写明!

Service下的deploy用于设置部署选项,通过标签来指定服务部署的节点。

1
2
3
deploy:
placement:
constraints: [ node.labels.db-node == 1 ]

其他字段可参考文件内的注释。

注:这里有个我认为设计不合理的地方,在部署时通过deploy的placement指定了Service部署的节点,但映射出来的端口重复判断依旧是在单机单节点来识别的,导致无法在不同的主机节点同时暴露9200端口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
version: '3.8'
services:
opensearch-data-node1:
image: opensearchproject/opensearch:2.6.0
environment:
- cluster.name=opensearch-db # 集群名称
- node.name=opensearch-data-node1 # 节点名称
- node.roles=data,ingest,master #节点角色,3节点小集群建议设置为数据节点、数据预处理节点、Master-eligible节点。
- discovery.seed_hosts=opensearch-data-node1,opensearch-data-node2,opensearch-data-node3 #通过主机名(ServiceName)进行服务发现
- cluster.initial_master_nodes=opensearch-data-node1,opensearch-data-node2,opensearch-data-node3 #初始化master节点列表,这里设置3个以让其自动选举
- bootstrap.memory_lock=true # 禁止JVM堆内存交换
- http.cors.enabled=true # 支持跨域
- http.cors.allow-origin=* # 跨域来源
- plugins.security.ssl.http.enabled=false # 禁止SSL通信
- DISABLE_INSTALL_DEMO_CONFIG=true # 禁止默认配置,如SSL证书等配置
- DISABLE_SECURITY_PLUGIN=true # 禁止安全插件
- "OPENSEARCH_JAVA_OPTS=-Xms4g -Xmx4g" # 设置Java堆内存最小值和最大值,官方建议设置为系统内存的一半。
deploy:
placement:
constraints: [ node.labels.db-node == 1 ]
ulimits:
memlock:
soft: -1 # Set memlock to unlimited (no soft or hard limit)
hard: -1
nofile:
soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536
hard: 65536
volumes:
- opensearch-node1-data:/usr/share/opensearch/data # 通过volume挂载opensearch数据
- /data/opensearch_cluster/node1.yml:/usr/share/opensearch/config/opensearch.yml # 设置默认配置
ports:
- 9200:9200
- 9300:9300
- 9600:9600
networks:
- db-cluster


opensearch-dashboards:
image: opensearchproject/opensearch-dashboards:2.6.0
ports:
- 5601:5601
environment:
OPENSEARCH_HOSTS: '["http://opensearch-data-node1:9200","http://opensearch-data-node2:9200","http://opensearch-data-node3:9200"]'
opensearch.requestHeadersWhitelist: '["securitytenant","Authorization"]'
deploy:
placement:
constraints: [ node.labels.db-node == 1 ]
networks:
- db-cluster

opensearch-data-node2:
image: opensearchproject/opensearch:2.6.0
environment:
- cluster.name=opensearch-db
- node.name=opensearch-data-node2
- node.roles=data,ingest,master
- discovery.seed_hosts=opensearch-data-node1,opensearch-data-node2,opensearch-data-node3
- cluster.initial_cluster_manager_nodes=opensearch-data-node1,opensearch-data-node2,opensearch-data-node3
- bootstrap.memory_lock=true
- http.cors.enabled=true
- http.cors.allow-origin=*
- plugins.security.ssl.http.enabled=false
- DISABLE_INSTALL_DEMO_CONFIG=true
- DISABLE_SECURITY_PLUGIN=true
- "OPENSEARCH_JAVA_OPTS=-Xms4g -Xmx4g" # Set min and max JVM heap sizes to at least 50% of system RAM
deploy:
placement:
constraints: [ node.labels.db-node == 2 ]
ulimits:
memlock:
soft: -1 # Set memlock to unlimited (no soft or hard limit)
hard: -1
nofile:
soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536
hard: 65536
volumes:
- opensearch-node2-data:/usr/share/opensearch/data
- /data/opensearch_cluster/node2.yml:/usr/share/opensearch/config/opensearch.yml
ports:
- 10200:9200 # REST API
- 10300:9300 # Cluster Node
- 10600:9600 # Performance Analyzer
networks:
- db-cluster

opensearch-data-node3:
image: opensearchproject/opensearch:2.6.0
environment:
- cluster.name=opensearch-db
- node.name=opensearch-data-node3
- node.roles=data,ingest,master
- discovery.seed_hosts=opensearch-data-node1,opensearch-data-node2,opensearch-data-node3
- cluster.initial_cluster_manager_nodes=opensearch-data-node1,opensearch-data-node2,opensearch-data-node3
- bootstrap.memory_lock=true
- http.cors.enabled=true
- http.cors.allow-origin=*
- plugins.security.ssl.http.enabled=false
- DISABLE_INSTALL_DEMO_CONFIG=true
- DISABLE_SECURITY_PLUGIN=true
- "OPENSEARCH_JAVA_OPTS=-Xms4g -Xmx4g"
deploy:
placement:
constraints: [ node.labels.db-node == 2 ]
ports:
- 9400:9200 # REST API
- 9500:9300 # Cluster Node
- 9800:9600 # Performance Analyzer
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- opensearch-node3-data:/usr/share/opensearch/data
- /data/opensearch_cluster/node3.yml:/usr/share/opensearch/config/opensearch.yml
networks:
- db-cluster


volumes:
opensearch-node1-data:
opensearch-node2-data:
opensearch-node3-data:

# 使用已经创建好的网络
networks:
db-cluster:
external: true

6.编写每个节点的配置文件

复制以下内容到node1.yml、node2.yml、node3.yml,

1
2
3
4
5
6
7
cluster.name: opensearch-db
network.host: 0.0.0.0
network.publish_host: opensearch-data-node1
http.publish_host: opensearch-data-node1
transport.publish_host: opensearch-data-node1

compatibility.override_main_response_version: true

将node2.yml中所有的opensearch-data-node1字符替换为opensearch-data-node2

将node3.yml中所有的opensearch-data-node1字符替换为opensearch-data-node3

节点配置和服务名称(ServiceName)保持一致即可,这个步骤必不可少!。

实测如果缺少三个publish_host配置,OpenSearch会在选举时识别到错误的IP,导致选举失败,进而无法启动集群。

compatibility.override_main_response_version 配置为true表示版本号返回兼容模式,对于OpenSearch2.6将返回7.10版本

后续需要将node1.yml、node2.yml、node3.yml按照部署的对应关系分别放到192.168.1.2和192.168.1.3主机的/data/opensearch_cluster目录。

7.集群启动、查看

完成以上步骤便可在compose文件所在目录,执行以下命令启动集群。

1
docker stack deploy -c docker-compose-cluster.yml db-cluster

执行完成,可看到输出信息为

1
2
3
4
Creating service db-cluster_opensearch-data-node3
Creating service db-cluster_opensearch-data-node1
Creating service db-cluster_opensearch-dashboards
Creating service db-cluster_opensearch-data-node2

查看所有的任务(Task)

1
2
# docker stack ps <集群名称>
docker stack ps db-cluster

输出信息

1
2
3
4
5
ID             NAME                                  IMAGE                                           NODE       DESIRED STATE   CURRENT STATE           ERROR     PORTS
j70p5arth4jl db-cluster_opensearch-dashboards.1 opensearchproject/opensearch-dashboards:2.6.0 db-1 Running Running 4 minutes ago
p9yu6h5yokyu db-cluster_opensearch-data-node1.1 opensearchproject/opensearch:2.6.0 db-1 Running Running 4 minutes ago
ad7o1clcr7wi db-cluster_opensearch-data-node2.1 opensearchproject/opensearch:2.6.0 db-2 Running Running 3 minutes ago
dikndljx5x2t db-cluster_opensearch-data-node3.1 opensearchproject/opensearch:2.6.0 db-2 Running Running 4 minutes ago

查看所有Service信息

1
2
# docker stack services <集群名称>
docker stack services db-cluster

输出信息

1
2
3
4
5
ID             NAME                                MODE         REPLICAS   IMAGE                                           PORTS
p6gzkh96c24r db-cluster_opensearch-dashboards replicated 1/1 opensearchproject/opensearch-dashboards:2.6.0 *:5601->5601/tcp
05pzy1h9lm0l db-cluster_opensearch-data-node1 replicated 1/1 opensearchproject/opensearch:2.6.0 *:9200->9200/tcp, *:9300->9300/tcp, *:9600->9600/tcp
i9l86hr5ccnm db-cluster_opensearch-data-node2 replicated 1/1 opensearchproject/opensearch:2.6.0 *:10200->9200/tcp, *:10300->9300/tcp, *:10600->9600/tcp
ybh9x23mgz9v db-cluster_opensearch-data-node3 replicated 1/1 opensearchproject/opensearch:2.6.0 *:9400->9200/tcp, *:9500->9300/tcp, *:9800->9600/tcp

最后确认下OpenSearch集群状态和OpenSearch节点状态。

前面9200部署给了主机192.168.1.2,因此访问http://192.168.1.2:9200/_cluster/health?pretty

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"cluster_name": "db-cluster",
"status": "green",
"timed_out": false,
"number_of_nodes": 3,
"number_of_data_nodes": 3,
"discovered_master": true,
"discovered_cluster_manager": true,
"active_primary_shards": 2,
"active_shards": 5,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0,
"delayed_unassigned_shards": 0,
"number_of_pending_tasks": 0,
"number_of_in_flight_fetch": 0,
"task_max_waiting_in_queue_millis": 0,
"active_shards_percent_as_number": 100.0
}

节点信息访问http://192.168.1.2:9200/_cat/nodes?v

1
2
3
4
ip        heap.percent ram.percent cpu load_1m load_5m load_15m node.role node.roles         cluster_manager name
10.0.4.10 6 95 4 1.71 1.26 0.69 dim data,ingest,master - opensearch-data-node2
10.0.4.2 7 95 4 1.71 1.26 0.69 dim data,ingest,master * opensearch-data-node3
10.0.4.5 3 76 4 0.06 0.09 0.09 dim data,ingest,master - opensearch-data-node1

可以看到集群状态为绿色,显示拥有3个节点,同时opensearch-data-node3被选为了集群的Master节点

大功告成!

2.1.3 集群删除

集群删除时涉及Service、网络、数据卷(Volume)的删除。

Service 可执行如下命令来删除集群以及集群下的所有服务

1
docker stack rm db-cluster

因为网络是单独创建的,没有通过compose文件,因此需要手动删除,在192.168.1.2和192.168.1.3两台主机分别执行

1
docker network rm db-cluster

如果在compose里面创建网络,在删除Service时会同步删除该网络。

数据卷在192.168.1.2和192.168.1.3两台主机中,需要根据Service部署的情况,在对应主机删除对应的volume,执行命令为

1
2
3
docker volume rm db-cluster_opensearch-node1-data
docker volume rm db-cluster_opensearch-node2-data
docker volume rm db-cluster_opensearch-node3-data

2.2 本章概念解释

2.2.1 Swarm中的worker和manager角色

Manager节点还执行维护集群所需状态所需的编排和集群管理功能。Manager节点会选择一个领导者Leader来执行编排任务。

Worker节点接收并执行从Manager节点分派的任务。默认情况下,Manager节点也将服务作为Worker节点运行,但您可以将它们配置为专门运行Manager任务并成为仅Manager节点(manager-only nodes)。Agent在每个工作节点上运行并报告分配给它的任务。工作节点将其分配任务的当前状态通知Manager节点,以便Manager节点可以维护每个Worker节点的所需状态。

如果要查看manager角色token或者manager角色 token遗忘时,可执行

1
docker swarm join-token manager

如果忘记worker角色token可执行

1
docker swarm join-token worker

如果节点以worker角色加入,想提升worker角色为manager角色的话,可以在管理节点执行如下命令

1
2
# docker node promote <hostname>
docker node promote db-2

如果节点以manager角色加入,移除该节点时必须将其降级为worker角色,可以在管理节点执行如下命令

1
2
# docker node demote <hostname>
docker node demote db-2

2.2.2 常用命令

Docker 网络

1
2
3
4
5
6
# 查看docker网络列表
docker network ls
# 删除docker网络
docker network rm db-cluster
# 查看网络详情
docker inspect db-cluster

Docker Volume存储卷

1
2
3
4
# 查看volume列表
docker volume ls
# 删除volume卷
docker volume rm db-cluster_opensearch-node2-data

2.2.3 引用

docker swarm 关键概念: https://docs.docker.com/engine/swarm/key-concepts/

docker swarm 初始化: https://docs.docker.com/engine/reference/commandline/swarm_init/

ElasticSearch 网络: https://www.elastic.co/guide/en/elasticsearch/reference/7.10/modules-network.html

3.致谢

特别感谢提供各类教程和文档的站点以及协助排查问题的朋友,尤其是 @x 7% 在关键坑publish_host提供了有效思路和相关文档链接。

OpenSearch 官方

Creating a cluster - OpenSearch documentation

https://opensearch.org/docs/2.6/

https://raw.githubusercontent.com/opensearch-project/documentation-website/2.6/assets/examples/docker-compose.yml

ElasticSearch 官方

https://www.elastic.co/guide/en/elasticsearch/reference/7.10/index.html

Elastic开源社区

https://blog.csdn.net/wlei0618/article/details/127371710

面圈网

架构原理-ELK Stack 中文指南-面试哥 (mianshigee.com)

OpenAI ChatGpt3.5 & 4

标签 OpenSearch Cluster DockerSwarm
最后更新:2024年01月12日

文章评论

小九

Just For Fun

文章大纲
  1. OpenSearch集群部署
    1. 1.概述
      1. 1.1 .本章概念解释及参考引用
        1. 1.1.1 Master Node/Master-eligible node概念及区别
        2. 1.1.2 引用
    2. 2.安装部署
      1. 2.1 Docker Swarm跨主机部署
        1. 2.1.1 修改主机名
        2. 2.1.2 创建Swarm集群
          1. 1.在主机192.168.1.2创建swarm管理节点
          2. 2.在主机192.168.1.3中执行docker swarm join 加入swarm集群。
          3. 3.为节点增加标签
          4. 4.创建Swarm Overlay网络
          5. 5.编写部署compose文件
          6. 6.编写每个节点的配置文件
          7. 7.集群启动、查看
        3. 2.1.3 集群删除
      2. 2.2 本章概念解释
        1. 2.2.1 Swarm中的worker和manager角色
        2. 2.2.2 常用命令
        3. 2.2.3 引用
    3. 3.致谢
分类目录
  • 编程开发
  • Yii2
  • 随笔
  • 工具资源
  • Django
  • 信息安全
标签聚合
dnspod workflow yii2事件 MariaDB mysql+es Hexo
随机 最新 热点
随机 最新 热点
Yii2 Event事件-初识 Git仓库同步附脚本 PHP反射机制 PHP-GD库漏洞可导致服务器宕机 免费CDN加速手把手教程 常见容器漏洞总结
OpenSearch集群部署 DNSRebind攻击 MySQL数据同步到ElasticSearch(Logstash方案)爬坑纪实 自动化编排学习(一)部署篇 常见容器漏洞总结 免费CDN加速手把手教程

COPYRIGHT © 2021 小九博客 ALL RIGHTS RESERVED.