集群安全

  1. 启用安全策略

(1)     验证版本是否支持

①      Elasticsearch的安全策略需要X-Pack插件的支持,不过对于7.X以上版本X-Pack已经内置,所以不需要额外的操作。

②      官方说明:

1)      https://www.elastic.co/cn/subscriptions

2)      许可配置:https://www.elastic.co/guide/en/kibana/7.6/managing-licenses.html

③      7.1以后安全功能免费,但是不包括单点登录、LDAP身份认证以及字段和文档级安全选项。

④      6.8之前,需要手动安装x-pack:

1)      bin/kibana-plugin install x-pack

2)      bin/elasticsearch-plugin install x-pack

(2)     打开安全配置选项(xpack.security.enabled):免费版本(基础版或者使用许可证)默认false,需要我们手动打开xpack.security.enabled=true,黄金VIP以上版本默认开启,但是建议仍然手动显式设置开启。

①      [1] bootstrap checks failed

②      [1]: Transport SSL must be enabled if security is enabled on a [basic] license. Please set [xpack.security.transport.ssl.enabled] to [true] or disable security by setting [xpack.security.enabled] to [false]

(3)     节点通讯安全性:未启用加密的群集将以纯文本格式(包括密码)发送所有数据。如果启用了Elasticsearch安全功能,除非您具有试用许可证,否则必须配置SSL / TLS进行节点间通信:

①      确认xpack.security.enabled设置为true

②      生成节点证书:TLS需要X.509证书才能对与之通信的应用程序执行加密和身份验证。为了使节点之间的通信真正安全,必须对证书进行验证。在Elasticsearch集群中验证证书真实性的推荐方法是信任签署证书的证书颁发机构(CA)。这样,将节点添加到群集时,它们只需要使用由同一CA签名的证书,即可自动允许该节点加入群集。此外,建议证书包含与节点的IP地址和DNS名称相对应的主题备用名称(SAN),以便可以执行主机名验证。

1)      为Elasticsearch集群创建证书颁发机构:您可以配置集群来信任所有拥有证书的节点,这些证书是由这个ca签署的。此文件是PKCS#12密钥存储库,其中包含您的CA的公共证书和用于为每个节点签署证书的私钥。elasticsearch-certutil命令还提示您输入密码以保护文件和密钥。如果您计划将来在集群中添加更多节点,请保留该文件的副本并记住其密码。

bin/elasticsearch-certutil ca

生成的 .p12包含CA的公共证书和用于对每个节点的证书签名的私钥。生成过程中  设置的密码在日后集群的横向扩容中需要用到,因此需要牢记。

2)      为集群中每个节点生成私钥及证书:

bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12

生成的 .p12文件包含了节点证书、节点密钥和CA证书。这个密码可以直接Enter   设置为空。节点证书默认不包含主机信息,所以每个节点都可以用此证书,但是节点  必须关闭主机认证。

3)      把节点证书复制到对应位置:需要将节点证书拷贝至config目录下

③      配置每个节点启用TLS:Transport层必须配置,HTTP层非必须,但是建议最好配置。

xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12

④      重启集群

⑤      其他通讯加密:

1)      Kibana

2)      Logstash

3)      Beats

4)      Java

5)      Hadoop

(4)     设置用户名和密码:

bin/elasticsearch-setup-passwords interactive

elasticsearch-setup-passwords使用引导密码,使用一次后失效,并且当前命令也不可再次使用。

①      Elasticsearch内置账户:

1)      elastic:Elastic内置超级用户

2)      apm_system:APM服务器在Elasticsearch中存储监视信息时使用的账户。

3)      kibana:kibana连接elasticsearch的账户。

4)      logstash_system:Logstash讲采集的日志输出到Elasticsearch时使用的账户。

5)      beats_system:beats在存储数据输出到Elasticsearch时使用的账户。

6)      remote_monitoring_user:Metricbeat用户在Elasticsearch中收集和存储监视信息时使用

②      内置账户信息:

1)      内置账户存储在.security索引中,由Elasticsearch统一管理。

