使用Docker在多台主机上构建Elasticsearch集群的建设验证
※本文已转移到个人博客上。
由于Elasticsearch官方提供了容器镜像,我打算利用它来建立一个集群。
虽然在文档中公开了docker-compose.yml文件,但是考虑到docker-compose只能有一个容器主机,从可用性的角度来看,我觉得这是个问题。(也许可以通过使用Swarm模式来解决?)
考虑到我想要将容器主机分散到多台服务器上,所以我进行了验证。
验证环境
-
- Mac OS X El Capitan(10.11.6)
-
- docker-machine version 0.10.0, build 76ed2a6
- VirtualBox 5.1.14 r112924 (Qt5.6.2)
点数
-
- docker-machineを利用してVirtualBox上に3つのコンテナホストを起動
-
- 各コンテナホストに公式のコンテナイメージをデプロイ
- Dockerのネットワークドライバはhostモードを利用する
验证程序
容器主机的准备工作
创建容器主机
我在VirtualBox上启动了三个容器主机。
$ docker-machine create --driver virtualbox elasticsearch1
$ docker-machine create --driver virtualbox elasticsearch2
$ docker-machine create --driver virtualbox elasticsearch3
提高容器主机内存映射的上限
如公式所述,若不进行设置,容器将无法启动(在开发者模式下可能会启动),因此进行设置。
$ docker-machine ssh elasticsearch1 sudo sysctl -w vm.max_map_count=262144
$ docker-machine ssh elasticsearch2 sudo sysctl -w vm.max_map_count=262144
$ docker-machine ssh elasticsearch3 sudo sysctl -w vm.max_map_count=262144
启动Elasticsearch并进行操作确认。
启动Elasticsearch容器
从Elastic的独立容器注册表中获取映像并启动。
通过环境变量(-e)传递参数可以覆盖Elasticsearch的配置,因此可以立即启动。
以下是传递给验证的参数。
環境変数名パラメータに渡す値説明network.host_eth1:ipv4_hostモードでコンテナを起動するとホストのNICが全部マッピングされますが、このオプションを指定しないとElasticsearchはeth0のIPアドレスをデフォルトで指定するようです。
eth0のIPアドレスはプライベートなIPアドレスが割り当てられていて外部と通信できないのでeth1を明示しています。discovery.zen.ping.unicast.hosts自分自身以外のコンテナホストのIPアドレスをカンマ区切りクラスタに参加させるホストを明示します。discovery.zen.minimum_master_nodes2
コンテナホストのメモリを増やすという方法もありますが、3台も2GB以上のホストを起動したらこのMacがゲロ重になるのでこうしました。
eth0のIPアドレスはプライベートなIPアドレスが割り当てられていて外部と通信できないのでeth1を明示しています。discovery.zen.ping.unicast.hosts自分自身以外のコンテナホストのIPアドレスをカンマ区切りクラスタに参加させるホストを明示します。discovery.zen.minimum_master_nodes2
ノード数/2+1
を設定するようドキュメントにも記載されているので従います。xpack.security.enabledfalse今回の検証には不要なのでX-PackのSecurityを無効化します。xpack.monitoring.enabledfalse今回の検証には不要なのでX-PackのMonitoringを無効化します。xpack.watcher.enabledfalse今回の検証には不要なのでX-PackのWatcherを無効化します。xpack.graph.enabledfalse今回の検証には不要なのでX-PackのGraphを無効化します。xpack.ml.enabledfalse今回の検証には不要なのでX-PackのMachine Learningを無効化します。ES_JAVA_OPTS-Xms512m -Xmx512mElasticsearchが使用するjavaのヒープサイズを指定します。コンテナホストのメモリを増やすという方法もありますが、3台も2GB以上のホストを起動したらこのMacがゲロ重になるのでこうしました。
除此之外,传递给容器的选项如下所示。
オプション説明-dデタッチドモードでコンテナを起動。
説明はいらないですよね?–network=”host”コンテナのネットワークモードを
コンテナホストのネットワークインターフェースがそのままコンテナ上でも利用されます。-p 9200:9200Elasticsearchのサービスポートを公開します。
説明はいらないですよね?–network=”host”コンテナのネットワークモードを
host
に設定します。コンテナホストのネットワークインターフェースがそのままコンテナ上でも利用されます。-p 9200:9200Elasticsearchのサービスポートを公開します。
-P(大文字)
でもよかったかも。-p 9300:9300Elasticsearchがノード間のコミュニケーションで使用するポートを公開します。-P(大文字)
でもよかったかも。$ eval $(docker-machine env elasticsearch1)
$ docker run -d \
-e "network.host=_eth1:ipv4_" \
-e "discovery.zen.ping.unicast.hosts=$(docker-machine ip elasticsearch2),$(docker-machine ip elasticsearch3)" \
-e "discovery.zen.minimum_master_nodes=2" \
-e "xpack.security.enabled=false" \
-e "xpack.monitoring.enabled=false" \
-e "xpack.watcher.enabled=false" \
-e "xpack.graph.enabled=false" \
-e "xpack.ml.enabled=false" \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
--network="host" \
-p 9200:9200 \
-p 9300:9300 \
docker.elastic.co/elasticsearch/elasticsearch:5.4.0
$ eval $(docker-machine env elasticsearch2)
$ docker run -d \
-e "network.host=_eth1:ipv4_" \
-e "discovery.zen.ping.unicast.hosts=$(docker-machine ip elasticsearch1),$(docker-machine ip elasticsearch3)" \
-e "discovery.zen.minimum_master_nodes=2" \
-e "xpack.security.enabled=false" \
-e "xpack.monitoring.enabled=false" \
-e "xpack.watcher.enabled=false" \
-e "xpack.graph.enabled=false" \
-e "xpack.ml.enabled=false" \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
--network="host" \
-p 9200:9200 \
-p 9300:9300 \
docker.elastic.co/elasticsearch/elasticsearch:5.4.0
$ eval $(docker-machine env elasticsearch3)
$ docker run -d \
-e "network.host=_eth1:ipv4_" \
-e "discovery.zen.ping.unicast.hosts=$(docker-machine ip elasticsearch1),$(docker-machine ip elasticsearch2)" \
-e "discovery.zen.minimum_master_nodes=2" \
-e "xpack.security.enabled=false" \
-e "xpack.monitoring.enabled=false" \
-e "xpack.watcher.enabled=false" \
-e "xpack.graph.enabled=false" \
-e "xpack.ml.enabled=false" \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
--network="host" \
-p 9200:9200 \
-p 9300:9300 \
docker.elastic.co/elasticsearch/elasticsearch:5.4.0
查看Cluster的状态
我会检查集群的状态,因为有3个节点已经启动。
$ curl $(docker-machine ip elasticsearch1):9200/_cat/health?v
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1496326996 14:23:16 docker-cluster green 3 3 0 0 0 0 0 0 - 100.0%
$ curl $(docker-machine ip elasticsearch1):9200/_cluster/health?pretty
{
"cluster_name" : "docker-cluster",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 3,
"number_of_data_nodes" : 3,
"active_primary_shards" : 0,
"active_shards" : 0,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
如果能够确认以下几点就好了。
-
- statusがgreen
-
- ノードの数が3
- データノードの数が3
创建索引并进行确认。
我觉得可以组织一下集群,所以我打算创建一个索引试试看。
$ curl -XPUT $(docker-machine ip elasticsearch1):9200/test?pretty
{
"acknowledged" : true,
"shards_acknowledged" : true
}
由于是集群,所以无论向哪个IP地址查询,只要上述创建的索引存在,就没有问题。我来确认一下。
$ curl $(docker-machine ip elasticsearch1):9200/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open test 0iOZud02QHqPMkcDemgdWg 5 1 0 0 1.2kb 650b
这台主机已经准备好了。因为这是在创建索引时指定的主机,所以当然如此。
$ curl $(docker-machine ip elasticsearch2):9200/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open test 0iOZud02QHqPMkcDemgdWg 5 1 0 0 1.2kb 650b
第二季度也顺利进行了。
$ curl $(docker-machine ip elasticsearch3):9200/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open test 0iOZud02QHqPMkcDemgdWg 5 1 0 0 1.2kb 650b
第三瘘刚好也有。
总结
我们可以通过容器在多个主机上启动具有可用性的Elasticsearch集群,如上所述。
之后,我想验证一下如何使用cloud-aws插件将其部署在EC2上(也许在容器中也可以?)。
很遗憾的是,亚马逊Elasticsearch服务不支持VPC。
如果您有任何意见或建议,我希望您能善意地指出。