如何在 docker 容器中使用 python 脚本 运行 创建(docker 化)Elasticsearch 索引?
How do I create a (dockerized) Elasticsearch index using a python script running in a docker container?
我正在尝试使用从脚本调用的 Python 客户端 https://github.com/elastic/elasticsearch-py(也在容器中的 运行)为容器化的 Elasticsearch 数据库建立索引。
通过查看现有的代码片段,docker-compose
似乎是一个可用于我的目的的有用工具。我的目录结构是
docker-compose.yml
indexer/
- Dockerfile
- indexer.py
- requirements.txt
elasticsearch/
- Dockerfile
我的docker-compose.yml
阅读
version: '3'
services:
elasticsearch:
build: elasticsearch/
ports:
- 9200:9200
networks:
- deploy_network
container_name: elasticsearch
indexer:
build: indexer/
depends_on:
- elasticsearch
networks:
- deploy_network
container_name: indexer
networks:
deploy_network:
driver: bridge
indexer.py
阅读
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk
es = Elasticsearch(hosts=[{"host":'elasticsearch'}]) # what should I put here?
actions = [
{
'_index' : 'test',
'_type' : 'content',
'_id' : str(item['id']),
'_source' : item,
}
for item in [{'id': 1, 'foo': 'bar'}, {'id': 2, 'foo': 'spam'}]
]
# create index
print("Indexing Elasticsearch db... (please hold on)")
bulk(es, actions)
print("...done indexing :-)")
elasticsearch 服务的 Dockerfile 是
FROM docker.elastic.co/elasticsearch/elasticsearch-oss:6.1.3
EXPOSE 9200
EXPOSE 9300
索引器的是
FROM python:3.6-slim
WORKDIR /app
ADD . /app
RUN pip install -r requirements.txt
ENTRYPOINT [ "python" ]
CMD [ "indexer.py" ]
with requirements.txt
只包含 elasticsearch
可以用 pip 下载。
运行 docker-compose run indexer
在 https://pastebin.com/6U8maxGX (ConnectionRefusedError: [Errno 111] Connection refused
) 处给我错误消息。
据我所知 curl -XGET 'http://localhost:9200/'
或 运行 docker ps -a
.
如何修改我的docker-compose.yml
或indexer.py
来解决问题?
P.S。为了完整起见,可以在此处找到代码的(工作)版本(由以下答案告知):https://github.com/davidefiocco/dockerized-elasticsearch-indexer.
问题是一个同步错误:当 indexer
尝试连接时,elasticsearch
尚未完全启动。您必须添加一些重试逻辑,以确保 elasticsearch
已启动并且 运行ning 在您尝试对其进行 运行 查询之前。在循环中 运行ning es.ping()
之类的东西,直到它成功进行指数退避应该可以解决问题。
更新:Docker HEALTHCHECK
指令可用于实现类似的结果(即确保 elasticsearch
已启动且 运行ning 在尝试 运行 对其进行查询)。
进行更明确的@Mihai_Todor更新,我们可以使用HEALTHCHECK
(docker 1.12+),例如使用如下命令:
curl -fsSL "http://$(hostname --ip-address):9200/_cat/health?h=status" | grep -E '^green'
使用HEALTHCHECK
回答这个问题:
FROM python:3.6-slim
WORKDIR /app
ADD . /app
RUN pip install -r requirements.txt
HEALTHCHECK CMD curl -fsSL "http://$(hostname --ip-address):9200/_cat/health?h=status" | grep -E '^green'
ENTRYPOINT [ "python" ]
CMD [ "indexer.py" ]
我使用 retry
来确保 Elasticsearch 已准备好接受连接:
from retrying import retry
client = Elasticsearch()
class IndexerService:
@staticmethod
@retry(wait_exponential_multiplier=500, wait_exponential_max=100000)
def init():
MyDocumentIndex.init()
# Here we will wait until ES is ready, or 100 sec passed.
IndexerService.init()
它会在 500 毫秒、1 秒、2 秒、4 秒后尝试直到 100 秒。
我正在尝试使用从脚本调用的 Python 客户端 https://github.com/elastic/elasticsearch-py(也在容器中的 运行)为容器化的 Elasticsearch 数据库建立索引。
通过查看现有的代码片段,docker-compose
似乎是一个可用于我的目的的有用工具。我的目录结构是
docker-compose.yml
indexer/
- Dockerfile
- indexer.py
- requirements.txt
elasticsearch/
- Dockerfile
我的docker-compose.yml
阅读
version: '3'
services:
elasticsearch:
build: elasticsearch/
ports:
- 9200:9200
networks:
- deploy_network
container_name: elasticsearch
indexer:
build: indexer/
depends_on:
- elasticsearch
networks:
- deploy_network
container_name: indexer
networks:
deploy_network:
driver: bridge
indexer.py
阅读
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk
es = Elasticsearch(hosts=[{"host":'elasticsearch'}]) # what should I put here?
actions = [
{
'_index' : 'test',
'_type' : 'content',
'_id' : str(item['id']),
'_source' : item,
}
for item in [{'id': 1, 'foo': 'bar'}, {'id': 2, 'foo': 'spam'}]
]
# create index
print("Indexing Elasticsearch db... (please hold on)")
bulk(es, actions)
print("...done indexing :-)")
elasticsearch 服务的 Dockerfile 是
FROM docker.elastic.co/elasticsearch/elasticsearch-oss:6.1.3
EXPOSE 9200
EXPOSE 9300
索引器的是
FROM python:3.6-slim
WORKDIR /app
ADD . /app
RUN pip install -r requirements.txt
ENTRYPOINT [ "python" ]
CMD [ "indexer.py" ]
with requirements.txt
只包含 elasticsearch
可以用 pip 下载。
运行 docker-compose run indexer
在 https://pastebin.com/6U8maxGX (ConnectionRefusedError: [Errno 111] Connection refused
) 处给我错误消息。
据我所知 curl -XGET 'http://localhost:9200/'
或 运行 docker ps -a
.
如何修改我的docker-compose.yml
或indexer.py
来解决问题?
P.S。为了完整起见,可以在此处找到代码的(工作)版本(由以下答案告知):https://github.com/davidefiocco/dockerized-elasticsearch-indexer.
问题是一个同步错误:当 indexer
尝试连接时,elasticsearch
尚未完全启动。您必须添加一些重试逻辑,以确保 elasticsearch
已启动并且 运行ning 在您尝试对其进行 运行 查询之前。在循环中 运行ning es.ping()
之类的东西,直到它成功进行指数退避应该可以解决问题。
更新:Docker HEALTHCHECK
指令可用于实现类似的结果(即确保 elasticsearch
已启动且 运行ning 在尝试 运行 对其进行查询)。
进行更明确的@Mihai_Todor更新,我们可以使用HEALTHCHECK
(docker 1.12+),例如使用如下命令:
curl -fsSL "http://$(hostname --ip-address):9200/_cat/health?h=status" | grep -E '^green'
使用HEALTHCHECK
回答这个问题:
FROM python:3.6-slim
WORKDIR /app
ADD . /app
RUN pip install -r requirements.txt
HEALTHCHECK CMD curl -fsSL "http://$(hostname --ip-address):9200/_cat/health?h=status" | grep -E '^green'
ENTRYPOINT [ "python" ]
CMD [ "indexer.py" ]
我使用 retry
来确保 Elasticsearch 已准备好接受连接:
from retrying import retry
client = Elasticsearch()
class IndexerService:
@staticmethod
@retry(wait_exponential_multiplier=500, wait_exponential_max=100000)
def init():
MyDocumentIndex.init()
# Here we will wait until ES is ready, or 100 sec passed.
IndexerService.init()
它会在 500 毫秒、1 秒、2 秒、4 秒后尝试直到 100 秒。