(5)     修改密码:

curl -H "Content-Type:application/json" -XPOST -u kibana 'http://172.16.10.184:9200/_xpack/security/user/elastic/_password' -d '{ "password" : "123456" }'

(6)     关于Head插件登录问题:

①      master节点增加配置:http.cors.allow-headers: "Authorization,X-Requested-With,Content-Length,Content-Type"

②      host/?auth_user=elastic&auth_password=my_pwd

(7)     Logstash和Beats增加需在配置文件中修改。

  1. ES集群调优:

(1)     慢日志:分片级的,针对于data_node。

①      现象:

1)      连接大量被拒绝

2)      CPU居高不下

3)      查询超时

②      原因:

1)      软件配置不合理

2)      硬件资源不够

③      配置:

1)      慢查询

  1. 配置
index.search.slowlog.threshold.query.warn: 10s
index.search.slowlog.threshold.query.info: 5s
index.search.slowlog.threshold.query.debug: 2s
index.search.slowlog.threshold.query.trace: 500ms
index.search.slowlog.threshold.fetch.warn: 1s
index.search.slowlog.threshold.fetch.info: 800ms
index.search.slowlog.threshold.fetch.debug: 500ms
index.search.slowlog.threshold.fetch.trace: 200ms
index.search.slowlog.level: info
1. setting
PUT /index/_settings
{
    "index.search.slowlog.threshold.query.warn": "10s",
    "index.search.slowlog.threshold.query.info": "5s",
    "index.search.slowlog.threshold.query.debug": "2s",
    "index.search.slowlog.threshold.query.trace": "500ms",
    "index.search.slowlog.threshold.fetch.warn": "1s",
    "index.search.slowlog.threshold.fetch.info": "800ms",
    "index.search.slowlog.threshold.fetch.debug": "500ms",
    "index.search.slowlog.threshold.fetch.trace": "200ms",
    "index.search.slowlog.level": "info"
}

2)      慢写入

index.indexing.slowlog.threshold.index.warn: 10s
index.indexing.slowlog.threshold.index.info: 5s
index.indexing.slowlog.threshold.index.debug: 2s
index.indexing.slowlog.threshold.index.trace: 500ms
index.indexing.slowlog.level: info
index.indexing.slowlog.source: 1000

(2)     优化建议:

①      搜索:

1)      减小page size:搜索结果不要返回过大的结果集,每页搜索数量控制在1000以内。

2)      避免deeping:如果需要深度分页,建议使用scroll search,如果一定要使用深查询,考虑使用search after,下面是讲解:https://www.elastic.co/guide/en/elasticsearch/reference/7.7/search-request-body.html#request-body-search-search-after

3)      聚合查询避免过多分桶:对于桶数过多的聚合,应将数据切片:比如按时间、按地理位置等分词请求。

4)      能用filter的不要使用query。

5)      避免过多agg嵌套。

6)      尽量避免使用fuzzy、前缀和正则,可以使用suggest做模糊搜索。

②      写入优化:

1)      用bulk批量写入

2)      使用多线程将数据写入ES

3)      大量数据一次性写入: 如果我们需要一次性写入大量数据,可以先禁止refresh和replia复制,将index.refresh_interval设置为-1,将index.number_of_replicas设置为0。但是ES不需要创建segment file文件了,replica数据也不需要互相同步了。此时写入的速度会非常快,我们可以等数据写入完成之后,再把他们设置回来。

4)      增加buffer缓冲区大小:indices.memory.index_buffer_size,一般来说indices.memory.index_buffer_size/total_shards< jvm heap的10%,增大buffer的大小可以大大提高写入速度。

5)      把更多内存留给OS Cache:可能有人认为应该把Jvm heap调大会增加性能,这都是想当然的操作,我们不仅不应该增大Jvm heap,反而应该把更多内存留给OS Cache,因为Lucene底层的读写都是基于OS cache的,需要大量的内存。

③      数据结构:

1)      尽量使用手工mapping,尽量手动指定string字段类型。

2)      避免稀疏数据结构:会产生磁盘浪费,同时降低读写性能。

