Elasticsearch:验证 Elasticsearch Docker 镜像并安装 Elasticsearch

2023年6月12日   |   by mebius

Elasticsearch 可以作为 Docker 镜像使用。 www.docker.elastic.co 上提供了所有已发布的 Docker 图像和标签的列表。 源文件在 Github 中。此软件包包含免费和订阅功能。 开始 30 天试用以试用所有功能。

从 Elasticsearch 8.0 开始,默认启用安全性。 启用安全性后,Elastic Stack 安全功能需要对传输网络层进行 TLS 加密,否则你的集群将无法启动。

安装 Docker Desktop 或 Docker Engine

为你的操作系统安装适当的 Docker 应用程序

注意:确保为 Docker 分配至少 4GiB 的内存。 在 Docker Desktop 中,你可以在首选项 (macOS) 或设置 (Windows) 的高级选项卡上配置资源使用。

拉取 Elasticsearch Docker 镜像

获取 Elasticsearch for Docker 就像针对 Elastic Docker 注册表发出 docker pull 命令一样简单:

docker pull docker.elastic.co/elasticsearch/elasticsearch:8.8.0
$ docker pull docker.elastic.co/elasticsearch/elasticsearch:8.8.0
8.8.0: Pulling from elasticsearch/elasticsearch
16c1e5ae78fc: Already exists 
2a63fecd431d: Pull complete 
c709fa6210ed: Pull complete 
89732bc75041: Pull complete 
a47052f8e9bf: Pull complete 
7f91ecd93209: Pull complete 
af03b547f578: Pull complete 
8931370f2a7b: Pull complete 
ab2e468d9ee0: Pull complete 
5a44f6d27aab: Pull complete 
Digest: sha256:9aaa38551b4d9e655c54d9dc6a1dad24ee568c41952dc8cf1d4808513cfb5f65
Status: Downloaded newer image for docker.elastic.co/elasticsearch/elasticsearch:8.8.0
docker.elastic.co/elasticsearch/elasticsearch:8.8.0

可选:验证 Elasticsearch Docker 镜像签名

虽然这是可选的,但我们强烈建议你验证下载的 Docker 映像中包含的签名,以确保映像有效。

Elastic 镜像使用 Sigstore 项目的一部分 Cosign 进行签名。Cosign 支持在 OCI 注册表中进行容器签名、验证和存储。

为你的操作系统安装适当的 Cosign 应用程序

Elasticsearch v8.8.0 的容器镜像签名验证如下:

wget https://artifacts.elastic.co/cosign.pub 
cosign verify --key cosign.pub docker.elastic.co/elasticsearch/elasticsearch:8.8.0 

%title插图%num

该命令以 JSON 格式打印检查结果和签名负载:

Verification for docker.elastic.co/elasticsearch/elasticsearch:{version} --
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - Existence of the claims in the transparency log was verified offline
  - The signatures were verified against the specified public key

现在你已经验证了 Elasticsearch Docker 镜像签名,你可以启动单节点或多节点集群。

使用 Docker 启动单节点集群

如果你在 Docker 容器中启动单节点 Elasticsearch 集群,系统会自动为你启用和配置安全性。 首次启动 Elasticsearch 时,会自动进行以下安全配置:

  • 为传输层和 HTTP 层生成证书和密钥
  • 传输层安全性 (TLS) 配置设置写入 elasticsearch.yml。
  • 为 elastic 用户生成密码。
  • 为 Kibana 生成注册令牌。

然后你可以启动 Kibana 并输入注册令牌,该令牌的有效期为 30 分钟。 此令牌自动应用 Elasticsearch 集群的安全设置,使用 kibana_system 用户向 Elasticsearch 进行身份验证,并将安全配置写入 kibana.yml。

以下命令启动用于开发或测试的单节点 Elasticsearch 集群。

1)为 Elasticsearch 和 Kibana 创建一个新的 docker 网络

docker network create elastic

提示:如果你已经存在某个网络,你可以使用docker network rm 来删除命名为 network_name 的网络。

$ docker network create elastic
3f510dc3fb931d808c98365b5126dbdda0e8aede4bb503f1f5aeeb8802bdfeb9

2)在 Docker 中启动 Elasticsearch。 为 elastic 用户生成密码并输出到终端,加上用于注册 Kibana 的注册令牌。

docker run -e ES_JAVA_OPTS="-Xms1g -Xmx1g" --name es01 --net elastic -p 9200:9200 -p 9300:9300 -it docker.elastic.co/elasticsearch/elasticsearch:8.8.0

