Week04总结

1. 文档学习

本周阅读了 Analyzer API、ingest API、Modules 三个章节,以及 xpack 的配置 https 访问部分,重点内容如下:

  • 内置分词器,以及自定义分词器;
  • ingest 数据处理;
  • shard allocationcluster allocaiton
  • 跨集群检索 cross-cluster search
  • xpack 角色配置、https 配置

2. Analyzer 总结

分词器是对一串语句进行词语分割处理的组件,它由三个部分组成:

  • char_filter(针对原始文本处理,如去掉某些符号、处理 html 等)
  • tokenizer按照规则,将上一步处理后的语句切分为单词
  • token filter 将切分后的单词进行加工(如转为小写、去除停用词增加同义词等等)

分词的流程也是严格按照 char_filter ---> tokenizer ----> filter 这样的顺序进行的。

分词测试 API

1
2
3
4
5
6
7
8
9
10
11
12
POST _analyze
{
"analyzer": "whitespace",
"text": "The quick brown fox."
}

POST _analyze
{
"tokenizer": "standard",
"filter": [ "lowercase", "asciifolding" ],
"text": "Is this déja vu?"
}

2.1 内置分词器

  • standard ,默认分词器,按词切分,小写处理;
  • simple,按照非字母切分,小写处理,dog's 会被拆分为 dogs
  • stop,小写处理,过滤停用词 theais 等,dog's 会被拆分为 dogs
  • whitespace,按空格拆分,不做小写处理;
  • keyword,不分词;
  • pattern,正则分词,例如自定义通过逗号切分;
  • language,常见语言分词,例如 english
  • fingerprint,没看懂

2.2 常用内置 tokenizer

  • standard 按词切分,保留数字;letter 按非字母拆分,不保留数字
  • lowercaseletter 类型,新增加了转小写操作;whitespace 按空格拆分;
  • uax_url_emailstandard 类似,增加了识别邮箱和 url 等数据;
  • NGram Tokenizer,滑动窗口分词,分词长度介于 min_grammax_gram 之间。
  • Keyword Tokenizer
  • Pattern Tokenizer 正则分割
  • Path Hierarchy Tokenizer路径切割
1
2
3
4
5
6
7
POST _analyze
{
"tokenizer": "path_hierarchy",
"text": "/one/two/three"
}
-------result--------
[ /one, /one/two, /one/two/three ]

2.3 常用内置 token filter

asciifolding

ASCII 过滤器,去除不在 ASCII 中的特殊标点符号,保留大小写,示例:

1
2
3
4
5
6
POST _analyze
{
"tokenizer": "standard",
"filter": ["asciifolding"],
"text": "Is This-<déja v'u"
}

length

分词长度过滤器。只保留长度介于 minmax 之间的 token

1
2
3
4
5
6
POST _analyze
{
"tokenizer": "standard",
"filter": [{"type": "length", "min":1, "max":3 }],
"text": "Is This-<déja v'u"
}

lowercase

将分词统一转为小写

1
2
3
4
5
6
POST _analyze
{
"tokenizer": "standard",
"filter": ["lowercase"],
"text": "Is This-<déja v'u"
}

uppercase

将分词统一转为大写

1
2
3
4
5
6
POST _analyze
{
"tokenizer": "standard",
"filter": ["lowercase"],
"text": "Is This-<déja v'u"
}

ngram

对分词结果进行再拆分,然后保留长度介于 min_grammax_gram 之间的词

1
2
3
4
5
6
POST _analyze
{
"tokenizer": "standard",
"filter": [{"type": "ngram", "min_gram":3, "max_gram":4 }],
"text": "Is This-<déja v'u"
}

shingle

将分词结果进行单词组装并保留原分词结果。例如[We ,love ,apple] => [We ,love ,apple, We love , love apple]

1
2
3
4
5
6
POST _analyze
{
"tokenizer": "standard",
"filter": [{"type": "shingle", "min_shingle_size":2 }],
"text": "Is This-<déja v'u"
}

stop

过滤停用词,支持 stopwordsstopwords_path

word_delimiter

将分词结果再次按照 “下划线”、“横线” 等分隔符进行拆分

1
2
3
4
5
6
POST _analyze
{
"tokenizer": "whitespace",
"filter": ["word_delimiter"],
"text": "Is this-<déja v'u?"
}

multiplexer