3)      避免将没有任何关联性的数据写入同一个索引。

4)      检索和聚合解耦:避免把大量用于检索的数据和用于聚合的数据放在同一个index。

5)      仅用于检索的字段关闭doc value,仅用于聚合的字段关闭index。

6)      避免使用filelddata。

7)      禁用norms:对于不需要参与评分的字段,可设置false,常见的比如filter和agg字段。

8)      禁用 index_options.

9)      禁用 _all field

10)    source和store分离(高级玩法,可节省带宽)。

11)    使用最小的数据类型:能用short的不要用long,这一点在ES里更为重要。

12)    scripting查询参数化:script脚本会触发编译行为,并且会产生缓存,使用不当会造成查询巨慢,还会造成OOM。

13)    Id:对于某些id字段,不需要我们做全文检索,使用keyword比数字类型性能更好

14)    尽量避免使用nested和parent/child:能在mapping阶段搞定的,尽量在mapping阶段搞定。

15)    避免自定义id。

16)    业务框架解耦:避免业务对ES过多的功能依赖,ES本身是一个搜索、存储、分析引擎,尽量把功能依赖放在这三个点上,有些功能虽然ES提供了,但是我们能用其他方案取代就用其他方案,这样留出更多资源让ES专注于搜索和聚合。即便ES提供的解决方案可能更好,但是代价却是占用了主要功能的资源。比如智能推荐、模糊查询等。

④      集群:

1)      冷热分离:高频数据使用性能更好的硬件,HDD<SSD<RAM

2)      单一职责:关闭master节点的data-node设置(如果是开启状态的话),数据节点和Master节点一定要分开,集群规模越大,这样做的意义也就越大。

3)      增加协调节点的数量:稳定的Master节点对于群集健康非常重要!理论上讲,应该尽可能的减轻Master节点的压力,分片数量越多,Master节点维护管理shard的任务越重,并且节点可能就要承担更多的数据转发任务,可增加“仅协调”节点来缓解Master节点和Data节点的压力,但是在集群中添加过多的仅协调节点会增加整个集群的负担,因为选择的主节点必须等待每个节点的集群状态更新确认。

4)      高可用性(HA)群集至少需要三个主节点,其中至少两个不是仅投票节点。即使其中一个节点发生故障,这样的群集也将能够选举一个主节点。生产环境最好设置3台仅Master候选节点(node.master = true  node.data = false)

5)      为确保群集仍然可用,集群不能同时停止投票配置中的一半或更多节点。只要有一半以上的投票节点可用,群集仍可以正常工作。这意味着,如果存在三个或四个候选节点,则群集可以容忍其中一个节点不可用。如果有两个或更少的主机资格节点,则它们必须都保持可用

6)      禁用swapping:swapping会大大降低性能。

⑤      索引:

1)      控制分片数量:每台节点的Shard数量越少,每个shard分配的CPU、内存和IO资源越多,单个Shard的性能越好,当一台机器一个Shard时,单个Shard性能最好。分片越少,分页查询越快。如果相同资源分配相同的前提下,shard数量越少,单个shard的体积越大,查询性能越低,速度越慢,这个取舍应根据实际集群状况和结合应用场景等因素综合考虑。单个分片不要太大尽量不要超过20-40G(不是绝对)

2)      搜索日志:统计高频词汇,对于命中率极高的关键词添加应用层缓存。

3)      冷热分离:把冷热数据放在不同索引。

⑥      硬件:

1)      全能型:数据节点处理与数据相关的操作,例如CRUD,搜索和聚合。这些操作是I / O,内存和CPU密集型的,所以他们需要更高配置的服务器以及更高的带宽,并且集群的性能冗余非常重要。

2)      带宽:由于仅投票节不参与Master竞选,所以和真正的Master节点相比,它需要的内存和CPU较少。但是,所有候选节点以及仅投票节点都可能是数据节点,所以他们都需要快速稳定低延迟的网络。

(3)     监控

①      ELK

②      熔断

  1. 总 分 实战

技术改变一切