%title插图%num

%title插图%num

提示:你可能需要在终端中向后滚动一点才能查看密码和注册令牌

3)复制生成的密码和注册令牌并将它们保存在安全位置。 这些值仅在你首次启动 Elasticsearch 时显示。

注意:如果需要重置 elastic 用户或其他内置用户的密码,请运行 elasticsearch-reset-password工具。 该工具位于 Docker 容器的 Elasticsearch /bin 目录中。 例如:

docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-reset-password

4)将 http_ca.crt 安全证书从 Docker 容器复制到本地计算机。

docker cp es01:/usr/share/elasticsearch/config/certs/http_ca.crt .
$ pwd
/Users/liuxg/tmp/certs
$ docker cp es01:/usr/share/elasticsearch/config/certs/http_ca.crt .
$ ls
http_ca.crt

5)打开一个新终端,并使用从 Docker 容器复制的 http_ca.crt 文件进行经过身份验证的调用,以验证你是否可以连接到 Elasticsearch 集群。 出现提示时输入弹性用户的密码。

curl --cacert http_ca.crt -u elastic https://localhost:9200
$ curl --cacert http_ca.crt -u elastic https://localhost:9200
Enter host password for user 'elastic':
{
  "name" : "2ea501480d1a",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "xL5JbUBqTN6_-7dUYSSazw",
  "version" : {
    "number" : "8.8.0",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "c01029875a091076ed42cdb3a41c10b1a9a5a20f",
    "build_date" : "2023-05-23T17:16:07.179039820Z",
    "build_snapshot" : false,
    "lucene_version" : "9.6.0",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

我们从上面的 Elasticsearch 启动的窗口中拷贝过来 elastic 超级用户的密码。如果你能看到上面的输出,那么贡献你。你已经成功地在你的电脑上运行起来 Elasticsearch!

添加额外的节点

首次启动 Elasticsearch 时,安装过程默认配置单节点集群。 此过程还会生成注册令牌并将其打印到你的终端。 如果你希望节点加入现有集群,请使用生成的注册令牌启动新节点。

生成注册令牌:

注册令牌的有效期为 30 分钟。 如果你需要生成新的注册令牌,请在现有节点上运行 elasticsearch-create-enrollment-token 工具。 该工具位于 Docker 容器的 Elasticsearch bin 目录中。

例如,在现有的 es01 节点上运行以下命令,为新的 Elasticsearch 节点生成注册令牌:

docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node

1)在启动第一个节点的终端中,复制生成的注册令牌以添加新的 Elasticsearch 节点。

2)在你的新节点上,启动 Elasticsearch 并包含生成的注册令牌。

docker run -e ENROLLMENT_TOKEN="" -e ES_JAVA_OPTS="-Xms1g -Xmx1g" --name es02 --net elastic -it docker.elastic.co/elasticsearch/elasticsearch:8.8.0

%title插图%num

%title插图%num

我们在第一个节点的终端中可以看到如下的信息:

%title插图%num

Elasticsearch 现在配置为加入现有集群。我们可以使用如下的命令来检查现有的 nodes:

curl --cacert http_ca.crt -u elastic https://localhost:9200/_cat/nodes
$ pwd
/Users/liuxg/tmp/certs
$ ls
http_ca.crt
$ curl --cacert http_ca.crt -u elastic https://localhost:9200/_cat/nodes
Enter host password for user 'elastic':
172.18.0.2 13 16 0 0.07 0.13 0.15 cdfhilmrstw * 8904985c21d9
172.18.0.3 48 16 0 0.07 0.13 0.15 cdfhilmrstw - f8a062a42e48

从上面的输出中,我们可以看到集群中有两个节点了。

设置 JVM 堆大小

如果你遇到在第二个节点启动时运行第一个节点的容器退出的问题,请显式设置 JVM 堆大小的值。 要手动配置堆大小,请在启动每个节点时包含 ES_JAVA_OPTS 变量并设置 -Xms 和 -Xmx 的值。 例如,以下命令启动节点 es02 并将最小和最大 JVM 堆大小设置为 1 GB:

docker run -e ES_JAVA_OPTS="-Xms1g -Xmx1g" -e ENROLLMENT_TOKEN="" --name es02 -p 9201:9200 --net elastic -it docker.elastic.co/elasticsearch/elasticsearch:8.8.0

在上面,我们的示例中已经这么做了。在我做练习时,没有定义这个参数,结果就退出了。

下一步

