docker安装es

安装参考官网文档:
https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html

docker pull docker.elastic.co/elasticsearch/elasticsearch:8.16.1

准备工作

1.Create a new docker network for Elasticsearch and Kibana[我是直接用我之前创建的sill网络,就不创建elastic网络了]

docker network create elastic

2.创建目录[config目录可以不用]

mkdir -p /opt/services/es01/config /opt/services/es01/data /opt/services/es01/logs
#给所属组添加读写执行权限
chmod g+rwx config data logs
#将es01给用户组0,原因如下图
sudo chgrp 0 config data logs

es目录赋给用户组03.修改vm.max_map_count

vi /etc/sysctl.conf
添加下面这行
vm.max_map_count=262144
#使修改生效
sudo sysctl -p

在这里插入图片描述
不然会报错
在这里插入图片描述
4.创建加密的keystore[默认创建的只是混淆了 ,并没有加密]

sudo docker run -it --rm -v /opt/services/es01/config:/usr/share/elasticsearch/config docker.elastic.co/elasticsearch/elasticsearch:8.16.1 bin/elasticsearch-keystore create -p

注意:实事证明-v /opt/services/es01/config/elasticsearch.keystore:/usr/share/elasticsearch/config/elasticsearch.keystore有问题,会报错,

Exception in thread "main" java.nio.file.FileSystemException: /usr/share/elasticsearch/config/elasticsearch.keystore.tmp -> /usr/share/elasticsearch/config/elasticsearch.keystore: Device or resource busy

而且官方的解决方法有两种
A:直接挂载config目录,而不直接到elasticsearch.keystore文件。这样的话,需要config里的其他配置文件也存在在config目录中,否则会报错。
B:重新创建keystore,再试一次。结果是,没什么作用,依然报错。
在这里插入图片描述
c:除了A之外的另一个正确的解决方法【参考:https://github.com/deviantony/docker-elk/issues/579】
在这里插入图片描述
在这里插入图片描述
在docker compose中加入enterpoint配置:

mv /opt/services/es01/config/elasticsearch.keystore /opt/config/es01/elasticsearch.keystore.ori

文件init-generate-certsandyml-x-es.yml

#初次启动生成证书用
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.16.1
    container_name: es01
    #不指定的话会随机生成一个hostname,自动生成的节点证书http.p12中的dns就是随机的,skywalking不能用容器名es01(因为没在证书的dns列表中)访问es,
    #会报Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching es01 found.
    #hostname不能是ip,为ip后skywalking连接仍报错Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address 10.0.4.3 found。也就是说 证书中'DNS 名称: 10.0.4.3'没用,必须是'IP 地址: 10.0.4.3'
    #hostname: 10.0.4.3
    hostname: es01
    #--group-add 0: This ensures that the user under which Elasticsearch is running is also a member of the root (GID 0) group inside the container.
    group_add:
       - '0'
    volumes:
      #需要提前生成好elasticsearch.keystore,实事证明直接挂载keystore文件报错
      #- /opt/services/es01/config/elasticsearch.keystore:/usr/share/elasticsearch/config/elasticsearch.keystore
      #- /opt/services/es01/config:/usr/share/elasticsearch/config
      #需要以.options为后缀,每行一个参数
      - /opt/services/es01/custom_jvm.options:/usr/share/elasticsearch/config/jvm.options.d/custom_jvm.options
      #- /opt/services/es01/certs:/usr/share/elasticsearch/config/certs
      #certs设置后这个也必须设置,不然会报ssl.enable还未设置为true,elasticsearch.keystore中存储的密码已经设置到环境变量中了,会导致启动失败
      #- /opt/services/es01/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
      - /opt/services/es01/data:/usr/share/elasticsearch/data
      - /opt/services/es01/plugins:/usr/share/elasticsearch/plugins
      - /opt/services/es01/logs:/usr/share/elasticsearch/logs
      - /opt/services/es01/keystore_password.txt:/run/secrets/keystore_password.txt
      #更新/opt/services/es01/elasticsearch.keystore时不能删除它,应docker cp 容器内的新elasticsearch.keystore到宿主机上另一位置,停掉容器后再替换,否则报 ...is not directory
      - /opt/config/es01/elasticsearch.keystore.ori:/usr/share/elasticsearc/elasticsearch.keystore:ro,z
      #映射时区
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
    environment:
      #KEYSTORE_PASSWORD_FILE 指向的是容器内部的
      KEYSTORE_PASSWORD_FILE: /run/secrets/keystore_password.txt
      #镜像内缺少timedatectl工具,这个设置没用
      #TZ: Asia/Shanghai
      #配了cluster.ame,logs中显示了正确的elasticsearch.cluster.name,但是自动生成的elasticsearch.yml中的cluster.name仍旧为docker-cluster,但https://10.0.4.3:9200/输出是正确的
      cluster.name: es-cluster
      node.name: node-1
    ports:
      - 9200:9200
      - 9300:9300
    entrypoint:
      - /bin/bash
      - -c
      - >
        cp /usr/share/elasticsearc/elasticsearch.keystore /usr/share/elasticsearch/config/elasticsearch.keystore;
        exec /usr/local/bin/docker-entrypoint.sh;
