首页 > 解决方案 > Errno 111:使用 Python 脚本连接到 Elasticsearch 时连接被拒绝

问题描述

我遇到了一个 dockerized elasticsearch 集群的问题,我想用一个简单的 python 索引脚本连接它。

执行 docker-compose up 后,它会启动集群,kibana 也是如此,但是当它尝试通过 python 脚本连接到 ES 时,我收到以下错误:

elasticsearch.exceptions.ConnectionError: ConnectionError(<urllib3.connection.HTTPConnection object at 0x7f1c04e0c0d0>: Failed to establish a new connection: [Errno 111] Connection refused) caused by: NewConnectionError(<urllib3.connection.HTTPConnection object at 0x7f1c04e0c0d0>: Failed to establish a new connection: [Errno 111] Connection refused)

我可以用浏览器访问ES,如果我在pycharm中执行脚本也可以定期索引。所以它与docker有关,但我找不到问题的根源。这是我的码头文件:

    version: '3.4'
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.8.1
    container_name: es01
    environment:
      #- discovery.type=single-node needed?
      - node.name=es01
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es02,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - xpack.security.enabled=false
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data01:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - elastic

  es02:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.8.1
    container_name: es02
    environment:
      - node.name=es02
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data02:/usr/share/elasticsearch/data
    networks:
      - elastic

  es03:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.8.1
    container_name: es03
    environment:
      - node.name=es03
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es02
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data03:/usr/share/elasticsearch/data
    networks:
      - elastic

  kib01:
    image: docker.elastic.co/kibana/kibana:7.8.1
    container_name: kib01
    depends_on:
      - es01
      - es02
      - es03
    ports:
      - 5601:5601
    environment:
      ELASTICSEARCH_URL: http://es01:9200
      ELASTICSEARCH_HOSTS: http://es01:9200
    networks:
      - elastic

  web:
    build: .
    ports:
      - 8000:8000
    depends_on:
      - es01
      - es02
      - es03
    networks:
      - elastic


volumes:
  data01:
    driver: local
  data02:
    driver: local
  data03:
    driver: local

networks:
  elastic:
    driver: bridge

和python脚本:

from elasticsearch import Elasticsearch, helpers
import sys, json, os
import requests

es = Elasticsearch([{'host': '127.0.0.1', 'port': 9200}])

def load_json(directory):
    " Use a generator, no need to load all in memory"
    for filename in os.listdir(directory):
        if filename.endswith('.json'):
            filename = "JSON/" + filename
            with open(filename,'r') as open_file:
                yield json.load(open_file)

if __name__ == '__main__':
    helpers.bulk(es, load_json("JSON"), index='urteile')

来自容器外部的 Curl localhost 可以工作,但不能在容器内部工作,并给出以下错误:

docker 文件中的 curl 命令也给了我一个 Connection denied 顺便说一句。这是我得到的错误:

mapping_1  | * TCP_NODELAY set
mapping_1  | * connect to 127.0.0.1 port 9200 failed: Connection refused
mapping_1  | *   Trying ::1...
mapping_1  | * TCP_NODELAY set
mapping_1  | * Immediate connect fail for ::1: Address not available
mapping_1  | *   Trying ::1...
mapping_1  | * TCP_NODELAY set
mapping_1  | * Immediate connect fail for ::1: Address not available
mapping_1  | * Failed to connect to localhost port 9200: Connection refused
mapping_1  | * Closing connection 0
mapping_1  | curl: (7) Failed to connect to localhost port 9200: Connection refused

有人知道这里可能是什么问题吗?

编辑:

好的,因此使用 es01 而不是 localhost 的评论有所帮助,因为当插入“客户端”服务时,它将成功 ping Elasticsearch。仍然 - python 应用程序告诉我连接被拒绝......

标签: pythondockerelasticsearchkibana

解决方案


您在 python 代码中使用 localhost 作为 ES 集群地址。ES 在单独的容器上运行,因此您需要使用这些主机名。在您的情况下,您可以使用 docker compose yaml 文件(es01、es02 等)中声明的服务名称,而不是 127.0.0.1


推荐阅读