你现在已经设置了测试 Elasticsearch 环境。 在开始认真开发或使用 Elasticsearch 投入生产之前,请查看下面在生产环境中在 Docker 中运行 Elasticsearch 时要应用的要求和建议。

安全证书和密钥

安装 Elasticsearch 时,会在 Elasticsearch 配置目录中生成以下证书和密钥,用于将 Kibana 实例连接到你的安全 Elasticsearch 集群并加密节点间通信。 此处列出这些文件以供参考。

http_ca.crt

用于为此 Elasticsearch 集群的 HTTP 层签署证书的 CA 证书。

http.p12

包含此节点的 HTTP 层的密钥和证书的密钥库。

tranport.p12

包含集群中所有节点的传输层密钥和证书的密钥库。

http.p12 和 transport.p12 是受密码保护的 PKCS#12 密钥库。 Elasticsearch 将这些密钥库的密码存储为安全设置。 要检索密码以便你可以检查或更改密钥库内容,请使用 bin/elasticsearch-keystore 工具。

使用以下命令检索 http.p12 的密码:

bin/elasticsearch-keystore show xpack.security.http.ssl.keystore.secure_password

使用以下命令检索 transport.p12 的密码:

bin/elasticsearch-keystore show xpack.security.transport.ssl.keystore.secure_password
$ docker ps
CONTAINER ID   IMAGE                                                 COMMAND                  CREATED          STATUS          PORTS                                            NAMES
f8a062a42e48   docker.elastic.co/elasticsearch/elasticsearch:8.8.0   "/bin/tini -- /usr/l…"   50 minutes ago   Up 50 minutes   9200/tcp, 9300/tcp                               es02
8904985c21d9   docker.elastic.co/elasticsearch/elasticsearch:8.8.0   "/bin/tini -- /usr/l…"   52 minutes ago   Up 52 minutes   0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   es01
$ docker exec -it es01 /bin/bash
elasticsearch@8904985c21d9:~$ ls
LICENSE.txt  NOTICE.txt  README.asciidoc  bin  config  data  jdk  lib  logs  modules  plugins
elasticsearch@8904985c21d9:~$ cd bin/
elasticsearch@8904985c21d9:~/bin$ cd ..
elasticsearch@8904985c21d9:~$ bin/elasticsearch-keystore show xpack.security.http.ssl.keystore.secure_password
pKee5zKnR6mq32YCFGsBew
elasticsearch@8904985c21d9:~$ bin/elasticsearch-keystore show xpack.security.transport.ssl.keystore.secure_password
Ca7GGTq9Qo2PgGWgPbc6Dg
elasticsearch@8904985c21d9:~$ 

使用 Docker Compose 启动多节点集群

要在启用安全性的 Docker 中启动和运行多节点 Elasticsearch 集群和 Kibana,你可以使用 Docker Compose。

此配置提供了一种启动安全集群的简单方法,你可以在使用多台主机构建分布式部署之前将其用于开发。

先决条件

为你的操作系统安装适当的 Docker 应用程序

如果你在 Linux 上运行,请安装 Docker Compose

注意:确保至少为 Docker 分配了 4GB 内存。 在 Docker Desktop 中,你可以在首选项 (macOS) 或设置 (Windows) 的高级选项卡上配置资源使用。

准备环境

在新的空目录中创建以下配置文件。 这些文件也可以从 GitHub 上的 elasticsearch 存储库中获得。

.env

.env 文件设置运行 docker-compose.yml 配置文件时使用的环境变量。 确保使用 ELASTIC_PASSWORD 和 KIBANA_PASSWORD 变量为 elastic 和 kibana_system 用户指定强密码。 这些变量由 docker-compose.yml 文件引用。

重要:你的密码必须是字母数字,并且不能包含特殊字符,例如! 或者 @。 docker-compose.yml 文件中包含的 bash 脚本仅对字母数字字符起作用。

# Password for the 'elastic' user (at least 6 characters)
ELASTIC_PASSWORD=

# Password for the 'kibana_system' user (at least 6 characters)
KIBANA_PASSWORD=

# Version of Elastic products
STACK_VERSION=8.8.0

# Set the cluster name
CLUSTER_NAME=docker-cluster

# Set to 'basic' or 'trial' to automatically start the 30-day trial
LICENSE=basic
#LICENSE=trial

# Port to expose Elasticsearch HTTP API to the host
ES_PORT=9200
#ES_PORT=127.0.0.1:9200

# Port to expose Kibana to the host
KIBANA_PORT=5601
#KIBANA_PORT=80