在分词的相同 position 执行多个 filter,如果处理后的词和原词相同。则移除掉。否则保留原词和新词

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST _analyze
{
"tokenizer": "whitespace",
"filter": [
{
"type": "multiplexer",
"filters": [
"lowercase"
]
}
],
"text": "Is This-<déja v'u"
}
------result-------
[Is(is),This-<déja(this-<déja),v'u]

condition

条件过滤,下面的例子表示将长度小于 5 的词转为小写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST _analyze
{
"tokenizer": "whitespace",
"filter": [
{
"type": "condition",
"filter": [
"lowercase"
],
"script": {
"source": "token.getTerm().length() < 5"
}
}
],
"text": "Is This-<déja v'u"
}

predicate_token_filter

移除不满足 script 条件的 token

1
2
3
4
5
6
7
8
9
10
11
12
13
POST _analyze
{
"tokenizer": "whitespace",
"filter": [
{
"type": "predicate_token_filter",
"script": {
"source": "token.getTerm().length() > 5"
}
}
],
"text": "Is This-<déja v'u"
}

stemmer、snowball

提取各种语言的词干,默认语言为english,去掉 inged 等。两者提取的词干略有不同(例如 are ,stemmer 会提取为 ar ,snowball 则保持不变)

1
2
3
4
5
6
POST _analyze
{
"tokenizer": "whitespace",
"filter": ["stemmer"],
"text": "Is This-<déja doing"
}

stemmer_override

覆盖 stemmer 的自动提取词干,顺序需要在其他 stemmer 之前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST _analyze
{
"tokenizer": "standard",
"filter": [
{
"type": "stemmer_override",
"rules": [
"doing => dddd"
]
},
"stemmer"
],
"text": "What are you doing?"
}

keyword_marker

保护 token 不被 stemmer 提取词干

1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST _analyze
{
"tokenizer": "standard",
"filter": [
{
"type": "keyword_marker",
"keywords": [
"doing"
]
},
"stemmer"
],
"text": "What are you doing?"
}

kstem

english 的高性能 filter,必须所有的词均为小写状态才能使用

synonym

重点!!!,同义词处理

1
2
3
4
5
6
7
8
9
10
11
12
13
POST _analyze
{
"tokenizer": "standard",
"filter": [
{
"type": "synonym",
"synonyms": [
"you => 你"
]
}
],
"text": "What are you doing?"
}

支持同义词文件路径参数 synonyms_path ,文件案例如下

1
2
3
4
5
6
i-pod, i pod => ipod,
sea biscuit, sea biscit => seabiscuit
ipod, i-pod, i pod
foozball , foosball
universe , cosmos
lol, laughing out loud

reverse

token 字符串翻转过来

truncate

有点类似于 substring,将原 token 按照 length 长度进行截取。

1
2
3
4
5
6
7
8
9
10
POST _analyze
{
"tokenizer": "standard",
"filter": [{
"type":"truncate",
"length":3
}
],
"text": "What are you doing?"
}

unique

相同的 token 只保留一个,设置 only_on_same_position:true 之后则只会移除在相同位置的,默认 false

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST _analyze
{
"tokenizer": "standard",
"filter": ["unique"],
"text": "What are you doing? are you doing?"
}

POST _analyze
{
"tokenizer": "standard",
"filter": [{
"type":"unique",
"only_on_same_position":true
}],
"text": "What are you doing? are you doing?"
}

limit

限制分词个数,由 max_token_count 控制,默认为 1consume_all_tokens:true试了下没什么用

1
2
3
4
5
6
7
8
9
10
11
POST _analyze
{
"tokenizer": "whitespace",
"filter": [
{
"type": "limit",
"max_token_count": 2
}
],
"text": "What are you doing?"
}

keep

keep_words 只留下指定的词, keep_types 留下指定类型的词( 通过 mode 可以指定 exclude 模式)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
POST _analyze
{
"tokenizer": "standard",
"filter": [{
"type":"keep",
"keep_words":["this"]
}],
"text": "Is this 123"
}

POST _analyze
{
"tokenizer": "standard",
"filter": [
{
"type": "keep_types",
"mode": "exclude",
"types": [
"<NUM>"
]
}
],
"text": "Is this déja v'u 234"
}

apostrophe

撇号处理器,去掉 ' 之后的字符,例如 don't => don

1
2
3
4
5
6
7
8
POST _analyze
{
"tokenizer": "standard",
"filter": [
"apostrophe"
],
"text": "d'uuuuu"
}

fingerprint

token 排序并去重

2.4 常用内容中 char filter

html_strip char filter

顾名思义,在原文本基础上过滤 html 标签;通过 escaped_tags 可以自定义不需要处理的标签。

1
2
3
4
5
6
7
8
9
10
11
12
POST _analyze
{
"tokenizer": "standard",
"filter": [
"asciifolding"
],
"char_filter": [{
"type":"html_strip",
"escaped_tags":"span"
}],
"text": "<div><span>déja</span></div>"
}

mapping char filter

在原文本基础上进行字符映射,例如将 and 转为 & ,定义时至少要声明 mappingsmappings_path 中的其中一个。

1
2
3
4
5
6
7
8
9
10
11
12
13
POST _analyze
{
"tokenizer": "whitespace",
"char_filter": [
{
"type": "mapping",
"mappings": [
"and => &"
]
}
],
"text": "you and me"
}

pattern replace char filter

使用 java 正则表达式进行文本替换,正则写的很糟糕的话,会导致运行慢、节点宕机、Stack Overflow 等一系列问题。下面是一个替换数字 - 连接符为 _ 的案例:

1
2
3
4
5
6
7
8
9
10
11
12
POST _analyze
{
"tokenizer": "whitespace",
"char_filter": [
{
"type": "pattern_replace",
"pattern": """(\d+)-(?=\d)""",
"replacement": "$1_"
}
],
"text": "My card is 123-456-789"
}

还有个群友提问到的场景,如何将 babyShoes 拆分为 babyshoes,下面是解决办法。(这里拆分后会有新问题,高亮位置不正确,因为正则映射后,原词的 position 位置被我们改动了)

1
2
3
4
5
6
7
8
9
10
11
12
13
POST _analyze
{
"tokenizer": "whitespace",
"char_filter": [
{
"type": "pattern_replace",
"pattern": """(?<=\p{Lower})(?=\p{Upper})""",
"replacement": " "
}
],
"filter": ["lowercase"],
"text": "The fooBarBaz method"
}

3. 跨集群检索

跨集群检索允许只发送一个请求同时查询多个集群上的数据

3.1 跨集群检索案例

使用跨集群检索之前,需要先配置 remote_server ,方式如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
PUT _cluster/settings
{
"persistent": {
"cluster": {
"remote": {
"cluster_one": {
"seeds": [
"127.0.0.1:9300"
]
},
"cluster_two": {
"seeds": [
"127.0.0.1:9301"
]
},
"cluster_three": {
"seeds": [
"127.0.0.1:9302"
]
}
}
}
}
}

配置好 remote_server 之后就可以直接进行查询了:

1
2
3
4
5
6
7
8
GET /twitter,cluster_one:twitter,cluster_two:twitter/_search
{
"query": {
"match": {
"user": "kimchy"
}
}
}

通过以下设置,可以选择性的跳过由于某个集群不可用,而引起的查询报错问题:

1
2
3
4
5
6
PUT _cluster/settings
{
"persistent": {
"cluster.remote.cluster_two.skip_unavailable": true
}
}

3.2 cross-cluster search(CCS) 是如何工作的

跨集群的检索肯定会涉及到集群之间的通信,而任何网络问题或者请求延迟都会使查询变慢。为了避免 cross-cluster search 的慢查询问题,在发送请求时 Elasticsearch 提供了以下两种策略:

  • Minimize network roundtrips,默认情况下,Elasticsearch 减少远程集群之间的网络往返次数,这样可以减少网络延迟对搜索速度的影响。但是,Elasticsearch 不能减少大型搜索请求(例如包含 Scrollinner_hits 的请求)的网络往返次数。(该分多次的还是得分多次查询….)
  • Don’t minimize network roundtrips,对于 scrollinner_hits 这类检索, Elasticsearch 可以通过批量 outgoingingoing 的方式来访问远程集群。通过在请求中添加 ?ccs_minimize_roundtrips=false 参数可以关闭请求数量压缩,速度较慢,但适用于低延迟的网络环境。

Minimize network roundtrips 检索的步骤:

  1. 将跨集群搜索请求发送到本地集群。该集群中的协调节点接收并解析该请求;

crossClusterSearch1_1.png

  1. 协调节点向每个集群发送单个搜索请求,包括其自身的搜索请求。每个集群独立执行搜索请求;

crossClusterSearch1_2.png

  1. 每个远程集群将其搜索结果发送回协调节点;

crossClusterSearch1_3.png

  1. 从每个集群收集结果之后,协调节点将在跨群集搜索响应中返回最终结果。

crossClusterSearch1_4.png

Don’t minimize network roundtrips 检索的步骤:

  1. 将跨集群搜索请求发送到本地集群。该集群中的协调节点接收并解析该请求;

crossClusterSearch2_1.png

  1. 协调节点向每个集群发送单个搜索请求,包括其自身的搜索请求。每个集群独立执行搜索请求;

crossClusterSearch2_2.png

  1. 每个远程集群将其响应发送回协调节点。该响应中包含了将要执行跨集群搜索请求的分片和索引的信息。

crossClusterSearch2_3.png

  1. 协调节点向每个分片(包括其自己的集群中的分片)发送搜索请求。每个分片独立执行搜索请求。

crossClusterSearch2_4.png

  1. 每个分片将其搜索结果发送回协调节点。

crossClusterSearch2_5.png

  1. 从每个集群收集结果之后,协调节点将在跨群集搜索响应中返回最终结果。

crossClusterSearch2_6.png

4. index_level shard allocation

设置节点属性

1
2
3
4
5
// yml 配置
node.attr.size: medium

// 启动参数配置
./bin/elasticsearch -Enode.attr.size=medium

配置索引策略:

1
2
3
4
5
6
// 声明多个则表示需要同时满足
PUT test/_settings
{
"index.routing.allocation.include.size": "big",
"index.routing.allocation.include.rack": "rack1"
}
  • index.routing.allocation.include.{attribute},节点至少需要满足 include 中的一个属性;
  • index.routing.allocation.require.{attribute},节点必须满足 require 中的所有属性
  • index.routing.allocation.exclude.{attribute},索引不能分配在 exclude 属性的节点上

attribute 属性值由用户自定义 ,也可以使用 Elasticsearch 内建的以下属性:

  • _name,通过节点名称匹配节点
  • _host_ip,通过主机 IP 地址(与主机名关联的 IP )匹配节点
  • _publish_ip,通过发布 IP 地址匹配节点
  • _ip,匹配 _host_ip_publish_ip
  • _host 通过主机名匹配节点

限制每个节点上的分片数量

使用该配置会影响物理层面的分配,如果节点数不够,可能会导致部分分片状态为 unAssigned

1
2
index.routing.allocation.total_shards_per_node
cluster.routing.allocation.total_shards_per_node

5. cluster_level shard allocation

allocation awarenessFore awareness 是针对不同机房、机架环境设置的,例如不希望将主副分片分配到同一个机架,或者同一个地区。避免一处停电,影响所有数据。

第一步:设置节点属性,与index_level是相同的,可自定义

1
node.attr.rack_id: rack1

第二步:设置集群层面的分片分配策略,属性保持相同

如下的例子中

  • awareness.attribute 指明了分片分配的感知策略基于 rack_id
  • force.rack_id.values 指明了分片分配的范围,主副分片必须在两个机架上。
    1
    2
    3
    4
    5
    6
    7
    PUT _cluster/setting
    {
    "persistent":{
    "cluster.routing.allocation.awareness.attribute": "rack_id",
    "cluster.routing.allocation.awareness.force.rack_id.values": "rack1,rack2"
    }
    }

测试

如果只有一个机架属性,副本分配将表现为 unassigned 状态

1
2
3
4
5
6
7
PUT test_004
{
"settings": {
"number_of_shards": 5,
"number_of_replicas": 1
}
}

6. ingest pipeline

6.1 增删改查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//重复调用,会自动更新原有的声明
PUT _ingest/pipeline/my_pipeline
{
"description" : "describe pipeline",
"processors" : [
{
"set" : {
"field": "foo",
"value": "bar"
}
}
]
}
// 查询
GET _ingest/pipeline/my_pipeline
// 删除
DELETE _ingest/pipeline/my_pipeline

6.2 condition 语法(可以使用正则判断)

根据数据内容判断

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
// if 案例
PUT _ingest/pipeline/drop_guests_network
{
"processors": [
{
"drop": {
"if": "ctx.network_name == 'Guest'"
}
}
]
}
// 展开对象,多条件判断案例
PUT _ingest/pipeline/drop_guests_network
{
"processors": [
{
"dot_expander": {
"field": "network.name"
}
},
{
"drop": {
"if": "ctx.network?.name != null && ctx.network.name.contains('Guest')"
}
}
]
}

使用复杂的代码语法判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 有些类似于 `script` 操作了
PUT _ingest/pipeline/not_prod_dropper
{
"processors": [
{
"drop": {
"if": """
Collection tags = ctx.tags;
if(tags != null){
for (String tag : tags) {
if (tag.toLowerCase().contains('prod')) {
return false;
}
}
}
return true;
"""
}
}
]
}

按条件使用 processor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
PUT _ingest/pipeline/logs_pipeline
{
"description": "A pipeline of pipelines for log files",
"version": 1,
"processors": [
{
"pipeline": {
"if": "ctx.service?.name == 'apache_httpd'",
"name": "httpd_pipeline"
}
},
{
"pipeline": {
"if": "ctx.service?.name == 'syslog'",
"name": "syslog_pipeline"
}
},
{
"fail": {
"message": "This pipeline requires service.name to be either `syslog` or `apache_httpd`"
}
}
]
}

6.3 处理器 processors

  • append,向数组中添加元素,如果数组不存在,则使用给定元素新建。
  • bytes,单位转换,1kb --> 1024
  • convert,类型转换,字符串转数字,或者转 boolean
  • date,日期格式化,处理后的字段默认为 @timestamp ,通过 target_field 变更
  • date_index_name,按照日期将数据分配到不同索引,使用 set 处理器修改 _index 也可以实现类似效果
  • dissect ,也称解剖…从单个文本字段中提取结构化字段,与 grok 类似,但不使用正则表达,所以某些情况下速度比 grok 更快
  • dot_expander,展开类似 fullname.firstname 的字段为 object 格式.
  • drop,移除文档,可以按 if 条件来 drop
  • fail,抛出异常的处理器,用于提示请求出错
  • foreach,遍历数组字段,可以在内部使用所有其他的处理器。
  • grok
  • gsub,将字符串按照 pattern 进行替换,如果不是字符串类型则会报错。
  • html_strip,去除 html 标签
  • json,将 json 字符串转换为对象
  • kv,通过 field_split 切分为数组,再根据 value_split 切分 keyvalue
  • lowercase/uppercase,大小写转换
  • pipeline,类似于 include 的感觉,引用另一个 pipeline 的所有处理器
  • remove,移除一个已有的字段,如果字段不存在,抛出错误
  • rename,字段重命名
  • script,脚本处理器
  • set,为字段设值
  • split,分割
  • sort,排序
  • trim,去空格
  • urldecode,解析 url 中的转义字符,例如 %23 对应 #

一个较为全面的应用案例:

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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"append": {
"field": "tags",
"value": [
"{{app}}",
"{{owner}}"
]
}
},
{
"bytes": {
"field": "file"
}
},
{
"date": {
"field": "date_test",
"formats": [
"yyyy-MM-dd"
],
"target_field": "@date",
"timezone": "UTC+8"
}
},
{
"dissect": {
"field": "log",
"pattern": "[%{ts}] [%{level}] %{*p1}:%{&p1} %{*p2}:%{&p2}"
}
},
{
"dot_expander": {
"field": "fullname.firstname"
}
},
{
"dot_expander": {
"field": "fullname.lastname"
}
},
{
"fail": {
"if": "ctx.tags.contains('blue') != true",
"message": "The production tag is not present, found tags: {{tags}}"
}
},
{
"foreach": {
"field": "hobby",
"processor": {
"uppercase": {
"field": "_ingest._value"
}
}
}
},
{
"grok": {
"field": "message",
"patterns": [
"%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}"
]
}
},
{
"html_strip": {
"field": "html_strip_test"
}
},
{
"join": {
"field": "hobby",
"separator": "-",
"target_field": "join_hobby"
}
},
{
"json": {
"field": "json_test"
}
},
{
"kv": {
"field": "kv_test",
"field_split": "&",
"value_split": "="
}
},
{
"remove": {
"field": "ip"
}
},
{
"rename": {
"field": "rename_test",
"target_field": "new_rename_test"
}
},
{
"script": {
"source": """
ArrayList hobbyList = ctx.hobby;
hobbyList.remove(0);
ctx.script_test = hobbyList;
"""
}
},
{
"set": {
"field": "set_test",
"value": "我是{{set_test}}"
}
},
{
"split": {
"field": "split_test",
// +号表示连续的符号视为一个
"separator": ",+"
}
},
{
"sort": {
"field": "sort_test",
"order": "asc"
}
},
{
"trim": {
"field": "trim_test"
}
},
{
"urldecode":{
// url转义符解析,例如 %23 对应 #
"field":"urldecode_test"
}
}
]
},
"docs": [
{
"_source": {
"tags": "blue",
"app": "surfshark",
"owner": "zengxin",
"file": "1kb",
"date_test": "2021-05-10",
"log": "[2018-08-10T17:15:42,466] [ERR] ip:1.2.3.4 error:REFUSED",
"fullname.firstname": "zeng",
"fullname.lastname": "xin",
"hobby": [
"read",
"moive",
"coding"
],
"ip": "8.8.8.8",
"message": "55.3.244.1 GET /index.html 15824 0.043",
"html_strip_test": "<span style='color:red'>测试</span>",
"json_test": """{"foo": 2000}""",
"kv_test": "username=zhangsan&password=123456",
"rename_test": "history",
"set_test": "123",
"split_test":"zengxin,,,zhengxin,tomas,北方",
"sort_test":[10,23,9,11,7,5],
"trim_test":"这是 的 ",
"urldecode_test":"http://172.25.17.142:5601/app/kibana%23/dev_tools/console?_g=()"
}
}
]
}