networks:
  default:
    name: sill

注意:启动时需带上keystore的密码,用-e KEYSTORE_PASSWORD或将密码放到文件里-e KEYSTORE_PASSWORD_FILE
建立/opt/services/es01/keystore_password.txt里面直接放入密码字符串
将该文件权限更改,不然会报错
ERROR: File /run/secrets/keystore_password.txt from KEYSTORE_PASSWORD_FILE must have file permissions 400 or 600, but actually has: 664

sudo chmod 400 keystore_password.txt

注意:-e KEYSTORE_PASSWORD_FILE指向的目录是容器内的目录,所以需要将keystore_password.txt挂载到容器中

在这里插入图片描述
在这里插入图片描述
配置jvm内存
在这里插入图片描述
custom_jvm.options内容如下:

-Xms256m
-Xmx256m
-XX:MaxDirectMemorySize=256m

5.如何查看elastic密码:密码存放在elasticstore.keystore中。
启动容器后,【初次启动es时,es8以上版本会自动生成各种证书和密钥库,在config/certs中。并且密钥库的密码(http_ca.crt证书没有密码,证书是包含公钥,主体等公开信息,一般不需要密钥保护)会自动更新到elasticsearch.keystore中。并且elasticsearch.yml会自动配置启动ssl相关信息

sudo docker exec -it es01 /bin/bash
#查看项
./bin/elasticsearch-keystore list
#设置bootstrap密码 设置之后keystore.seed作为默认bootstrap密码不再起作用
../bin/elasticsearch-keystore add "bootstrap.password"

#更新/opt/services/es01/elasticsearch.keystore时不能删除它,应docker cp 容器内的新elasticsearch.keystore直接覆盖到宿主机上,否则报 …is not directory[如果删除了,也可以从别的地方重新copy过来一个]
然后在宿主机上执行

sudo docker cp es01:/usr/share/elasticsearch/config/elasticsearch.keystore /opt/services/es01/elasticsearch.keystore

参考es设置账户密码
在这里插入图片描述


具体看链接的官方文档:
keystore.seed项默认引导密码
如果只有keystore.seed,则可以用此项的值可以当作所有账户的密码,
如果设置了bootstrap.password,则keystore.seed不再起作用。
如果单独设置了各个账号比如elastic用户的密码,则对此账户只有该密码起作用。这种方法的密码不在elasticsearch.keystore文件中

附:修改elastic用户密码【这种方法的密码不在elasticsearch.keystore文件中】,这步不必要

./elasticsearch-reset-password -u elastic -i

8.es8以上本版,初次启动es时,会自动生成ssl证书和密钥库,将它们复制出来

sudo docker cp es01:/usr/share/elasticsearch/config/certs /opt/services/es01