# Increase or decrease based on the available host memory (in bytes)
MEM_LIMIT=1073741824

# Project namespace (defaults to the current folder name if not set)
#COMPOSE_PROJECT_NAME=myproject

docker-compose.yml

这个 docker-compose.yml 文件创建了一个启用身份验证和网络加密的三节点安全 Elasticsearch 集群,以及一个安全连接到它的 Kibana 实例。

暴露端口:此配置在所有网络接口上公开端口 9200。 由于 Docker 处理端口的方式,未绑定到 localhost 的端口使你的 Elasticsearch 集群可公开访问,可能会忽略任何防火墙设置。 如果你不想将端口 9200 暴露给外部主机,请将 .env 文件中的 ES_PORT 值设置为类似于 127.0.0.1:9200 的值。 Elasticsearch 将只能从主机本身访问。

version: "2.2"

services:
  setup:
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    volumes:
      - certs:/usr/share/elasticsearch/config/certs
    user: "0"
    command: >
      bash -c '
        if [ x${ELASTIC_PASSWORD} == x ]; then
          echo "Set the ELASTIC_PASSWORD environment variable in the .env file";
          exit 1;
        elif [ x${KIBANA_PASSWORD} == x ]; then
          echo "Set the KIBANA_PASSWORD environment variable in the .env file";
          exit 1;
        fi;
        if [ ! -f config/certs/ca.zip ]; then
          echo "Creating CA";
          bin/elasticsearch-certutil ca --silent --pem -out config/certs/ca.zip;
          unzip config/certs/ca.zip -d config/certs;
        fi;
        if [ ! -f config/certs/certs.zip ]; then
          echo "Creating certs";
          echo -ne 
          "instances:n"
          "  - name: es01n"
          "    dns:n"
          "      - es01n"
          "      - localhostn"
          "    ip:n"
          "      - 127.0.0.1n"
          "  - name: es02n"
          "    dns:n"
          "      - es02n"
          "      - localhostn"
          "    ip:n"
          "      - 127.0.0.1n"
          "  - name: es03n"
          "    dns:n"
          "      - es03n"
          "      - localhostn"
          "    ip:n"
          "      - 127.0.0.1n"
          > config/certs/instances.yml;
          bin/elasticsearch-certutil cert --silent --pem -out config/certs/certs.zip --in config/certs/instances.yml --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key;
          unzip config/certs/certs.zip -d config/certs;
        fi;
        echo "Setting file permissions"
        chown -R root:root config/certs;
        find . -type d -exec chmod 750 {} ;;
        find . -type f -exec chmod 640 {} ;;
        echo "Waiting for Elasticsearch availability";
        until curl -s --cacert config/certs/ca/ca.crt https://es01:9200 | grep -q "missing authentication credentials"; do sleep 30; done;
        echo "Setting kibana_system password";
        until curl -s -X POST --cacert config/certs/ca/ca.crt -u "elastic:${ELASTIC_PASSWORD}" -H "Content-Type: application/json" https://es01:9200/_security/user/kibana_system/_password -d "{"password":"${KIBANA_PASSWORD}"}" | grep -q "^{}"; do sleep 10; done;
        echo "All done!";
      '
    healthcheck:
      test: ["CMD-SHELL", "[ -f config/certs/es01/es01.crt ]"]
      interval: 1s
      timeout: 5s
      retries: 120

  es01:
    depends_on:
      setup:
        condition: service_healthy
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    volumes:
      - certs:/usr/share/elasticsearch/config/certs
      - esdata01:/usr/share/elasticsearch/data
    ports:
      - ${ES_PORT}:9200
    environment:
      - node.name=es01
      - cluster.name=${CLUSTER_NAME}
      - cluster.initial_master_nodes=es01,es02,es03
      - discovery.seed_hosts=es02,es03
      - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
      - bootstrap.memory_lock=true
      - xpack.security.enabled=true
      - xpack.security.http.ssl.enabled=true
      - xpack.security.http.ssl.key=certs/es01/es01.key
      - xpack.security.http.ssl.certificate=certs/es01/es01.crt
      - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.key=certs/es01/es01.key
      - xpack.security.transport.ssl.certificate=certs/es01/es01.crt
      - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.license.self_generated.type=${LICENSE}
    mem_limit: ${MEM_LIMIT}
    ulimits:
      memlock:
        soft: -1
        hard: -1
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'",
        ]
      interval: 10s
      timeout: 10s
      retries: 120

  es02:
    depends_on:
      - es01
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    volumes:
      - certs:/usr/share/elasticsearch/config/certs
      - esdata02:/usr/share/elasticsearch/data
    environment:
      - node.name=es02
      - cluster.name=${CLUSTER_NAME}
      - cluster.initial_master_nodes=es01,es02,es03
      - discovery.seed_hosts=es01,es03
      - bootstrap.memory_lock=true
      - xpack.security.enabled=true
      - xpack.security.http.ssl.enabled=true
      - xpack.security.http.ssl.key=certs/es02/es02.key
      - xpack.security.http.ssl.certificate=certs/es02/es02.crt
      - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.key=certs/es02/es02.key
      - xpack.security.transport.ssl.certificate=certs/es02/es02.crt
      - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.license.self_generated.type=${LICENSE}
    mem_limit: ${MEM_LIMIT}
    ulimits:
      memlock:
        soft: -1
        hard: -1
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "curl -s --cacert config/certstgcode/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'",
        ]
      interval: 10s
      timeout: 10s
      retries: 120

  es03:
    depends_on:
      - es02
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    volumes:
      - certs:/usr/share/elasticsearch/config/certs
      - esdata03:/usr/share/elasticsearch/data
    environment:
      - node.name=es03
      - cluster.name=${CLUSTER_NAME}
      - cluster.initial_master_nodes=es01,es02,es03
      - discovery.seed_hosts=es01,es02
      - bootstrap.memory_lock=true
      - xpack.security.enabled=true
      - xpack.security.http.ssl.enabled=true
      - xpack.security.http.ssl.key=certs/es03/es03.key
      - xpack.security.http.ssl.certificate=certs/es03/es03.crt
      - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.key=certs/es03/es03.key
      - xpack.security.transport.ssl.certificate=certs/es03/es03.crt
      - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.license.self_generated.type=${LICENSE}
    mem_limit: ${MEM_LIMIT}
    ulimits:
      memlock:
        soft: -1
        hard: -1
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'",
        ]
      interval: 10s
      timeout: 10s
      retries: 120

  kibana:
    depends_on:
      es01:
        condition: service_healthy
      es02:
        condition: servitgcodece_healthy
      es03:
        condition: service_healthy
    image: docker.elastic.co/kibana/kibana:${STACK_VERSION}
    volumes:
      - certs:/usr/share/kibana/config/certs
      - kibanadata:/usr/share/kibana/data
    ports:
      - ${KIBANA_PORT}:5601
    environment:
      - SERVERNAME=kibana
      - ELASTICSEARCH_HOSTS=https://es01:9200
      - ELASTICSEARCH_USERNAME=kibana_system
      - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD}
      - ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=config/certs/ca/ca.crt
    mem_limit: ${MEM_LIMIT}
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'",
        ]
      interval: 10s
      timeout: 10s
      retries: 120

