Elastic Beanstalk 上的 ElasticSearch

Posted

技术标签:

【中文标题】Elastic Beanstalk 上的 ElasticSearch【英文标题】:ElasticSearch on Elastic Beanstalk 【发布时间】: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

【问题讨论】:

【参考方案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.177ip-10-165-71-177.ec2.internal/10.165.71.177:9300: [ping_responsenode [86ac0ad55d5bU3PF5qOaQCucpK3JfZ3ARA172.17.0.3172.17.0.3:9300], id[5], master [null], hasJoinedOnce [false], cluster_name[es-staging], ping_responsenode [86ac0ad55d5bU3PF5qOaQCucpK3JfZ3ARA172.17.0.3172.17.0.3:9300], id[7], master [null], hasJoinedOnce [false], cluster_name[es-staging], ping_responsenode [86ac0ad55d5bU3PF5qOaQCucpK3JfZ3ARA172.17.0.3172.17.0.3:9300], id[9], master [null], hasJoinedOnce [false], cluster_name[es-staging], ping_responsenode [86ac0ad55d5bU3PF5qOaQCucpK3JfZ3ARA172.17.0.3172.17.0.3:9300], id[11], master [null], hasJoinedOnce [false], cluster_name[es-staging], ping_responsenode [89764d1bb185yVRC-HmIQoayIuWfi6a09g172.17.0.3172.17.0.3:9300], id[30], master [89764d1bb185yVRC-HmIQoayIuWfi6a09g172.17.0.3172.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_responsenode [89764d1bb185yVRC-HmIQoayIuWfi6a09g172.17.0.3172.17.0.3:9300], id[30], master [89764d1bb185yVRC-HmIQoayIuWfi6a09g172.17.0.3172.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_responsenode [89764d1bb185yVRC-HmIQoayIuWfi6a09g172.17.0.3172.17.0.3:9300], id[30], master [89764d1bb185yVRC-HmIQoayIuWfi6a09g172.17.0.3172.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

以上是关于Elastic Beanstalk 上的 ElasticSearch的主要内容,如果未能解决你的问题,请参考以下文章

Terraform elasticbeanstalk部署

运行 AWS Deep Learning Base AMI (Amazon Linux 2) 时,如何在 Elastic Beanstalk 中设置 WSGI?

Elastic Beanstalk 上的 Cronjob 未运行

Elastic Beanstalk 上的 ElasticSearch

AWS Elastic Beanstalk 上的 Spring Boot 并记录到文件

Elastic Beanstalk 上的 SSL