9.elasticsearch.yml复制出来

sudo docker cp es01:/usr/share/elasticsearch/config/elasticsearch.yml /opt/services/es01/

修改,添加node.name,并将cluster.initial_master_nodes的值改为node.name的值

cluster.name: "docker-cluster"
node.name: "node-1"
network.host: 0.0.0.0

#----------------------- BEGIN SECURITY AUTO CONFIGURATION -----------------------
#
# The following settings, TLS certificates, and keys have been automatically      
# generated to configure Elasticsearch security features on 04-12-2024 12:32:31
#
# --------------------------------------------------------------------------------

# Enable security features
xpack.security.enabled: true

xpack.security.enrollment.enabled: true

# Enable encryption for HTTP API client connections, such as Kibana, Logstash, and Agents
xpack.security.http.ssl:
  enabled: true
  keystore.path: certs/http.p12

# Enable encryption and mutual authentication between cluster nodes
xpack.security.transport.ssl:
  enabled: true
  verification_mode: certificate
  keystore.path: certs/transport.p12
  truststore.path: certs/transport.p12
# Create a new cluster with the current node only
# Additional nodes can still join the cluster later
cluster.initial_master_nodes: ["node-1"]

#----------------------- END SECURITY AUTO CONFIGURATION -------------------------

10.测试证书访问

curl --cacert http_ca.crt -u elastic:密码 https://localhost:9200

后续启动配置文件


附录:es8初次启动时config/certs/文件夹下生成的http_ca.crt,http.p12,transport.p12说明

在这里插入图片描述
在这里插入图片描述

http_ca.crt和http.p12的关系:

# 获取 http_ca.crt 的详细信息
openssl x509 -in http_ca.crt -text -noout

# 获取 http.p12 中证书的详细信息
openssl pkcs12 -in http.p12 -nokeys -info
#或者下面这个可以看到SAN信息
/usr/share/elasticsearch/jdk/bin/keytool -list -v -keystore http.p12 -storetype PKCS12

# 对比它们的内容发现
http.p12包含了两个证书 alias name分别为http和http_ca,而http_ca就是http_ca.crt,它们的issuer,Serial number,Owner,Certificate fingerprints and 
expiration...等等都是相同的。

也就是说http.p12 文件确实包含了 http_ca.crt 的CA证书。这表示当你使用 http.p12 文件进行HTTPS通信时,客户端或服务器会信任由这个CA签发的所有证书,因为该CA证书已经在密钥库中。

http_ca.crt和transport.p12的关系:

为了确认 transport.p12 中是否包含完整的证书链,可以尝试将所有证书导出到一个PEM文件中并检查它们:

openssl pkcs12 -in transport.p12 -nokeys -info
#或者下面这个可以看到SAN信息
/usr/share/elasticsearch/jdk/bin/keytool -list -v -keystore transport.p12 -storetype PKCS12

对比http_ca.p12和transpor.p12,序列号,颁发者,有效期,主体都不同。说明transport.p12没有用http_ca.crt证书。
并且transport.p12没有SAN,有效期有99年,几乎不需要更换。它们共同点是,CN相同都为node.name.
在这里插入图片描述
集群布署时,传输层证书transport.p12【如果自己生成的话,默认名为elastic-certificates.p12】可以只需一个【此时xpack.security.transport.ssl.verification_mode的值须配置为certificate。如xpack.security.transport.ssl.verification_mode: certificate】,复制到各个节点就可以,http.p12需要每个节点都有自己的
参考https://www.elastic.co/guide/en/elasticsearch/reference/current/security-basic-setup.html
在这里插入图片描述

附录:用http_ca.crt(为pem格式)生成jks格式密钥库

用处:skywalking连接es时,skywalking需要jks格式的密钥库

/usr/share/elasticsearch/jdk/bin/keytool -import -v -trustcacerts -file http_ca.crt -keystore es_keystore.jks -keypass 解锁特定私钥条目的密码 -storepass 解锁es_keystore.jsk密钥库的密码

