由于工作过程中硬件资源未能达到要求,现将使用 Elasticsearch 取代原 Redis + MySQL + Milvus 技术栈,在重新搭建的同时记录一下搭建过程(由于之前也分享过 Docker 版本 Elasticsearch 5.x 和 Elasticsearch 7.x 的部署方法,因此本文对分享过的内容将不再重复说明)。
1. 应用部署
虽然最终没有使用 8.14.2 版本,但考虑到实际部署跟这个过程也是大差不差的,因此这段内容还是保留吧。
第一步,先将 Elasticsearch 容器启动起来,如下图:
docker run -d -p 9200:9200 -p 9300:9300 elasticsearch:8.14.2
启动起来后可以进入容器内部将 config、data、plugins 三个目录下载到宿主机(这里为了方便使用了 Docker Desktop 来操作,在命令行下要使用 docker cp 命令进行操作),如下图:
目录下载后结构如下图所示:
如上图所示, elasticsearch.yml 和 jvm.options 可以按需进行修改(配置内容在之前文章已经说明,这里不再细说)。接着挂载目录就可以启动 Elasticsearch 容器,全部命令如下图:
docker run -d \
--privileged=true \
--name es_vct \
--network elknetwork \
-p 9200:9200 \
-p 9300:9300 \
-v ${docker_path}/elasitcsearch8/data:/usr/share/elasticsearch/data \
-v ${docker_path}/elasitcsearch8/plugins:/usr/share/elasticsearch/plugins \
-v ${docker_path}/elasitcsearch8/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
--restart=always \
elasticsearch:8.14.2
但是… OSX 系统在启动后会报以下错误,如下图:
2024-08-06 09:46:51 {"@timestamp":"2024-08-06T01:46:51.542Z", "log.level":"ERROR", "message":"fatal exception while booting Elasticsearch", "ecs.version": "1.2.0","service.name":"ES_ECS","event.dataset":"elasticsearch.server","process.thread.name":"main","log.logger":"org.elasticsearch.bootstrap.Elasticsearch","elasticsearch.node.name":"ff06f045201e","elasticsearch.cluster.name":"elastic_vector","error.type":"java.lang.IllegalStateException","error.message":"Plugin [.DS_Store] is missing a descriptor properties file.","error.stack_trace":"java.lang.IllegalStateException: Plugin [.DS_Store] is missing a descriptor properties file.\n\tat org.elasticsearch.server@8.14.2/org.elasticsearch.plugins.PluginDescriptor.readFromProperties(PluginDescriptor.java:233)\n\tat org.elasticsearch.server@8.14.2/org.elasticsearch.plugins.PluginsUtils.readPluginBundle(PluginsUtils.java:255)\n\tat org.elasticsearch.server@8.14.2/org.elasticsearch.plugins.PluginsUtils.findBundles(PluginsUtils.java:236)\n\tat org.elasticsearch.server@8.14.2/org.elasticsearch.plugins.PluginsUtils.getPluginBundles(PluginsUtils.java:218)\n\tat org.elasticsearch.server@8.14.2/org.elasticsearch.plugins.PluginsService.<init>(PluginsService.java:156)\n\tat org.elasticsearch.server@8.14.2/org.elasticsearch.node.NodeServiceProvider.newPluginService(NodeServiceProvider.java:54)\n\tat org.elasticsearch.server@8.14.2/org.elasticsearch.node.NodeConstruction.createEnvironment(NodeConstruction.java:451)\n\tat org.elasticsearch.server@8.14.2/org.elasticsearch.node.NodeConstruction.prepareConstruction(NodeConstruction.java:252)\n\tat org.elasticsearch.server@8.14.2/org.elasticsearch.node.Node.<init>(Node.java:192)\n\tat org.elasticsearch.server@8.14.2/org.elasticsearch.bootstrap.Elasticsearch$2.<init>(Elasticsearch.java:240)\n\tat org.elasticsearch.server@8.14.2/org.elasticsearch.bootstrap.Elasticsearch.initPhase3(Elasticsearch.java:240)\n\tat org.elasticsearch.server@8.14.2/org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:75)\n"}
2024-08-06 09:46:51 ERROR: Elasticsearch did not exit normally - check the logs at /usr/share/elasticsearch/logs/elastic_vector.log
在 github 找到了这个错误的解释,如下图:
(吐槽一下:问题是 2022 年发现的,但 2024 年还没有修复…)
我们按上述方法执行一下删除命令即可消除错误信息,如下图:
rm ${docker_path}/elasitcsearch8/plugins/.DS_Store
接着第二个问题又来了,Elasticsearch 启动到时出现卡顿,如下图:
2024-08-06 10:15:36 Aug 06, 2024 2:15:36 AM sun.util.locale.provider.LocaleProviderAdapter <clinit>
2024-08-06 10:15:36 WARNING: COMPAT locale provider will be removed in a future release
2024-08-06 10:15:36 {"@timestamp":"2024-08-06T02:15:36.723Z", "log.level": "INFO", "message":"Using [jdk] native provider and native methods for [Linux]", "ecs.version": "1.2.0","service.name":"ES_ECS","event.dataset":"elasticsearch.server","process.thread.name":"main","log.logger":"org.elasticsearch.nativeaccess.NativeAccess","elasticsearch.node.name":"86f65a8da329","elasticsearch.cluster.name":"docker-cluster"}
2024-08-06 10:15:37 {"@timestamp":"2024-08-06T02:15:37.123Z", "log.level": "INFO", "message":"Java vector incubator API enabled; uses preferredBitSize=512; FMA enabled", "ecs.version": "1.2.0","service.name":"ES_ECS","event.dataset":"elasticsearch.server","process.thread.name":"main","log.logger":"org.apache.lucene.internal.vectorization.PanamaVectorizationProvider","elasticsearch.node.name":"86f65a8da329","elasticsearch.cluster.name":"docker-cluster"}
这种“假死”情况大几率是因为配置出现问题了,重新审视一遍配置文件得知, discovery.type 并未正常配置(由于是单体服务,这里需要通过 single-node 进行表示)。
将配置加上后就可以正常启动了。
2. 8.12 版本部署并安装分词(ik)插件
启动成功后添加分词插件,到 github 仓库中找到最新的 release ,如下图:
尝试安装 8.4.1 版本后发现与目前 Elasticsearch 版本不匹配。出现以下报错:
java.lang.IllegalStateException: Plugin [ik] is missing a descriptor properties file
最后实在弄得有点儿烦了就选择了 8.12.2 版本的分词插件,而 Elasticsearch 也降级到 8.12.2 版本。
PS:这里其实我也是不太确定的,尝试了很多次还是安装不上才选择了降级。或许是当时配置也有点错误吧,8.12.2 版本能用我就没有再深究这个问题了。
8.12.2 版本部署过程其实跟 8.14.2 一致(没什么好说的)。接下来只需将分词插件放对位置就能够实现安装,如下图:
在分词插件的 github release 网页中点击打开 8.12.2 的 Assets 折叠区,并选择下载 elasticsearch-analysis-ik-8.12.2.zip 压缩包。下载完成后将其放到 ${docker_path}/elasitcsearch8/plugins 目录下并解压。解压后重命名文件夹为 analysis-ik 并删除 zip 压缩包。之后重启 Elasticsearch 容器 ik 分词插件就会自动安装,最终启动命令如下:
docker run -d \
--privileged=true \
--name elasticsearch8 \
-p 9200:9200 \
-p 9300:9300 \
-v ${docker_path}/elasitcsearch8/data:/usr/share/elasticsearch/data \
-v ${docker_path}/elasitcsearch8/plugins:/usr/share/elasticsearch/plugins \
-v ${docker_path}/elasitcsearch8/config:/usr/share/elasticsearch/config \
-v ${docker_path}/elasitcsearch8/logs:/usr/share/elasticsearch/logs \
-v /etc/localtime:/etc/localtime \
-e TZ="Asia/Shanghai" \
-e LANG="C.UTF-8" \
--restart=always \
elasticsearch:8.12.2
那么如何验证分词插件安装成功呢?
这时我在 Firefox 浏览器中安装一个 Elasticvue 插件(这个插件还挺好用),对 Elasticsearch 服务提交 REST 分词请求,如下图:
看到上面的输出就证明分词器安装成功。
3. 安装 x-pack 安全插件
这个在之前博客中已经详细说明过一次,在这里我再补充说明一下(主要是跟之前不一样的部分)。
第一步开启 xpack.security 服务,如下图:
注意, xpack 的其他服务都是 false(关闭)状态的,只有 xpack.security.enabled 是 true(开启)状态,不然启动时会报错。之后重启 Elasticsearch 容器,并进入 CLI 控制台先创建 keystore,如下图:
sh-5.0$ ./bin/elasticsearch-keystore create
An elasticsearch keystore already exists. Overwrite? [y/N]y
Created elasticsearch keystore in /usr/share/elasticsearch/config/elasticsearch.keystore
keystore 创建完成后就可以针对“elastic”用户进行 password 重置了,如下图:
sh-5.0$ elasticsearch-reset-password -i -u elastic
This tool will reset the password of the [elastic] user.
You will be prompted to enter the password.
Please confirm that you would like to
continue [y/N]y
Enter password for [elastic]:
Re-enter password for [elastic]:
Password for the [elastic] user successfully reset.
这里可以通过 elasticsearch-reset-password 直接对指定用户进行密码重置(跟之前不同的地方)。
再之后就可以创建 ca 证书了,如下图:
sh-5.0$ ./bin/elasticsearch-certutil ca
...
Please enter the desired output file [elastic-stack-ca.p12]: config/certs/elastic-stack-ca.p12
Enter password for elastic-stack-ca.p12 :
再之后就可以使用 ca 证书创建密钥,如下图:
sh-5.0$ ./bin/elasticsearch-certutil cert --ca config/certs/elastic-stack-ca.p12
...
Enter password for CA (config/certs/elastic-stack-ca.p12) :
Please enter the desired output file [elastic-certificates.p12]: config/certs/elastic-certificates.p12
Enter password for elastic-certificates.p12 :
...
For client applications, you may only need to copy the CA certificate and
configure the client to trust this certificate.
注意,这里的 ca 证书和密钥的 output 目录都是指向 config/certs 。之所以要指向这个目录是因为它已经挂载到宿主机了。万一这个容器被干掉了,还可以直接用回 ca 证书重新生成密钥。
sh-5.0$ ./bin/elasticsearch-keystore add \
> xpack.security.transport.ssl.keystore.secure_password
Enter value for xpack.security.transport.ssl.keystore.secure_password:
sh-5.0$ ./bin/elasticsearch-keystore add \
> xpack.security.transport.ssl.truststore.secure_password
Enter value for xpack.security.transport.ssl.truststore.secure_password:
最后创建安全连接的密码。
好了,密钥都创建完成了。现在只需在 elasticsearch.yml 开放所有安全校验即可,如下图:
将 transport.ssl 开启并指派密钥的地址(容器内地址),就可以重新启动 Elasticsearch 容器了。
最后使用 Elasticvue 进行测试,看到以上的输出就证明配置成功了。