作者:来自 Elastic Philipp Krenn
Kibana 的控制台是开始使用 Elasticsearch 的 REST API 的最简单方法 - 语法突出显示、自动完成、格式化、导出 cURL、JavaScript 或 Python。而且你不必担心正确的端点、身份验证等。但是有时,如果 Kibana 不可用、你必须自动化某些操作,或者你想将输出用作另一个命令行工具的输入,则需要(或想要)使用 shell。本文简要概述了最常见的问题、绊脚石以及一些使用 cURL 的有用技巧。
端点 - endpoint
本文中的所有示例对 Elasticsearch 使用 https://localhost:9200,对 Kibana 使用 https://localhost:5601。但对于你的安装,你可能需要调整协议(http 或 https)、主机(localhost、(子)域或 IP)或端口(默认为 9200 和 5601)。
提示:如果你还没有安装好自己的 Elasticsearch 或 Kibana,请参阅文章 "如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch" 及 "Kibana:如何在 Linux,MacOS 及 Windows 上安装 Elastic 栈中的 Kibana"。
如果你使用了错误的设置,你可能会遇到类似 curl 的错误:curl: (7) Failed to connect to localhost port 9201 after 0 ms: Could not connect to server 或 cURL 等待请求超时。
TLS
根据你的部署和配置,你可能没有 TLS(仅纯文本 HTTP)或 TLS(仅 HTTPS,自签名或具有有效证书)。
你将收到的最常见错误消息是:
- curl: (35) TLS connect error: error:0A0000C6:SSL routines::packet length too long(如果你使用 HTTPS 进行 HTTP 配置)。请改用 http://。
- curl: (52) Empty reply from server 如果你使用 HTTP 进行 HTTPS 配置。请改用 https://。
- 如果你使用自签名证书,可能会出现以下错误:
curl: (60) SSL peer certificate or SSH remote key was not OK
。通过添加 -k 参数(如 curl -k https://localhost:9200)忽略证书错误,或引用自生成的证书文件(如 curl --cacert certs/http_ca.crt https://localhost:9200)。
身份验证
身份验证是入门过程中最常见但也是令人沮丧的绊脚石之一。错误的身份验证通常会引发以下错误:
{
"error" : {
"root_cause" : [
{
"type" : "security_exception",
"reason" : "unable to authenticate user [elastic] for REST request [/?pretty]",
"header" : {
"WWW-Authenticate" : [
"Basic realm=\"security\", charset=\"UTF-8\"",
"Bearer realm=\"security\"",
"ApiKey"
]
}
}
],
"type" : "security_exception",
"reason" : "unable to authenticate user [elastic] for REST request [/?pretty]",
"header" : {
"WWW-Authenticate" : [
"Basic realm=\"security\", charset=\"UTF-8\"",
"Bearer realm=\"security\"",
"ApiKey"
]
}
},
"status" : 401
}
基本身份验证 - Basic Auth
基本身份验证是针对 REST API 进行身份验证的经典方式。虽然它是当今使用最广泛的选项,但 Elasticsearch Serverless 并不支持它。但对于自管理集群或托管 Elastic Cloud,它是默认选择。
虽然你应该使用正确的权限集配置自定义用户,但本文跳过授权并坚持使用默认超级用户 elastic。
最简单的身份验证形式是 curl -XGET -u elastic:... "https://localhost:9200/",你需要将 ... 替换为 elastic 用户的密码。运行此命令的副作用是你的密码将成为 shell 历史记录的一部分。如果你想避免这种情况,你可以:
- 运行 curl -XGET -u elastic "https://localhost:9200/" 并在提示时输入密码。
- 在命令前添加一个空格,即在 curl 之前添加一个空格,这会将其从历史记录中排除。
API 密钥
如果你使用的是 Serverless 项目或已配置 API 密钥,则可以使用 curl -XGET -H "Authorization: ApiKey ..." "https://localhost:9200/" 来使用它,其中你需要将 ... 替换为你的 API 密钥。请确保 ApiKey 和密钥之间有一个空格 --- 两个空格或多个空格都将无法验证你的身份。
另一个经常引起混淆的部分是 Elastic Cloud 帐户还具有用于管理集群的 API 密钥(例如通过 Terraform 进行配置)。不要将此管理 API 密钥与用于访问单个集群上数据的密钥混淆;即使两者都是 API 密钥。
cURL 参数
如果你想深入了解所有可用选项,man curl 是最好的地方,尽管内容非常广泛。对于几个简单示例,tldr(无论是在网站上还是在安装时)都是使用 tldr curl 的绝佳起点。
我们已经在 TLS 部分中查看了 -k 参数。
另一个方便且更新的选项是 --json。默认情况下,在请求中包含 JSON 主体时,你需要几个参数:
curl -XGET -u elastic -H "Content-Type: application/json" -d '{"query":{"match_all":{}}}' "https://localhost:9200/_all/_search"
记住或输入 -H "Content-Type: application/json" 并不好。但你不必再这样做了,因为 --json 正在执行相同的请求:
Elasticsearch 参数
同时,Elasticsearch 还具有一些有用的参数,可让你的 shell 生活更加轻松。例如,将 ?pretty 添加到你的请求中以获取漂亮的打印输出。
或者将 ?v(表示详细)添加到你的 _cat 查询中以包含每个列名。把下面的格式调整:
curl -XGET -u elastic "https://localhost:9200/_cat/nodes"
172.20.138.162 54 90 1 1.77 1.76 1.61 mv - tiebreaker-0000000003
172.20.140.25 75 100 0 0.85 1.18 1.39 himrst - instance-0000000001
172.20.143.14 12 48 0 0.71 0.85 1.07 lr - instance-0000000002
172.20.139.42 53 100 0 2.09 1.84 1.83 himrst * instance-0000000000
为:
curl -XGET -u elastic "https://localhost:9200/_cat/nodes?v"
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
172.20.138.162 36 90 0 2.33 2.41 1.93 mv - tiebreaker-0000000003
172.20.140.25 82 100 0 2.20 1.77 1.59 himrst - instance-0000000001
172.20.143.14 16 48 0 0.59 0.81 1.01 lr - instance-0000000002
172.20.139.42 71 99 0 2.27 1.70 1.75 himrst * instance-0000000000
更多工具
一旦请求开始工作,shell 的真正威力就会开始显现:组合多个命令。
如果你的响应是 JSON(因此排除之前的 _cat API),jq 可能是最有用的工具。例如,查看长输出:
curl -XGET -u elastic "https://localhost:9200/_nodes/stats?pretty"
{
"_nodes" : {
"total" : 4,
"successful" : 4,
"failed" : 0
},
"cluster_name" : "21b3293a6efe45d289bed311a2213320",
"nodes" : {
...
如果我们只对总数和成功节点感兴趣,那么也可以在流程中将其重命名为成功:jq 为我们提供了所需的所有功能(尽管它可能很难使用 - 如果有疑问,请务必查阅文档或 ChatGPT):
curl -XGET --silent -u elastic "https://localhost:9200/_nodes/stats" | jq "{total: ._nodes.total, success: ._nodes.successful}"
{
"total": 4,
"success": 4
}
如果你正在使用 _cat API,那么 awk 值得再看一看;或者可能是 sed、cut......这取决于任务和偏好。从索引列表开始:
curl -XGET --silent -u elastic "https://localhost:9200/_cat/indices"
green open starwars 4auEgBXQTHSrxlshmdCgHg 1 1 2 0 19.6kb 9.8kb 9.8kb
green open semantic-starwars X2Q2XhxQR9CUWiMbnmUgUg 1 1 4 0 67.5kb 33.7kb 33.7kb
如果只想提取索引名称然后按字母顺序排序:
curl -XGET --silent -u elastic "https://localhost:9200/_cat/indices" | awk '{ print $3 }' | sort
semantic-starwars
starwars
结论
这只是一个入门指南。一旦你掌握了基础知识,调试和自动化的可能性几乎是无限的。继续使用 Shell!