在这里插入图片描述
如果你只是导入CA证书,只需要提供 -storepass 来解锁密钥库即可。对于包含私钥的操作(例如从 .p12 文件导入带有私钥的证书),则需要同时提供 -keypass 来保护或访问这些私钥。

所以简化为:

/usr/share/elasticsearch/jdk/bin/keytool -import -v -trustcacerts -file http_ca.crt -keystore es_keystore.jks -storepass 解锁es_keystore.jsk密钥库的密码(当es_keystore.jks不存在时,这个密码就是新生成的es_keystore.jks密钥库的密码)

/usr/share/elasticsearch/jdk/bin/keytool -import -v -trustcacerts -file ./config/certs/http_ca.crt -keystore http.jks -storepass changeit

然后可以将密码存入elasticsearch.keystore中【试了不行,启动报错:“error.message”:“unknown secure setting [custom.jks.keystore.secure_password] did you mean any of [reindex.ssl.keystore.secure_password, xpack.http.ssl.keystore.secure_password]?”】

./elasticsearch-keystore add "custom.jks.keystore.secure_password"

查看这个jks证书

/usr/share/elasticsearch/jdk/bin/keytool -list -v -keystore http.jks

实践检验,这样生成的证书在skywalking中使用时,若使用不合适的ip会报错。
Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address 10.0.4.3 found
通义千问说原因如下:

在这里插入图片描述
节点定义的ip可以在浏览器中看到:
在这里插入图片描述
其中 DNS 名称: 957069544f1d是docker启动时随机生成的hostname,可以用参数hostname指定。
在这里插入图片描述

也可以将http.p12转化为es_keystore.jks【****这种也报Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address 10.0.4.3 found.用es01的容器ip就没问题了。这种可以

/usr/share/elasticsearch/jdk/bin/keytool -importkeystore \
  -deststorepass es_keystore.jks密钥库的密码 \
  -destkeypass 新导入的密钥的密码(当你省略 -destkeypass 参数时,es_keystore.jks 中密钥条目的密码会默认使用 -deststorepass 中指定的密钥库密码) \
  -destkeystore es_keystore.jks \
  -srckeystore http.p12 \
  -srcstoretype PKCS12 \
  -srcstorepass http.p12密钥库的密码

/usr/share/elasticsearch/jdk/bin/keytool -importkeystore \
  -deststorepass changeit \
  -destkeypass sferretgh11234 \
  -destkeystore es_keystore.jks \
  -srckeystore http.p12 \
  -srcstoretype PKCS12 \
  -srcstorepass Klp_qrzDQw-_YE6etfdfd


结合我的springboot的代码,可知
就是.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)这句话导致不会校验服务器证书的SAN。

// 自签证书的设置,并且还包含了账号密码
        RestClientBuilder.HttpClientConfigCallback callback = httpAsyncClientBuilder -> httpAsyncClientBuilder
                .setSSLContext(buildSSLContext())
                //NoopHostnameVerifier.INSTANCE 是一个不执行任何主机名验证的实现,这意味着它将接受任何证书,而不会检查服务器提供的证书是否与连接的主机名匹配(包括SAN字段)
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .setDefaultCredentialsProvider(credentialsProvider);

我把上面这句注释掉,就会报错
在这里插入图片描述

总结:es默认生成的http.p12。如果客户端严格校验服务器证书,则只能用于同一docker网络中的服务之间。因为可以A方式:设置hostname为容器名,然后通过容器名访问,或者也可以B方式:通过容器ip访问。 但是外部服务不能校验成功该证书,因为外部服务只能通过宿主机来访问容器,但默认生成的证书的SAN中没有宿主机的域名或IP存在。所以,如果要在验格模式下访问es,就需要重新生成证书。es官网也有相应的教程可参考。

附录:clients连接es的四种方式

A: username & password&ca.crt
B:API KEY & ca.crt
C:username & password & CA certificate fingerprint
D:API KEY & CA certificate fingerprint
连接示例:
https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/8.17/connecting.html

