连接编辑

此页面包含使用 Elasticsearch 连接客户端所需的信息。

连接到 Elastic Cloud编辑

Elastic Cloud 是 Elasticsearch 入门的最佳方式。使用 Python Elasticsearch 客户端连接到 Elastic Cloud 时,您应始终使用 cloud_id 参数进行连接。您可以在创建集群后在“管理部署”页面中找到此值(如果您在 Kibana 中,请查看左上角)。

我们建议尽可能使用云 ID,因为您的客户端将自动配置为与 Elastic Cloud 最佳使用,包括 HTTPS 和 HTTP 压缩。

from elasticsearch import Elasticsearch

# Password for the 'elastic' user generated by Elasticsearch
ELASTIC_PASSWORD = "<password>"

# Found in the 'Manage Deployment' page
CLOUD_ID = "deployment-name:dXMtZWFzdDQuZ2Nw..."

# Create the client instance
client = Elasticsearch(
    cloud_id=CLOUD_ID,
    basic_auth=("elastic", ELASTIC_PASSWORD)
)

# Successful response!
client.info()
# {'name': 'instance-0000000000', 'cluster_name': ...}

连接到自管集群编辑

默认情况下,Elasticsearch 将启用身份验证和 TLS 等安全功能。要连接到 Elasticsearch 集群,您需要将 Python Elasticsearch 客户端配置为将 HTTPS 与生成的 CA 证书一起使用,以便成功发出请求。

如果您刚开始使用 Elasticsearch,我们建议您阅读有关 配置启动 Elasticsearch 的文档,以确保您的集群按预期运行。

首次启动 Elasticsearch 时,您将在 Elasticsearch 的输出中看到一个类似于下面的独特块(如果已经有一段时间了,您可能需要向上滚动)

----------------------------------------------------------------
-> Elasticsearch security features have been automatically configured!
-> Authentication is enabled and cluster connections are encrypted.

->  Password for the elastic user (reset with `bin/elasticsearch-reset-password -u elastic`):
  lhQpLELkjkrawaBoaz0Q

->  HTTP CA certificate SHA-256 fingerprint:
  a52dd93511e8c6045e21f16654b77c9ee0f34aea26d9f40320b531c474676228
...
----------------------------------------------------------------

记下 elastic 用户密码和 HTTP CA 指纹,以供下一节使用。在下面的示例中,它们将分别存储在变量 ELASTIC_PASSWORDCERT_FINGERPRINT 中。

根据情况,有两种验证 HTTPS 连接的选项,可以使用 CA 证书本身进行验证,也可以通过 HTTP CA 证书指纹进行验证。

使用 CA 证书验证 HTTPS编辑

使用 ca_certs 选项是 Python Elasticsearch 客户端验证 HTTPS 连接的默认方式。

生成的根 CA 证书位于 Elasticsearch 配置位置的 certs 目录中($ES_CONF_PATH/certs/http_ca.crt)。如果您在 Docker 中运行 Elasticsearch,则有 有关检索 CA 证书的其他文档

http_ca.crt 文件放在可访问的位置后,通过 ca_certs 将路径传递给客户端

from elasticsearch import Elasticsearch

# Password for the 'elastic' user generated by Elasticsearch
ELASTIC_PASSWORD = "<password>"

# Create the client instance
client = Elasticsearch(
    "https://127.0.0.1:9200",
    ca_certs="/path/to/http_ca.crt",
    basic_auth=("elastic", ELASTIC_PASSWORD)
)

# Successful response!
client.info()
# {'name': 'instance-0000000000', 'cluster_name': ...}

如果您没有指定 ca_certsssl_assert_fingerprint,则默认情况下,如果可用,将使用 certifi 包 作为 ca_certs

使用证书指纹验证 HTTPS(Python 3.10 或更高版本)编辑

使用此方法需要使用 Python 3.10 或更高版本,并且在使用 aiohttp HTTP 客户端库时不可用,因此不能与 AsyncElasticsearch 一起使用。