7. x-pack:role、https 配置

7.1 身份认证与用户鉴权

Authentication 认证体系

  • 提供用户名、密码
  • 提供密钥或 kerberos 票据

    Realms:X-pack中的认证服务

  • 内置 Realms(免费),File/Native 用户名/密码保存在 Elasticsearch 中;
  • 外部 Realms(收费),LDAP/Active Directory/PKI/SAML/Kerberos

RBAC 用户鉴权

什么是 RBAC: Role Based Access Control(基于角色的权限控制),定义一个角色,并分配一组权限。权限包括索引级,字段级,集群级的不同的操作。然后通过将角色分配给用户,使得用户拥有这些权限。
ES

  • User
  • Role
  • Permission
  • Previlege

7.2 集群安全通信: tranposrt + https

配置xpack

  1. 切换到 es 启动用户,修改配置文件 xpack.security.enabled: true
  2. 执行 bin/elasticsearch-certutil ca 生成 ca 文件,一路回车默认即可, 7.2 版本的默认文件名为 elastic-stack-ca.p12,存放在安装根目录下
  3. 执行 bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12 生成证书。默认文件名为 elastic-certificates.p12 ,存放在安装根目录下
  4. 执行 mv elastic-certificates.p12 config/cert/ 将证书移动到 config/cert/ 目录下
  5. 将证书拷贝到集群其它节点的 config/cert/ 目录下
  6. 修改最终的配置文件为如下所示
