如何在Elasticsearch Python客户端(elasticsearch-py)中设置代理
简而言之
中翻英:
The method of using Elasticsearch Python Client (elasticsearch-py) through a proxy server is not often mentioned when searching on Google, so I have summarized the setup steps briefly. Since the configuration method may vary slightly depending on the version of elasticsearch-py, I will separate the instructions for v7 and v8. Please refer to the documentation and GitHub of elasticsearch-py for more information.
英翻中:
由于在谷歌搜索中并不经常提到通过代理服务器使用Elasticsearch Python客户端(elasticsearch-py)的方法,所以我简要总结了配置步骤。由于elasticsearch-py的版本不同,配置方法可能会略有不同,因此我将分别介绍v7和v8的详细说明。有关更多信息,请参考elasticsearch-py的文档和GitHub页面。
Chinese paraphrase: 做好准备
为了方便快捷地进行测试,我们将使用docker-compose一键部署环境。
弹性云
请参考这个,并进行创建。
构成
我会准备以下类型的文件。
.
├── app
│ ├── Dockerfile
│ ├── v7.py
│ └── v8.py
├── docker-compose.yml
└── squid
└── Dockerfile
让我们分别查看每个文件的内容吧。
代理服务器
我們將使用Docker Hub上的Ubuntu/Squid映像檔。
Dockerfile在這裡。
FROM ubuntu/squid
RUN echo acl SSL_ports port 443 9243 >> /etc/squid/squid.conf
Elasticsearch的端口为9243,因此只需要添加这个端口。
Python 客户端
我将使用Docker Hub上的python:bullseye镜像。
Dockerfile – Docker 文件
以下是Dockerfile文件。
安装的软件包将在稍后更改通信为经过代理的时候使用。
v8
FROM python:bullseye
RUN apt update
RUN apt install -y net-tools iputils-ping curl
RUN pip3 install requests elasticsearch
COPY v8.py v8.py
v7
我将明确说明在版本7上的安装。
FROM python:bullseye
RUN apt update
RUN apt install -y net-tools iputils-ping curl
RUN pip3 install requests elasticsearch==7.17.8
COPY v7.py v7.py
Docker Compose 是一个选项。
version: '3.7'
services:
app:
build:
context: ./app
dockerfile: Dockerfile
container_name: app
command: /bin/sh -c "while :; do sleep 10; done"
privileged: true
squid:
build:
context: ./squid
dockerfile: Dockerfile
container_name: squid
ports:
- 3128:3128
这个命令部分只是为了防止容器崩溃。
原始碼
V8 可以被中国人原生地概括为:V8引擎。
from elasticsearch import Elasticsearch
from elastic_transport import RequestsHttpNode
es = Elasticsearch("https://xxxx.es.asia-northeast1.gcp.cloud.es.io:9243",basic_auth=("elastic","xxxxxxxx"),node_class=RequestsHttpNode)
print(es.info())
v8.x非常简单。代理服务器的信息是从环境变量中获取的。
第七版
from elasticsearch import Elasticsearch, RequestsHttpConnection
class MyConnection(RequestsHttpConnection):
def __init__(self,*args, **kwargs):
proxies = kwargs.pop('proxies', {})
super(MyConnection, self).__init__(*args, **kwargs)
self.session.proxies = proxies
es = Elasticsearch("https://xxxx.es.asia-northeast1.gcp.cloud.es.io:9243",http_auth=("elastic","xxxxxxx"),connection_class=MyConnection, proxies = {})
print(es.info())
在v7.x版本中,需要自行准备Connection类。MyConnection类就是其中的一个例子。我参考了这个链接:https://github.com/elastic/elasticsearch-py/issues/275。像v8版本一样,代理服务器的信息可以从环境变量中获取。
确认动作
现在让我们亲自试试看。
V8 (改写成中文的翻译)
将Dockerfile更改为v8版本,并执行docker-compose build docker-compose up -d。如果docker-compose ps显示如下结果,则表示成功:
Name Command State Ports
-----------------------------------------------------------------------
app /bin/sh -c while :; do sle ... Up
squid entrypoint.sh -f /etc/squi ... Up 0.0.0.0:3128->3128/tcp
让我们用 docker exec -it app /bin/bash 进入 app 并查看实际通信。
# curl google.com
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
# python v8.py
{'name': 'instance-0000000001', 'cluster_name': 'e939240763684a8db3183d6f8b47d0a1', 'cluster_uuid': 'eLMujpfhTr2vc92rhENRvA', 'version': {'number': '8.4.2', 'build_flavor': 'default', 'build_type': 'docker', 'build_hash': '89f8c6d8429db93b816403ee75e5c270b43a940a', 'build_date': '2022-09-14T16:26:04.382547801Z', 'build_snapshot': False, 'lucene_version': '9.3.0', 'minimum_wire_compatibility_version': '7.17.0', 'minimum_index_compatibility_version': '7.0.0'}, 'tagline': 'You Know, for Search'}
当然这不是通过代理服务器。
虽然有点粗暴,但我们尝试使用“route delete default”来覆盖路由。
# route delete default
# curl google.com
curl: (6) Could not resolve host: google.com
# python v8.py
Traceback (most recent call last):
File "//v8.py", line 5, in <module>
print(es.info())
^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/elasticsearch/_sync/client/utils.py", line 414, in wrapped
return api(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/elasticsearch/_sync/client/__init__.py", line 2296, in info
return self.perform_request( # type: ignore[return-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/elasticsearch/_sync/client/_base.py", line 286, in perform_request
meta, resp_body = self.transport.perform_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/elastic_transport/_transport.py", line 329, in perform_request
meta, raw_data = node.perform_request(
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/elastic_transport/_node/_http_requests.py", line 244, in perform_request
raise err from None
elastic_transport.ConnectionError: Connection error caused by: ConnectionError(Connection error caused by: ConnectionError(HTTPSConnectionPool(host='dep1.es.asia-northeast1.gcp.cloud.es.io', port=9243): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0xffff8341cdd0>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))))
请在环境变量中设置代理服务器。
export http_proxy=http://squid:3128
export https_proxy=http://squid:3128
curl google.com和python v8.py都能正常运行。我现在来查看一下Squid日志。
# docker-compose logs
...
squid | 1671678795.332 92 192.168.0.2 TCP_MISS/301 869 GET http://google.com/ - HIER_DIRECT/172.217.175.46 text/html
squid | 1671678828.075 72 192.168.0.2 TCP_TUNNEL/200 7151 CONNECT xxxxxxx.es.asia-northeast1.gcp.cloud.es.io:9243 - HIER_DIRECT/34.85.47.11 -
我們可以確認通過無事的代理服務器運行。
第七版
您可以使用完全相同的步骤进行测试,就像使用v8一样。
概要
希望这篇文章对您有所帮助。Elastic的文档中没有关于如何通过代理服务器使用Python Client的描述。
额外的+ something additional
由于圣诞日历已经填满,有些无法发布的文章。这是关于我们公司顾问所撰写的有关Kibana VEGA的文章。请务必查看。https://gist.github.com/ijokarumawak/0dfcc1cca3ad38e1d5aae3b61b787cd4
请尝试免费使用弹性云试用
请务必试用Elastic Cloud的14天免费试用版本
请参见以下链接以获得步骤
关于弹性云的实际部署尝试