volumes:
  certs:
    driver: local
  esdata01:
    driver: local
  esdata02:
    driver: local
  esdata03:
    driver: local
  kibanadata:
    driver: local

在启用和配置安全性的情况下启动集群

1)修改 .env 文件并为 ELASTIC_PASSWORD 和 KIBANA_PASSWORD 变量输入强密码值。

注意:你必须使用 ELASTIC_PASSWORD 值才能与集群进一步交互。 KIBANA_PASSWORD 值仅在配置 Kibana 时在内部使用。

2)创建并启动三节点 Elasticsearch 集群和 Kibana 实例:

docker-comptgcodeose up -d

3)部署开始后,打开浏览器并导航至 http://localhost:5601 以访问 Kibana,你可以在其中加载示例数据并与集群交互。

停止并删除部署

要停止集群,请运行 docker-compose down。 当你使用 docker-compose up 重新启动集群时,Docker 卷中的数据将被保留和加载。

docker-compose down

要在停止集群时删除网络、容器和卷,请指定 -v 选项:

docker-compose down -v

下一步

你现在已经设置了测试 Elasticsearch 环境。 在开始认真开发或使用 Elasticsearch 投入生产之前,请查看下面在生产环境中在 Docker 中运行 Elasticsearch 时要应用的要求和建议。

在生产环境中使用 Docker 镜像

在生产中的 Docker 中运行 Elasticsearch 时,以下要求和建议适用。

将 vm.max_map_count 设置为至少 262144

vm.max_map_count 内核设置必须至少设置为 262144 才能用于生产。

如何设置 vm.max_map_count 取决于你的平台。

Linux

要查看 vm.max_map_count 设置的当前值,请运行:

grep vm.max_map_count /etc/sysctl.conf
vm.max_map_count=262144