1
2
3
4
5
6
7
8
9
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: cert/elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: cert/elastic-certificates.p12

xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: cert/elastic-certificates.p12
xpack.security.http.ssl.truststore.path: cert/elastic-certificates.p12

配置用户名、密码

执行 bin/elasticsearch-setup-passwords interactive 初始化各用户的密码

kibana 访问设置

kibana 使用 https 时还需要修改如下三个参数:

1
2
3
elasticsearch.hosts: ["http://localhost:9200"]
elasticsearch.ssl.certificateAuthorities: [ "/path/to/your/CA.pem" ]
elasticsearch.ssl.verificationMode: certificate

生成 pem 文件需要使用到 openssl,执行如下指令:

1
openssl pkcs12 -in elastic-certificates.p12 -cacerts -nokeys -out elastic-ca.pem

kibana的https设置

  1. 执行 bin/elasticsearch-certutil ca --pem,生成的 elastic-stack-ca.zip 文件中包含了 ca.crtca.key 两个文件;
  2. 解压缩后,将两个文件拷贝到 config/cert 目录下,编辑 kibana.yml 文件的如下配置;
1
2
3
server.ssl.enabled: true
server.ssl.certificate: config/cert/ca.crt
server.ssl.key: config/cert/ca.key

由于证书是自签的,仅能用于测试,所以kibana中会有SSL相关的报错


あなたがいきる、この世界に

Alt

0%