创建API KEY
参考官网
https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html#security-api-create-api-key
.创建API KEY

sudo curl -X POST "https://localhost:9200/_security/api_key?pretty" --cacert /opt/services/es01/certs/ca.crt -u elastic:UpuIlguhiTfBrsC7rglX -H 'Content-Type: application/json' -d'{"name": "my-api-key-1000d","expiration": "1000d"}'

重新查看fingerprint:

sudo openssl x509 -fingerprint -sha256 -in /opt/config/es01/certs/ca.crt

在这里插入图片描述

参考自动安全设置:
Start the Elastic Stack with security enabled automatically:
https://www.elastic.co/guide/en/elasticsearch/reference/current/configuring-stack-security.html
Set up minimal security:
https://www.elastic.co/guide/en/elasticsearch/reference/current/security-minimal-setup.html
Set up basic security:
https://www.elastic.co/guide/en/elasticsearch/reference/current/security-basic-setup.html
Set up basic security plus HTTPS:
https://www.elastic.co/guide/en/elasticsearch/reference/current/security-basic-setup-https.html
参考更新节点证书:用相同的CA证书
https://www.elastic.co/guide/en/elasticsearch/reference/current/update-node-certs-same.html
参考更新节点证书:用不同的CA证书
https://www.elastic.co/guide/en/elasticsearch/reference/current/update-node-certs-different.html
Setting passwords for native and built-in users:
https://www.elastic.co/guide/en/elasticsearch/reference/current/change-passwords-native-users.html

附录:重新创建证书

说明:默认的传输层认证模式:certificate 只用证书就可以了。且默认生成的transport.p12有99年有效期。所以我们在此不需要更换。只用更换http.p12这个Http层证书。要更换http.p12,需要首先生成一个ca证书【因为es首次启动默认生成的http_ca.crt,没有给我们相应的http_ca.key.所以无法用http_ca.crt生成新证书。】(这个新的CA证书可以签署translate层和http层证书。但是我们就不更换translate层的证书了)

sudo docker exec -it es01 /bin/bash
cd config/certs/
#设置超级用户密码
~/bin/elasticsearch-keystore add "bootstrap.password"
#查看默认生成的证书的密码
~/bin/elasticsearch-keystore show xpack.security.http.ssl.keystore.secure_password
Qzgi6-IIR4G4oZGPDXL1uw
~/bin/elasticsearch-keystore show xpack.security.transport.ssl.keystore.secure_password
1QYQnd4CQXSF98MF4py7RQ
~/bin/elasticsearch-keystore show xpack.security.transport.ssl.truststore.secure_password
1QYQnd4CQXSF98MF4py7RQ

#生成并解压ca证书[ca.crt]和秘钥[ca.key](这里用的pem格式,也可以不加--pem,就会生成PKCS#12格式的默认名字为elastic-stack-ca.p12的证书)
~/bin/elasticsearch-certutil ca --pem
mv ~/elastic-stack-ca.zip  .
unzip elastic-stack-ca.zip -d .

#重新生成http层证书
~/bin/elasticsearch-certutil http
设置SAN:
DNS Name=localhost
DNS Name=es01(容器名字)

IP Address=172.20.0.6(es01对应的ip,容器的ip)
IP Address=127.0.0.1(localhost对应的ip)
IP Address=10.0.4.3(宿主机的内网ip)
#我们就用默认的http.p12的密码作为新的证书秘钥库的密码,这样就不用更新elasticsearch.keystore了。生成的文件为/usr/share/elasticsearch/elasticsearch-ssl-http.zip
#Archive:  elasticsearch-ssl-http.zip
#   creating: ./elasticsearch/
#  inflating: ./elasticsearch/README.txt  
#  inflating: ./elasticsearch/http.p12  
#  inflating: ./elasticsearch/sample-elasticsearch.yml  
#   creating: ./kibana/
#  inflating: ./kibana/README.txt     
#  inflating: ./kibana/elasticsearch-ca.pem  
#  inflating: ./kibana/sample-kibana.yml
mv ~/elasticsearch-ssl-http.zip .
unzip elasticsearch-ssl-http.zip -d .
#然后将http.p12和http_ca.crt备份,直接删除也可以。
elasticsearch@es01:~/config/certs$ mv http.p12 http.p12.bak
elasticsearch@es01:~/config/certs$ mv http_ca.crt http_ca.crt.bak