这种验证 HTTPS 连接的方法利用了前面记下的证书指纹值。获取此 SHA256 指纹值,并通过 ssl_assert_fingerprint 将其传递给 Python Elasticsearch 客户端

from elasticsearch import Elasticsearch

# Fingerprint either from Elasticsearch startup or above script.
# Colons and uppercase/lowercase don't matter when using
# the 'ssl_assert_fingerprint' parameter
CERT_FINGERPRINT = "A5:2D:D9:35:11:E8:C6:04:5E:21:F1:66:54:B7:7C:9E:E0:F3:4A:EA:26:D9:F4:03:20:B5:31:C4:74:67:62:28"

# Password for the 'elastic' user generated by Elasticsearch
ELASTIC_PASSWORD = "<password>"

client = Elasticsearch(
    "https://127.0.0.1:9200",
    ssl_assert_fingerprint=CERT_FINGERPRINT,
    basic_auth=("elastic", ELASTIC_PASSWORD)
)

# Successful response!
client.info()
# {'name': 'instance-0000000000', 'cluster_name': ...}

可以使用 openssl x509 和证书文件计算证书指纹

openssl x509 -fingerprint -sha256 -noout -in /path/to/http_ca.crt

如果您无权访问 Elasticsearch 生成的 CA 文件,则可以使用以下脚本通过 openssl s_client 输出 Elasticsearch 实例的根 CA 指纹

# Replace the values of 'localhost' and '9200' to the
# corresponding host and port values for the cluster.
openssl s_client -connect localhost:9200 -servername localhost -showcerts </dev/null 2>/dev/null \
  | openssl x509 -fingerprint -sha256 -noout -in /dev/stdin

openssl x509 的输出如下所示

SHA256 Fingerprint=A5:2D:D9:35:11:E8:C6:04:5E:21:F1:66:54:B7:7C:9E:E0:F3:4A:EA:26:D9:F4:03:20:B5:31:C4:74:67:62:28

在未启用安全性的情况下连接编辑

不建议在未启用安全性的情况下运行 Elasticsearch。

如果您的集群配置为 明确禁用了安全性,则可以通过 HTTP 进行连接

from elasticsearch import Elasticsearch

# Create the client instance
client = Elasticsearch("https://127.0.0.1:9200")

# Successful response!
client.info()
# {'name': 'instance-0000000000', 'cluster_name': ...}

连接到多个节点编辑

Python Elasticsearch 客户端支持将 API 请求发送到集群中的多个节点。这意味着工作将更均匀地分布在集群中,而不是反复使用请求攻击同一个节点。要使用多个节点配置客户端,您可以传递一个 URL 列表,每个 URL 将用作池中的单独节点。

from elasticsearch import Elasticsearch

# List of nodes to connect use with different hosts and ports.
NODES = [
    "https://127.0.0.1:9200",
    "https://127.0.0.1:9201",
    "https://127.0.0.1:9202",
]

# Password for the 'elastic' user generated by Elasticsearch
ELASTIC_PASSWORD = "<password>"

client = Elasticsearch(
    NODES,
    ca_certs="/path/to/http_ca.crt",
    basic_auth=("elastic", ELASTIC_PASSWORD)
)

默认情况下,使用循环法选择节点,但可以使用 node_selector_class 参数配置备用节点选择策略。

如果您的 Elasticsearch 集群位于负载均衡器之后(例如使用 Elastic Cloud 时),则无需配置多个节点。而是使用负载均衡器主机和端口。

身份验证编辑

本节包含代码片段,向您展示如何连接到各种 Elasticsearch 提供程序。客户端构造函数或每个请求的 .options() 方法都支持所有身份验证方法

from elasticsearch import Elasticsearch

# Authenticate from the constructor
client = Elasticsearch(
    "https://127.0.0.1:9200",
    ca_certs="/path/to/http_ca.crt",
    basic_auth=("username", "password")
)

