小编典典

使用NEST访问Elasticsearch Docker实例

elasticsearch

我使用Docker Compose运行了一个简单的Elasticsearch实例:

---
version: '2'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.1.1
    hostname: elasticsearch
    environment:
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
    ulimits:
      memlock:
        soft: -1
        hard: -1
    mem_limit: 1g
    ports:
      - 9200:9200

  kibana:
    image: docker.elastic.co/kibana/kibana:6.1.1
    environment:
      SERVER_NAME: "0.0.0.0"
      ELASTICSEARCH_URL: http://elasticsearch:9200
    ports:
      - 5601:5601

我可以使用localhost从浏览器访问它,但是当我运行我的应用程序并连接到它时,遇到了一些问题。从我能够跟踪到的内容来看,应用程序似乎成功连接到Elasticsearch实例,然后解析了它绑定的IP,然后使用该IP地址与Elasticsearch实例进行通信。

来自Fiddler:

  1. http://10.0.75.2:9200/_nodes/http,settings?flat_settings&timeout=2s
  2. 它返回具有以下行的json: "host": "172.18.0.4"
  3. 然后它尝试使用该IP地址,但我的请求失败,因为它无法解析该IP地址

为了能够从C#应用程序成功连接到我的Elasticsearch实例,我应该改变什么?

NEST版本:5.5.0


阅读 368

收藏
2020-06-22

共1个答案

小编典典

(注意:此答案使用NEST 7.1.0和Elasticsearch 7.2.0,但基本概念相同)。

SniffingConnectionPool植入连接池后,将使用http.publish_address节点的。这意味着客户端必须可以访问http发布地址。如果未显式设置,它将使用from中的值http.host,如果未设置,将使用network.host,这将是专用网络上的地址。

使用docker之类的配置

version: '2.2'
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0
    container_name: es01
    environment:
      - node.name=es01
      - discovery.seed_hosts=es02
      - cluster.initial_master_nodes=es01,es02
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - "http.port=9200"
      - "http.publish_host=_local_"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata01:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - esnet
  es02:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0
    container_name: es02
    environment:
      - node.name=es02
      - discovery.seed_hosts=es01
      - cluster.initial_master_nodes=es01,es02
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - "http.port=9201"
      - "http.publish_host=_local_"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata02:/usr/share/elasticsearch/data
    ports:
      - 9201:9201
    networks:
      - esnet

volumes:
  esdata01:
    driver: local
  esdata02:
    driver: local

networks:
  esnet:

es01节点被映射到localhost:9200es02localhost:9201。我们本来可以指定它es02在9200上的容器中运行,并将其映射到9201的主机端口,但是这样做的问题是es02http.publish_address仍然是127.0.0.1:9200,这将成为SniffingConnectionPool播种时最终使用的内容节点。为避免这种情况,我们在es02与的不同端口上运行es01,以便http发布地址将不同。

使用以上配置,http://localhost:9200/_nodes?filter_path=nodes.*.http返回

{
  "nodes": {
    "CSWncVnxS1esOm1KQtOR3A": {
      "http": {
        "bound_address": ["0.0.0.0:9200"],
        "publish_address": "127.0.0.1:9200",
        "max_content_length_in_bytes": 104857600
      }
    },
    "rOAp0T57TgSI_zU1L-T-vw": {
      "http": {
        "bound_address": ["0.0.0.0:9201"],
        "publish_address": "127.0.0.1:9201",
        "max_content_length_in_bytes": 104857600
      }
    }
  }
}

如果尝试这样做,则节点名称将有所不同 )。现在,SniffingConnectionPool将工作

private static void Main()
{
    var defaultIndex = "posts";
    var uris = new[]
    {
        new Uri("http://localhost:9200"),
        new Uri("http://localhost:9201")
    };

    var pool = new SniffingConnectionPool(uris);

    var settings = new ConnectionSettings(pool)
        .DefaultIndex(defaultIndex);

    var client = new ElasticClient(settings);

    var response = client.Nodes.Info();

    foreach (var node in response.Nodes)
    {
        Console.WriteLine($"{node.Key} http publish_address is: {node.Value.Http.PublishAddress}");
    }
}

版画

CSWncVnxS1esOm1KQtOR3A http publish_address is: 127.0.0.1:9200
rOAp0T57TgSI_zU1L-T-vw http publish_address is: 127.0.0.1:9201
2020-06-22