将新生成的http.p12移到certs目录下,就完成了替换
elasticsearch@es01:~/config/certs$ mv elasticsearch/http.p12 ./
#将ca.crt,ca.key移动certs目录中,然后删除其余的解压的文件,只保留zip文件就可以了
elasticsearch@es01:~/config/certs$ mv ca/* .
elasticsearch@es01:~/config/certs$ rm -rf ca
elasticsearch@es01:~/config/certs$ rm -rf elasticsearch/ kibana/

然后将ca.crt转为jks格式,供skywalking使用:
~/jdk/bin/keytool -import -v -trustcacerts -file ca.crt -keystore http.jks -storepass dfertygsd14345

最后在宿主机上复制出相应的文件
sudo docker cp es01:/usr/share/elasticsearch/config/elasticsearch.keystore /opt/services/es01/elasticsearch.keystore
sudo docker cp es01:/usr/share/elasticsearch/config/certs /opt/services/es01

附录:

.更新密码
./bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password
./bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password
./bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
./bin/elasticsearch-keystore add http.jks(不能放会报错)
./bin/elasticsearch-keystore add user_elastic_password(不能放会报错)
.查看密码库
./bin/elasticsearch-keystore list
./bin/elasticsearch-keystore show xpack.security.http.ssl.keystore.secure_password
./bin/elasticsearch-keystore show xpack.security.transport.ssl.keystore.secure_password
./bin/elasticsearch-keystore show xpack.security.transport.ssl.truststore.secure_password
.重新启动
docker start es01

curl --cacert /opt/services/es01/config/certs/http_ca.crt -u elastic https://172.20.0.6:9200
curl --cacert /opt/services/es01/config/certs/http_ca.crt -u elastic https://elastic:9200

当配置了集群模式,但是只有一个节点时,运行一段时间健康状态会变量yellow,cpu占用350%还多[看错了,是skywalking-oap占用350%多]
在这里插入图片描述
在这里插入图片描述
解决方案
A.启动更多的节点:
如果条件允许,启动更多节点加入集群。这将使副本分片能够被分配,从而提升集群的容错能力和查询性能。
B.调整索引设置:
如果暂时无法添加更多节点,可以考虑减少或禁用副本分片。例如,您可以修改现有索引的设置,将副本数量设为 0:
我们用B方法:

sudo curl --cacert /opt/services/es01/certs/ca.crt -u elastic:UpuIlguhiTfBrsC7rglX -X PUT "https://localhost:9200/_all/_settings" -H 'Content-Type: application/json' -d'
{
  "index" : {
      "number_of_replicas" : 0
  }
}
'

执行前
在这里插入图片描述

执行后查看是否生效

https://10.0.4.3:9200/_cat/shards?v=true&pretty

在这里插入图片描述

根据您提供的 _cat/shards 输出,看起来所有的分片都已经被标记为 STARTED 并且所有列出的分片都是主分片(prirep 列显示为 p),这意味着没有副本分片在运行。这表明您之前将 number_of_replicas 设置为 0 的操作已经生效。

在这种情况下,Elasticsearch 不再尝试分配副本分片,因此集群状态应该会从黄色变为绿色(如果所有的主分片都已经成功启动并且没有未分配的分片)。不过,由于您只运行一个节点,集群状态可能仍然保持黄色,直到添加了更多的节点来容纳副本分片或者明确地将所有索引的副本数设置为 0。

为了进一步确认更改是否完全生效,您可以再次检查集群健康状态:

https://10.0.4.3:9200/_cat/health

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值