# Authenticate via the .options() method:
client.options(
    basic_auth=("username", "password")
).indices.get(index="*")

# You can persist the authenticated client to use
# later or use for multiple API calls:
auth_client = client.options(api_key="api_key")
for i in range(10):
    auth_client.index(
        index="example-index",
        document={"field": i}
    )

HTTP 基本身份验证(用户名和密码)编辑

HTTP 基本身份验证使用 basic_auth 参数,方法是在元组中传递用户名和密码

from elasticsearch import Elasticsearch

# Adds the HTTP header 'Authorization: Basic <base64 username:password>'
client = Elasticsearch(
    "https://127.0.0.1:9200",
    ca_certs="/path/to/http_ca.crt",
    basic_auth=("username", "password")
)

HTTP 持有者身份验证编辑

HTTP 持有者身份验证使用 bearer_auth 参数,方法是将令牌作为字符串传递。此身份验证方法由 服务帐户令牌持有者令牌 使用。

from elasticsearch import Elasticsearch

# Adds the HTTP header 'Authorization: Bearer token-value'
client = Elasticsearch(
    "https://127.0.0.1:9200",
    bearer_auth="token-value"
)

API 密钥身份验证编辑

您可以将客户端配置为使用 Elasticsearch 的 API 密钥连接到您的集群。这些可以通过 Elasticsearch 创建 API 密钥 APIKibana 堆栈管理 生成。

from elasticsearch import Elasticsearch

# Adds the HTTP header 'Authorization: ApiKey <base64 api_key.id:api_key.api_key>'
client = Elasticsearch(
    "https://127.0.0.1:9200",
    ca_certs="/path/to/http_ca.crt",
    api_key="api_key",
)

启用兼容模式编辑

Elasticsearch 服务器版本 8.0 引入了一种新的兼容模式,可以让您从 7 到 8 的升级体验更加顺畅。简而言之,您可以将最新的 7.x Python Elasticsearch 客户端与 8.x Elasticsearch 服务器一起使用,从而为将代码库升级到下一个主要版本提供更多空间。

如果您想利用此功能,请确保您使用的是最新的 7.x Python Elasticsearch 客户端,并将环境变量 ELASTIC_CLIENT_APIVERSIONING 设置为 true。客户端在内部处理其余部分。对于每个 8.0 及更高版本的 Python Elasticsearch 客户端,您都已准备就绪!默认情况下启用兼容模式。

在函数即服务环境中使用客户端编辑

本节说明了在函数即服务 (FaaS) 环境中利用 Elasticsearch 客户端的最佳实践。

最有影响力的优化是在函数外部(全局范围)初始化客户端。

这种做法不仅可以提高性能,还可以启用后台功能,例如 嗅探。以下示例提供了最佳实践的框架。

不应在函数即服务中使用异步客户端,因为必须为每次调用启动一个新的事件循环。建议使用同步 Elasticsearch 客户端。

GCP 云函数编辑

from elasticsearch import Elasticsearch

# Client initialization
client = Elasticsearch(
    cloud_id="deployment-name:ABCD...",
    api_key=...
)

def main(request):
    # Use the client
    client.search(index=..., query={"match_all": {}})

AWS Lambda编辑

from elasticsearch import Elasticsearch

# Client initialization
client = Elasticsearch(
    cloud_id="deployment-name:ABCD...",
    api_key=...
)

def main(event, context):
    # Use the client
    client.search(index=..., query={"match_all": {}})

Azure 函数编辑

import azure.functions as func
from elasticsearch import Elasticsearch

# Client initialization
client = Elasticsearch(
    cloud_id="deployment-name:ABCD...",
    api_key=...
)

def main(request: func.HttpRequest) -> func.HttpResponse:
    # Use the client
    client.search(index=..., query={"match_all": {}})

用于评估这些建议的资源