要在实时系统上应用设置,请运行:

sysctl -w vm.max_map_count=262144

要永久更改 vm.max_map_count 设置的值,请更新 /etc/sysctl.conf 中的值。

适用于 Mac 的 macOS 和 Docker

vm.max_map_count 设置必须在 xhyve 虚拟机中设置:

1)从命令行运行:

screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty

2)按 enter 并使用 sysctl 配置 vm.max_map_count:

sysctl -w vm.max_map_count=262144

3)要退出屏幕会话,请键入 Ctrl a d。

Windows 和 macOS 与 Docker 桌面

vm.max_map_count 设置必须通过 docker-machine 设置:

docker-machine ssh
sudo sysctl -w vm.max_map_count=262144

带有 Docker Desktop WSL 2 后端的 Windows

在 Elasticsearch 容器正确启动之前,必须在 “docker-desktop” WSL 实例中设置 vm.max_map_count 设置。 有多种方法可以执行此操作,具体取决于你的 Windows 版本和 WSL 版本。

如果你在 Windows 10 版本 22H2 之前,或者如果你在 Windows 10 版本 22H2 使用内置版本的 WSL,则必须在每次启动 Elasticsearch 容器之前重新启动 Docker 时手动设置它,或者(如果你这样做 不希望在每次重新启动时都这样做)你必须全局设置每个 WSL2 实例以更改 vm.max_map_count。 这是因为这些版本的 WSL 无法正确处理 /etc/sysctl.conf 文件。

要在每次重新启动时手动设置它,你必须在每次重新启动 Docker 时在命令提示符或 PowerShell 窗口中运行以下命令:

wsl -d docker-desktop -u root
sysctl -w vm.max_map_count=262144

如果你使用的是这些版本的 WSL,并且不想在每次重新启动 Docker 时都运行这些命令,则可以通过修改 %USERPROFILE%.wslconfig 来全局更改具有此设置的每个 WSL 发行版,如下所示:

[wsl2]
kernelCommandLine = "sysctl.vm.max_map_count=262144"

这将导致所有 WSL2 VM 在启动时分配该设置。

如果你使用的是 Windows 11 或 Windows 10 版本 22H2 并且安装了 Microsoft Store 版本的 WSL,则可以修改 “docker-desktop” WSL 分发版中的 /etc/sysctl.conf,可能使用如下命令:

wsl -d docker-desktop -u root
vi /etc/sysctl.conf
并附加一行内容如下:
vm.max_map_count = 262144

配置文件必须是 elasticsearch 用户可读的

默认情况下,Elasticsearch 使用 uid:gid 1000:0 作为用户 elasticsearch 在容器内运行。

重要:一个例外是 Openshift,它使用任意分配的用户 ID 运行容器。 Openshift 提供 gid 设置为 0 的持久卷,无需任何调整即可工作。

如果你正在绑定挂载本地目录或文件,则它必须可被 elasticsearch 用户读取。 此外,此用户必须具有对配置、数据和日志目录的写入权限(Elasticsearch 需要对配置目录的写入权限,以便它可以生成密钥库)。 一个好的策略是授予组访问本地目录的 gid 0。

例如,通过绑定挂载准备一个用于存储数据的本地目录:

mkdir esdatadir
chmod g+rwx esdatadir
chgrp 0 esdatadir

你还可以使用自定义 UID 和 GID 运行 Elasticsearch 容器。 你必须确保文件权限不会阻止 Elasticsearch 执行。 你可以使用以下两个选项之一:

  • 绑定挂载 config、data 和 logs 目录。 如果你打算安装插件并且不想创建自定义 Docker 映像,则还必须绑定挂载插件目录。
  • 将 –group-add 0 命令行选项传递给 docker run。 这可确保运行 Elasticsearch 的用户也是容器内根 (GID 0) 组的成员。

增加 nofile 和 nproc 的 ulimits

增加的 nofilenproc 的 ulimits 必须可用于 Elasticsearch 容器。 验证 Docker 守护进程的 init system 将它们设置为可接受的值。

要检查 ulimits 的 Docker 守护程序默认值,请运行:

docker run --rm docker.elastic.co/elasticsearch/elasticsearch:{version} /bin/bash -c 'ulimit -Hn && ulimit -Sn && ulimit -Hu && ulimit -Su'

如果需要,在守护进程中调整它们或按容器覆盖它们。 例如,使用 docker run 时,设置:

--ulimit nofile=65535:65535

禁用 swapping

为了性能和节点稳定性,需要禁用 swapping。 有关执行此操作的方法的信息,请参阅 disable swapping

