【问题标题】:Not able to connect to local elasticsearch process from docker container无法从 docker 容器连接到本地弹性搜索进程
【发布时间】:2019-11-26 12:52:45
【问题描述】:

编辑

我认为是 docker 进程中的 localhost 指的是容器自己的 localhost,而不是我系统的 localhost。那么如何确保运行容器的应用程序在尝试连接到容器的 localhost:9200 时,实际上连接到了我系统的 localhost:9200?

当我访问 localhost:9200 时,我的 ES 应用程序似乎正在运行。它在 chrome 中看起来像这样:

{
  "name" : "H1YDvcg",
  "cluster_name" : "elasticsearch_jwan",
  "cluster_uuid" : "aAorzRYTQPOI0j_OgMGKpA",
  "version" : {
    "number" : "6.8.1",
    "build_flavor" : "oss",
    "build_type" : "tar",
    "build_hash" : "1fad4e1",
    "build_date" : "2019-06-18T13:16:52.517138Z",
    "build_snapshot" : false,
    "lucene_version" : "7.7.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

我在终端窗口中运行 ES,它在我运行命令 elasticsearch 后工作。

我正在使用这个命令运行一个 docker 容器:

docker run -e DATALOADER_QUEUE='<some aws SQS queue name'\
             -e ES_HOST='localhost'\
             -e ES_PORT='9200'\
             -e AWS_ACCESS_KEY_ID='<somekey>'\
             -e AWS_SECRET_ACCESS_KEY='<somekey>'\
             -e AWS_DEFAULT_REGION='us-west-2'\
             <application name>

我得到这个错误:

requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=9200): Max retries exceeded with url: /person/_search (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f36e4189c90>

有人知道怎么回事吗?我不明白为什么即使 ti 似乎在 localhost:9200 上运行它也无法连接到 ES。

【问题讨论】:

标签: python docker elasticsearch


【解决方案1】:

解决方案是在 ES 主机设置中使用 host.docker.internal

我刚刚使用 es_client = Elasticsearch(host=_es_host, where es_host = host.docker.internal 并确保在本地使用 http 而不是 https。

【讨论】:

    【解决方案2】:

    Elasticsearch 正在您的主机上的端口9200 上运行,并且想要访问elasticsearch 的应用程序正在容器内运行。

    docker 容器默认运行在bridge 网络模式,其中主机和容器网络不同。因此容器内的 localhost 与主机上的不同。

    在这里你可以做两件事:

    • 在您的应用程序代码中尝试使用private/public-ip:9200 访问elasticsearch

    • host网络模式下运行docker容器,使容器内的localhost与主机上的相同。因为在这种模式下容器使用主机网络。
    docker run -e DATALOADER_QUEUE='<some aws SQS queue name'\
                 -e ES_HOST='localhost'\
                 -e ES_PORT='9200'\
                 -e AWS_ACCESS_KEY_ID='<somekey>'\
                 -e AWS_SECRET_ACCESS_KEY='<somekey>'\
                 -e AWS_DEFAULT_REGION='us-west-2'\
                 --net=host \
                 <application name>
    

    注意: --net=host 选项将告诉 docker 容器使用主机网络模式。

    【讨论】:

    • 我试过了,但后来我对 aws 的请求似乎是托管
    • @Jwan622 这肯定会发生,因为您希望容器内的 localhost 与主机内的相同。
    • 或者将应用程序代码更改为指向机器 ip 将是不错的选择。
    【解决方案3】:

    您可以使用 -p 选项 docker 命令将主机端口绑定到 docker 端口。因此,在下面的 docker 命令中,您可以再添加一行将主机 9200 端口绑定到 docker 9200 端口。注意我已经添加了-p 9200:9200,并且在第 3 点 this doc 中很好地解释了这一点

    docker run -p 9200:9200 -e DATALOADER_QUEUE='<some aws SQS queue name'\
                 -e ES_HOST='localhost'\
                 -e ES_PORT='9200'\
                 -e AWS_ACCESS_KEY_ID='<somekey>'\
                 -e AWS_SECRET_ACCESS_KEY='<somekey>'\
                 -e AWS_DEFAULT_REGION='us-west-2'\
                 <application name>
    

    【讨论】:

    • -e 标志应该在 -p 9200:9200 的后面吧?
    • 所以我再次尝试了这个,它没有工作。基本上这应该解决我认为的问题:我的 docker 应用程序正在向 localhost:9200 发出请求,但它正在向容器内的 localhost 发出请求,而不是主机的 localhost 对吗?由于某种原因,这不起作用。
    • 这个答案的问题是 -p 选项会将来自主机上 9200 端口的请求转发到容器内的 9200 端口。但你想要的是另一种方式。从容器 9200 端口到 -> 主机 9200 端口。
    • @Jwan622 这就是我试图在我的帖子中回答的问题。 :)
    • 浏览我在回答中提供的主机和桥接网络文档,它将帮助您了解 docker 网络并清楚地了解我的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 2016-07-26
    • 1970-01-01
    • 2019-06-26
    相关资源
    最近更新 更多