【问题标题】:ElasticSearch on Elastic BeanstalkElastic Beanstalk 上的 ElasticSearch
【发布时间】:2015-06-03 02:15:24
【问题描述】:

我正在尝试让 ElasticSearch 在 Elastic Beanstalk 环境中运行。使用 Docker 映像让一个实例在负载平衡的环境中运行相当简单。但是,当我尝试向集群添加更多实例时,它们无法发现彼此,并且每个新实例都成为 new_master。

我的Dockerfile 如下所示

FROM dockerfile/java:oracle-java8
RUN ... # Downloading and installing ElasticSearch
RUN /elasticsearch/bin/plugin install elasticsearch/elasticsearch-cloud-aws/2.5.0
VOLUME ["/data"]
ADD config/elasticsearch.yml /elasticsearch/config/elasticsearch.yml
WORKDIR /data
CMD ["/elasticsearch/bin/elasticsearch"]

EXPOSE 9200

配置config/elasticsearch.yml 如下所示:

cluster:
  name: elastic-env-dev
cloud:
  aws:
    region: ap-southeast-2
discovery:
  type: ec2
  ec2:
    tag:
      Name: elastic-env-dev
    ping_timeout: 120s

EB 环境的名称是elastic-env-dev

【问题讨论】:

    标签: amazon-web-services elasticsearch docker amazon-elastic-beanstalk


    【解决方案1】:

    1) 检查您的实例安全组,以便 ES 实例相互通信,它们必须使用端口 9300

    2) AWS 不允许多播。您必须在 elasticsearch 配置中禁用多播

    将此行添加到每个 ES 配置的配置中

    discovery.zen.ping.multicast.enabled: false
    

    如果这不起作用,请尝试添加单播配置

    discovery.zen.ping.unicast.hosts: loadbalancer.address
    

    3) 记住实例上的安全组必须允许来自 ELB 的 9300

    Custom TCP Rule  TCP  9300 amazon-elb/sg-123456ed (amazon-elb-sg)
    

    4) 使用 telnet 来检查 ES 实例之间的通讯使用

    telnet ip_address 9300
    

    【讨论】:

    • 我忘了你还必须在 docker 文件上暴露端口 9300
    • 这里还是一片黑暗。不能telnet 到任何东西,即使是同一台机器,除非我使用来自sudo docker inspect ... | grep IP 的IP。随机猜测,会不会是未映射的 IPv4 造成的?一条可疑线路是bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/172.17.0.5:9300]}
    • 安全组是否允许端口 9300?还将其添加到配置中:network.host: ec2:privateIpv4
    • @RăzvanPetruescu 您无法连接到本地实例 IP,因为来自 docker 的端口未映射到主机。 AWS 每个 VPS 运行一个容器。您可以创建 appdeploy post hook,它将通过 iptables 映射 IP,但是还有另一个我不知道如何解决的问题。你可以在这里阅读它discuss.elastic.co/t/deploy-es-to-aws-beanstalk/34567
    【解决方案2】:

    可以在 EBT 上部署 ES,方法如下

    http://vladmiller.com/elasticsearch/aws/2015/12/08/deploy-elasticsearch-on-aws-elasticbeanstalk.html


    在这一点上(2015 年 11 月 14 日),花了一些时间后,我会说不可能让 ES 集群在 EB 上工作。

    问题 #1 是您必须将 docker 端口映射到主机,就像您会做的那样

    docker run -p 9300:9300 ...
    

    如果您通过 .ebextensions 添加 post appdeploy 挂钩,这将很容易解决,这将设置 iptables 端口转发

    files:
      "/opt/elasticbeanstalk/hooks/appdeploy/post/99_setup_iptables.sh":
        mode: "0755"
        owner: root
        group: root
        content: |
          #!/bin/sh
          iptables-save | grep -v added_by_ebextension | iptables-restore
    
          DOCKER_IP=$(docker inspect `cat /etc/elasticbeanstalk/.aws_beanstalk.current-container-id` | jq -r .[0].NetworkSettings.IPAddress)
          iptables -t nat -A DOCKER -p tcp --dport 9300:9400 -j DNAT --to-destination ${DOCKER_IP} -m comment --comment added_by_ebextension
    
          service iptables save
    

    问题 #2 您需要调整安全组,确保您允许 SG 中的节点之间的 TCP 9300-9400 和 ICMP 流量。

    问题 #3 使用 aws-ec2 发现插件并将其限制为您的 SG,因此不会发现其他机器

    // elasticsearch.yml
    
    cloud.aws:
      access_key: YYYYYYYYY
      secret_key: XXXXXXXXX
      region: us-east-1
    
    discovery.type: ec2
    discovery.ec2.ping_timeout: 30s
    discovery.ec2.tag.Name: [ENVIRONMENT_NAME]
    discovery.ec2.host_type: private_dns
    discovery.zen.ping.multicast.enabled: false
    

    问题#4,未解决是每个 ES 节点都会绑定到内部 docker IP 地址,类似于 172.17.0.3,但是您的主机私有 IP 不同.因此,当节点发现彼此并开始通信时,它们会向其他节点报告错误的 IP 地址。

    [2015-11-13 21:50:58,542][TRACE][discovery.zen.ping.unicast] [86ac0ad55d5b] [2] received response from {#zen_unicast_21_#cloud-i-8c317a3b-0#}{10.165.71.177}{ip-10-165-71-177.ec2.internal/10.165.71.177:9300}: [ping_response{node [{86ac0ad55d5b}{U3PF5qOaQCucpK3JfZ3ARA}{172.17.0.3}{172.17.0.3:9300}], id[5], master [null], hasJoinedOnce [false], cluster_name[es-staging]}, ping_response{node [{86ac0ad55d5b}{U3PF5qOaQCucpK3JfZ3ARA}{172.17.0.3}{172.17.0.3:9300}], id[7], master [null], hasJoinedOnce [false], cluster_name[es-staging]}, ping_response{node [{86ac0ad55d5b}{U3PF5qOaQCucpK3JfZ3ARA}{172.17.0.3}{172.17.0.3:9300}], id[9], master [null], hasJoinedOnce [false], cluster_name[es-staging]}, ping_response{node [{86ac0ad55d5b}{U3PF5qOaQCucpK3JfZ3ARA}{172.17.0.3}{172.17.0.3:9300}], id[11], master [null], hasJoinedOnce [false], cluster_name[es-staging]}, ping_response{node [{89764d1bb185}{yVRC-HmIQoayIuWfi6a09g}{172.17.0.3}{172.17.0.3:9300}], id[30], master [{89764d1bb185}{yVRC-HmIQoayIuWfi6a09g}{172.17.0.3}{172.17.0.3:9300}], hasJoinedOnce [true], cluster_name[es-staging]}]
    

    您可以看到在 ip-10-165-71-177.ec2.internal/10.165.71.177:9300 上发现的节点,但是该节点响应说它的 IP 是 172.17。 0.3 因此第一个节点而不是连接到 EC2 私有 IP 将尝试连接到内部 Docker IP

    [2015-11-13 21:51:00,037][TRACE][discovery.ec2 ] [86ac0ad55d5b] full ping responses:
    --> ping_response{node [{89764d1bb185}{yVRC-HmIQoayIuWfi6a09g}{172.17.0.3}{172.17.0.3:9300}], id[30], master [{89764d1bb185}{yVRC-HmIQoayIuWfi6a09g}{172.17.0.3}{172.17.0.3:9300}], hasJoinedOnce [true], cluster_name[es-staging]}
    [2015-11-13 21:51:00,041][DEBUG][discovery.ec2 ] [86ac0ad55d5b] filtered ping responses: (filter_client[true], filter_data[false])
    --> ping_response{node [{89764d1bb185}{yVRC-HmIQoayIuWfi6a09g}{172.17.0.3}{172.17.0.3:9300}], id[30], master [{89764d1bb185}{yVRC-HmIQoayIuWfi6a09g}{172.17.0.3}{172.17.0.3:9300}], hasJoinedOnce [true], cluster_name[es-staging]}
    

    我们需要以某种方式让 ES 绑定到主机的 IP 地址或忽略那些 docker IP 地址并继续使用发现的 IP。


    更新 1 我怀疑你可以在没有 Docker 的情况下将 ES 部署到 EB,但是我还没有尝试过这个选项。


    更新 2 我能够让节点发现彼此并尝试通信,但是现在它有一个 different issue


    UPDATE 3这是关于如何达到预期效果的故事和示例代码http://vladmiller.com/elasticsearch/aws/2015/12/08/deploy-elasticsearch-on-aws-elasticbeanstalk.html

    【讨论】:

    • vladmiller.com 的链接已损坏。博客是否已在某个地方重新托管?
    • 弗拉德在his Github上有代码,可以访问博客through archive.org
    猜你喜欢
    • 2017-06-14
    • 2020-09-28
    • 2020-11-25
    • 2015-05-27
    • 2013-06-12
    • 2016-03-12
    • 2014-08-03
    • 2014-09-08
    • 2014-12-18
    相关资源
    最近更新 更多