如果你选择 bootstrap.memory_lock: true 方法,你还需要在 Docker 守护进程中定义 memlock: true ulimit,或者如上面展示的示例 compose 文件中所示为容器明确设置。 使用 docker run 时,你可以指定:

-e "bootstrap.memory_lock=true" --ulimit memlock=-1:-1

随机化已发布的端口

该镜像公开了 TCP 端口 9200 和 9300。对于生产集群,建议使用 –publish-all 随机化已发布的端口,除非你为每个主机固定一个容器。

手动设置堆大小

默认情况下,Elasticsearch 根据节点的角色和节点容器可用的总内存自动调整 JVM 堆的大小。 对于大多数生产环境,我们建议使用此默认大小。 如果需要,你可以通过手动设置 JVM 堆大小来覆盖默认大小。

要在生产环境中手动设置堆大小,请在 /usr/share/elasticsearch/config/jvm.options.d 下绑定一个 JVM 选项文件,其中包含你所需的堆大小设置。

对于测试,你还可以使用 ES_JAVA_OPTS 环境变量手动设置堆大小。 例如,要使用 16GB,请指定 -e
ES_JAVA_OPTS=”-Xms16g -Xmx16g” 与 docker 运行。 ES_JAVA_OPTS 变量覆盖所有其他 JVM 选项。 我们不建议在生产中使用 ES_JAVA_OPTS。 上面的 docker-compose.yml 文件将堆大小设置为 512MB。

将部署固定到特定映像版本

将你的部署固定到特定版本的 Elasticsearch Docker 映像。 例如 docker.elastic.co/elasticsearch/elasticsearch:8.8.0。

始终绑定数据卷

出于以下原因,你应该使用绑定在 /usr/share/elasticsearch/data 上的卷:

  1. 如果容器被杀死,你的 Elasticsearch 节点的数据不会丢失
  2. Elasticsearch 对 I/O 敏感,而 Docker 存储驱动程序不适合快速 I/O
  3. 它允许使用高级 Docker 卷插件

避免使用 loop-lvm 模式

如果你正在使用 devicemapper 存储驱动程序,请不要使用默认的 loop-lvm 模式。 配置 docker-engine 以使用 direct-lvm

集中你的日志

考虑使用不同的日志记录驱动程序来集中你的日志。 另请注意,默认的 json 文件日志记录驱动程序并不非常适合生产使用。

使用 Docker 配置 Elasticsearch

当你在 Docker 中运行时,Elasticsearch 配置文件从 /usr/share/elasticsearch/config/ 加载。

要使用自定义配置文件,你可以将文件绑定安装在镜像中的配置文件之上。

你可以使用 Docker 环境变量设置单独的 Elasticsearch 配置参数。 上面示例组合文件和单节点示例使用此方法。 你可以直接使用设置名称作为环境变量名称。 如果你不能这样做,例如因为你的编排平台禁止在环境变量名称中使用句点,那么你可以通过如下转换设置名称来使用替代样式。

  1. 将设置名称更改为大写
  2. 前缀为 ES_SETTING_
  3. 通过复制转义任何下划线 (_)
  4. 将所有句点 (.) 转换为下划线 (_)

例如,-e bootstrap.memory_lock=true 变为 -e ES_SETTING_BOOTSTRAP_MEMORY__LOCK=true。

你可以使用文件的内容来设置 ELASTIC_PASSWORD 或 KEYSTORE_PASSWORD 环境变量的值,方法是在环境变量名称后加上 _FILE。 这对于将密码(例如密码)传递给 Elasticsearch 而无需直接指定它们很有用。

例如,要从文件设置 Elasticsearch 引导程序密码,你可以绑定挂载文件并将 ELASTIC_PASSWORD_FILE 环境变量设置为挂载位置。 如果将密码文件挂载到 /run/secrets/bootstrapPassword.txt,请指定:

-e ELASTIC_PASSWORD_FILE=/run/secrets/bootstrapPassword.txt

你可以覆盖图像的默认命令,以将 Elasticsearch 配置参数作为命令行选项传递。 例如:

docker run  bin/elasticsearch -Ecluster.name=mynewclustername

虽然绑定安装配置文件通常是生产中的首选方法,但你也可以创建包含你的配置的自定义 Docker 映像。

挂载 Elasticsearch 配置文件

创建自定义配置文件并将它们绑定挂载到 Docker 映像中的相应文件上。 例如,要使用 docker run 绑定挂载 custom_elasticsearch.yml,请指定:

