如何使用一个IP搭建ES集群——Docker如你所愿

版权声明:本文为CSDN博主原创文章,转载请注明出处(@http://blog.csdn.net/gamer_gyt)


随着业务的发展,elasticsearch部署在一台机子上显然会不够用,那么我们该如何处理呢,幸运的elasticsearch支持横向扩展,即集群模式,这样无论数据量增长多大,我们只需要扩展我们的es集群即可。


背景说明


  • Ubuntu16.04 

  • Docker 1.9 

  • Elasticsearch 2.4


  • 假设现在就一台服务器,我们要用这台服务器来部署一个ES的集群,那么最好的解决办法便是Docker了,我们可以利用Docker启动两个容器,在两个容器内各部署一个ElasticSearch,总而组成一个2个节点的ES集群


  • Linux下Docker的部署:

  • http://blog.csdn.net/gamer_gyt/article/details/52769294 

  • 终端安装Docker:

  • http://bbs.csdn.net/topics/392063910 

  • 我的Docker专栏:

  • http://blog.csdn.net/column/details/13159.html


  • Docker网络模式解释


    1.host模式


    众所周知,Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。


    例如,我们在10.10.101.105/24的机器上用host模式启动一个含有web应用的Docker容器,监听tcp80端口。当我们在容器中执行任何类似ifconfig命令查看网络环境时,看到的都是宿主机上的信息。而外界访问容器中的应用,则直接使用10.10.101.105:80即可,不用任何NAT转换,就如直接跑在宿主机中一样。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。


    2.container模式


    在理解了host模式后,这个模式也就好理解了。这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。


    3.none模式


    这个模式和前两个不同。在这种模式下,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。


    4.bridge模式


    bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上



    两个容器以组播方式创建ES集群


    组播配置示例如下,单播配置在最下边,使用时只需替换加几行配置即可


    1.下载Ubuntu最近版镜像


    sudo docker pull ubuntu


    2.配置基本环境


    启动容器,进入容器内安装基本环境vim,Java,和elasticsearch


    sudo docker run -it -d –name esc1 ubuntu:latest 

    sudo docker exec -it esc1 /bin/bash 

    apt-get install vim 

    apt install openjdk-8-jre


    然后安装es,下载安装包(阅读原文获取下载链接


    将其拷贝到docker内,安装


    dpkg -i elasticsearch-2.4.0.deb


    至此基本环境已经准备的差不多了,然后便是退出容器,stop 容器,然后进行commit 保存成两个容器


    sudo docker commit esc1 es1:1.0 

    sudo docker commit esc1 es2:1.0


    最后查看镜像如图所示: 



    3.es环境配置


    分别启动两个容器


    sudo docker run -it -d -p 9201:9201 -p 9301:9301 -p 5001:5001 -p 5602:5602 –name esc1 es1:1.0 

    sudo docker run -it -d -p 9200:9200 -p 9300:9300 -p 5000:5000 -p 5601:5601 –name esc2 es2:1.0


    进入两个容器进行配置elasticsearch.ymal文件 


    esc1:

    cluster.name: xdstar

    node.name: node-1

    node.master: false

    node.data: true

    network.host: 0.0.0.0

    http.port: 9201

    transport.tcp.port: 9301

    esc2:

    cluster.name: xdstar

    node.name: node-2

    node.master: true

    node.data: true

    network.host: 0.0.0.0

    http.port: 9200

    transport.tcp.port: 9300

  • cluster.name:集群名字,配置必须一样 

  • node.name:每个节点的名字,不能一样 

  • node.master: true 代表可以被选举为主节点,false代表不能被选举为主节点(这里我们设置esc2为主节点) 

  • ndoe.data:代表是否可以存储数据 

  • network.host:表示访问的ip,0.0.0.0表示可以以IP访问或者localhost,127.0.0.1 

  • network.port:访问的端口

  • 启动Elasticsearch

    service elasticsearch start

    细心的朋友会发现容器的启动端口转发端口不一致,这是因为,这里启动Docker容器默认采用的桥接,和主机共享端口了,所以两者端口不能一致,要不然会重复

    启动完es集群,浏览器输入 https:192.168.1.250:9200/_plugin/head 

    这里我安装了head插件,插件安装,参考之前的一篇文章,里边有讲到:

    http://blog.csdn.net/gamer_gyt/article/details/52654263

    4.安装logstash配置rsyslog解析文件

    logstash 2.4版本(阅读原文获取下载链接 )

    更多版本:https://www.elastic.co/downloads/past-releases

    dpkg -i logstash-all-plugins-2.4.0_all.deb

    然后进入配置文件目录

    cd /etc/logstash/conf.d 

    vim rsyscon.conf

    添加以下内容

    input {

       syslog{

        port => 5000

        type => syslog

      }

    }

    output {

      stdout {

        codec=> rubydebug

      }

      elasticsearch {

        hosts => ["localhost:9200"]

      }

    }


    启动logstash

    service logstash start


    5.本地配置,产生syslog日志

    编辑rsyslog的配置文件:

    vim /etc/rsyslog.conf


    最后添加

     *.*  @localhost:5000

     *.*  @@localhost:5000


    重启rsyslog服务

    service rsyslog restart


    ssh 本地,产生日志

    ssh localhost


    这个时候观察elasticsearch界面: 


    ES集群的多播与单播

    以上的集群是采用组播的方式来构建的,组播就是通过在你的网络中发送UDP的ping请求以发现节点,其它Elasticsearch会收到这些ping请求并且进行响应,这样随后就会形成一个集群。 

    多播对于开发环境是很好的,你不需要做什么事情,打开一些节点,他们自然的会发现对方形成一个集群。 

    正是因为这种易用性,你在生产环境中必须禁掉它。否在你得到的结果就是一个节点意外的加入到了你的生产环境,因为他们收到了一个错误的组播信号。对于组播本身并没有错。组播会导致一些愚蠢的问题,并且导致集群变的脆弱(例如:一个网络工程师正在捣鼓网络,而没有告诉你,你会发现所有的节点突然发现不了对方了)。 

    在生产环境中,建议使用单播代替组播,也就是说为Elasticsearch提供一些它应该去尝试连接的节点列表。一旦这个节点联系到组播列表中的一员,它就会得到整个集群所有节点的状态,然后它会联系master节点,并加入集群。 

    这意味着你的单播列表不需要包含你的集群中的所有节点,它只需要包含足够一个新节点联系上其中一个并且说上话就ok了。

    ES 是一个 P2P 类型(使用 gossip 协议)的分布式系统,除了集群状态管理以外,其他所有的请求都可以发送到集群内任意一台节点上,这个节点可以自己找到需要转发给哪些节点,并且直接跟这些节点通信。 

    所以,从网络架构及服务配置上来说,构建集群所需要的配置极其简单。在 Elasticsearch 2.0 之前,无阻碍的网络下,所有配置了相同 cluster.name 的节点都自动归属到一个集群中。 

    2.0 版本之后,基于安全的考虑,Elasticsearch 稍作了调整,避免开发环境过于随便造成的麻烦。

    ES 从 2.0 版本开始,默认的自动发现方式改为了单播(unicast)方式。配置里提供几台节点的地址,ES 将其视作 gossip router 角色,借以完成集群的发现。由于这只是 ES 内一个很小的功能,所以 gossip router 角色并不需要单独配置,每个 ES 节点都可以担任。所以,采用单播方式的集群,各节点都配置相同的几个节点列表作为 router 即可。 

    此外,考虑到节点有时候因为高负载,慢 GC 等原因可能会有偶尔没及时响应 ping 包的可能,一般建议稍微加大 Fault Detection 的超时时间。 

    同样基于安全考虑做的变更还有监听的主机名。现在默认只监听本地 lo 网卡上。所以正式环境上需要修改配置为监听具体的网卡。

    network.host: "0.0.0.0" 

    discovery.zen.minimum_master_nodes: 3

    discovery.zen.ping.timeout: 100s

    discovery.zen.fd.ping_timeout: 100s

    discovery.zen.ping.unicast.hosts: ["10.19.0.97","10.19.0.98","10.19.0.99","10.19.0.100"]

    上面的配置中,两个 timeout 可能会让人有所迷惑。这里的 fd 是 fault detection 的缩写。也就是说: 

  • discovery.zen.ping.timeout 参数仅在加入或者选举 master 主节点的时候才起作用; 

  • discovery.zen.fd.ping_timeout 参数则在稳定运行的集群中,master 检测所有节点,以及节点检测 master 是否畅通时长期有用。 

  • 既然是长期有用,自然还有运行间隔和重试的配置,也可以根据实际情况调整:

    discovery.zen.fd.ping_interval: 10s

    discovery.zen.fd.ping_retries: 10

    单播配置

    以上展示为组播方式,单播配置相对来说只需要在配置文件里加几行即可 

    esc1:

    discovery.zen.ping.unicast.hosts: ["localhost:9300","localhost:9301"]

    esc2:

    discovery.zen.ping.unicast.hosts: ["localhost:9300","localhost:9301"]

    PS:我这里尝试了很多次,增加了

    discovery.zen.minimum_master_nodes: 3

    discovery.zen.ping.timeout: 100s

    discovery.zen.fd.ping_timeout: 100s

    这三个属性之后集群并不能启动,所以这里只设置了discovery.zen.ping.unicast.hosts属性。


    我们是一群热爱IT的年轻人,如果你也爱IT、爱移动端开发,欢迎加入我们,让我们共同为梦想发声。

    关注蓝鸥(lanou3g),推送IT新知识与资讯,让你每天进步一点点。

    PS:喜欢你就点个赞,有用你就收进后宫,认识程序员你就转发一下辣。

    推荐阅读更多精彩内容