-v full_path_to/custom_elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

如果绑定挂载自定义 elasticsearch.yml 文件,请确保它包含 network.host: 0.0.0.0 设置。 此设置可确保节点可访问 HTTP 和传输流量,前提是其端口已公开。 Docker 镜像的内置 elasticsearch.yml 文件默认包含此设置。

重要:容器使用 uid:gid 1000:0 作为用户 elasticsearch 运行 Elasticsearch。 绑定挂载的主机目录和文件必须可以被该用户访问,数据和日志目录必须可以被该用户写入。

创建加密的 Elasticsearch 密钥库

默认情况下,Elasticsearch 会自动生成用于安全设置的密钥库文件。 此文件经过混淆但未加密。

要使用密码加密你的安全设置并让它们在容器外保留,请使用 docker run 命令手动创建密钥库。 命令必须:

  • 绑定挂载 config 目录。 该命令将在此目录中创建一个 elasticsearch.keystore 文件。 为避免错误,请勿直接绑定挂载 elasticsearch.keystore 文件。
  • 使用带有 create -p 选项的 elasticsearch-keystore 工具。 系统将提示你输入密钥库的密码。

例如:

docker run -it --rm 
-v full_path_to/config:/usr/share/elasticsearch/config 
docker.elastic.co/elasticsearch/elasticsearch:8.8.0 
bin/elasticsearch-keystore create -p

你还可以使用 docker run 命令添加或更新密钥库中的安全设置。 系统将提示你输入设置值。 如果密钥库已加密,系统还会提示你输入密钥库密码。

docker run -it --rm 
-v full_path_to/config:/usr/share/elasticsearch/config 
docker.elastic.co/elasticsearch/elasticsearch:8.8.0 
bin/elasticsearch-keystore 
add my.secure.setting 
my.other.secure.setting

如果你已经创建了密钥库并且不需要更新它,则可以直接绑定挂载 elasticsearch.keystore 文件。你可以使用 KEYSTORE_PASSWORD 环境变量在启动时向容器提供密钥库密码。 例如,docker run 命令可能有以下选项:

-v full_path_to/config/elasticsearch.keystore:/usr/share/elasticsearch/config/elasticsearch.keystore
-e KEYSTORE_PASSWORD=mypassword

使用自定义 Docker 镜像

在某些环境中,准备包含你的配置的自定义映像可能更有意义。 实现此目的的 Dockerfile 可能非常简单:

FROM docker.elastic.co/elasticsearch/elasticsearch:8.8.0
COPY --chown=elasticsearch:elasticsearch elasticsearch.yml /usr/share/elasticsearch/config/

然后你可以构建并运行镜像:

docker build --tag=elasticsearch-custom .
docker run -ti -v /usr/share/elasticsearch/data elasticsearch-custom

一些插件需要额外的安全权限。 你必须通过以下方式明确接受它们:

  • 在运行 Docker 映像时附加 tty,并在出现提示时允许权限。
  • 通过将 –batch 标志添加到插件安装命令来检查安全权限并接受它们(如果适用)。

有关更多信息,请参阅插件管理

排查 Elasticsearch 的 Docker 错误

以下是使用 Docker 运行 Elasticsearch 时解决常见错误的方法。

elasticsearch.keystore 是一个目录

Exception in thread "main" org.elasticsearch.bootstrap.BootstrapException: java.io.IOException: Is a directory: SimpleFSIndexInput(path="/usr/share/elasticsearch/config/elasticsearch.keystore") Likely root cause: java.io.IOException: Is a directory

与密钥库相关的 docker run 命令试图直接绑定挂载不存在的 elasticsearch.keystore 文件。 如果你使用 -v 或 –volume 标志挂载一个不存在的文件,Docker 会创建一个同名目录。

要解决此错误:

  1. 删除 config 目录下的 elasticsearch.keystore 目录。
  2. 更新 -v 或 –volume 标志以指向配置目录路径而不是密钥库文件的路径。 有关示例,请参阅创建加密的 Elasticsearch 密钥库
  3. 重试该命令。

elasticsearch.keystore: Device or resource busy

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

docker run 命令尝试在直接绑定挂载 elasticsearch.keystore 文件时更新密钥库。 要更新密钥库,容器需要访问配置目录中的其他文件,例如 keystore.tmp。

要解决此错误:

更多阅读:Kibana:使用 Docker 安装 Kibana – 8.x

文章来源于互联网:Elasticsearch:验证 Elasticsearch Docker 镜像并安装 Elasticsearch