Create an Elasticsearch cluster using docker to learn how it behaves during specific operations.
Preparation
Tune system settings to deal with initial bootstrap issues.
elasticsearch-emu | ERROR: [2] bootstrap checks failed elasticsearch-emu | [1]: memory locking requested for elasticsearch process but memory is not locked elasticsearch-emu | [2]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
Enable memory locking to prevent storing JVM heap on the disk.
$ sudo mkdir /etc/systemd/system/docker.service.d
$ echo -e "[Service]\nLimitMEMLOCK=infinity" | sudo tee /etc/systemd/system/docker.service.d/memlock.conf
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
Increase the maximum number of memory map areas a process may have.
$ echo vm.max_map_count=262144 | sudo tee /etc/sysctl.d/99-max_map_count.conf
$ echo vm.max_map_count=262144 | sudo tee /etc/sysctl.d/99-max_map_count.conf
$ sudo sysctl --system
Elasticsearch 6
Docker-compose for Elasticsearch 6.8.11. This cluster consists of five nodes, but only three are master eligible ones.
version: "3.3" services: elasticsearch-eel: image: elasticsearch:6.8.11 environment: node.name: elasticsearch-eel cluster.name: elasticsearch-cluster discovery.zen.ping.unicast.hosts: elasticsearch-eel,elasticsearch-elk,elasticsearch-emu,elasticsearch-ewe,elasticsearch-ewt bootstrap.memory_lock: "true" discovery.zen.minimum_master_nodes: 2 ES_JAVA_OPTS: "-Xmx512m -Xms512m" volumes: - elasticsearch_data_eel:/usr/share/elasticsearch/data ulimits: memlock: soft: -1 hard: -1 networks: - elasticsearch-internal-network labels: - stack=elasticsearch6 - traefik.http.routers.elasticsearch.rule=PathPrefix(`/`) - traefik.http.services.elasticsearch.loadbalancer.server.port=9200 - traefik.http.services.elasticsearch.loadbalancer.healthcheck.path=/_cluster/health?local=true - traefik.http.services.elasticsearch.loadbalancer.healthcheck.interval=15s - traefik.http.services.elasticsearch.loadbalancer.healthcheck.timeout=10s elasticsearch-elk: image: elasticsearch:6.8.11 environment: node.name: elasticsearch-elk cluster.name: elasticsearch-cluster discovery.zen.ping.unicast.hosts: elasticsearch-eel,elasticsearch-elk,elasticsearch-emu,elasticsearch-ewe,elasticsearch-ewt bootstrap.memory_lock: "true" discovery.zen.minimum_master_nodes: 2 ES_JAVA_OPTS: "-Xmx512m -Xms512m" volumes: - elasticsearch_data_elk:/usr/share/elasticsearch/data ulimits: memlock: soft: -1 hard: -1 networks: - elasticsearch-internal-network labels: - stack=elasticsearch6 - traefik.http.routers.elasticsearch.rule=PathPrefix(`/`) - traefik.http.services.elasticsearch.loadbalancer.server.port=9200 - traefik.http.services.elasticsearch.loadbalancer.healthcheck.path=/_cluster/health?local=true - traefik.http.services.elasticsearch.loadbalancer.healthcheck.interval=15s - traefik.http.services.elasticsearch.loadbalancer.healthcheck.timeout=10s elasticsearch-emu: image: elasticsearch:6.8.11 environment: node.name: elasticsearch-emu cluster.name: elasticsearch-cluster discovery.zen.ping.unicast.hosts: elasticsearch-eel,elasticsearch-elk,elasticsearch-emu,elasticsearch-ewe,elasticsearch-ewt bootstrap.memory_lock: "true" discovery.zen.minimum_master_nodes: 2 ES_JAVA_OPTS: "-Xmx512m -Xms512m" volumes: - elasticsearch_data_emu:/usr/share/elasticsearch/data ulimits: memlock: soft: -1 hard: -1 networks: - elasticsearch-internal-network labels: - stack=elasticsearch6 - traefik.http.routers.elasticsearch.rule=PathPrefix(`/`) - traefik.http.services.elasticsearch.loadbalancer.server.port=9200 - traefik.http.services.elasticsearch.loadbalancer.healthcheck.path=/_cluster/health?local=true - traefik.http.services.elasticsearch.loadbalancer.healthcheck.interval=15s - traefik.http.services.elasticsearch.loadbalancer.healthcheck.timeout=10s elasticsearch-ewe: image: elasticsearch:6.8.11 environment: node.name: elasticsearch-ewe cluster.name: elasticsearch-cluster discovery.zen.ping.unicast.hosts: elasticsearch-eel,elasticsearch-elk,elasticsearch-emu,elasticsearch-ewe,elasticsearch-ewt bootstrap.memory_lock: "true" node.master: "false" discovery.zen.minimum_master_nodes: 2 ES_JAVA_OPTS: "-Xmx512m -Xms512m" volumes: - elasticsearch_data_ewe:/usr/share/elasticsearch/data ulimits: memlock: soft: -1 hard: -1 networks: - elasticsearch-internal-network labels: - stack=elasticsearch6 - traefik.http.routers.elasticsearch.rule=PathPrefix(`/`) - traefik.http.services.elasticsearch.loadbalancer.server.port=9200 - traefik.http.services.elasticsearch.loadbalancer.healthcheck.path=/_cluster/health?local=true - traefik.http.services.elasticsearch.loadbalancer.healthcheck.interval=15s - traefik.http.services.elasticsearch.loadbalancer.healthcheck.timeout=10s elasticsearch-ewt: image: elasticsearch:6.8.11 environment: node.name: elasticsearch-ewt cluster.name: elasticsearch-cluster discovery.zen.ping.unicast.hosts: elasticsearch-eel,elasticsearch-elk,elasticsearch-emu,elasticsearch-ewe,elasticsearch-ewt bootstrap.memory_lock: "true" node.master: "false" discovery.zen.minimum_master_nodes: 2 ES_JAVA_OPTS: "-Xmx512m -Xms512m" volumes: - elasticsearch_data_ewt:/usr/share/elasticsearch/data ulimits: memlock: soft: -1 hard: -1 networks: - elasticsearch-internal-network labels: - stack=elasticsearch6 - traefik.http.routers.elasticsearch.rule=PathPrefix(`/`) - traefik.http.services.elasticsearch.loadbalancer.server.port=9200 - traefik.http.services.elasticsearch.loadbalancer.healthcheck.path=/_cluster/health?local=true - traefik.http.services.elasticsearch.loadbalancer.healthcheck.interval=15s - traefik.http.services.elasticsearch.loadbalancer.healthcheck.timeout=10s traefik: image: traefik:2.3 command: - --entrypoints.web.address=:9200 - --providers.docker=true - --providers.docker.constraints=Label(`stack`,`elasticsearch6`) - --api.insecure - --accesslog=true depends_on: - elasticsearch-eel - elasticsearch-elk - elasticsearch-emu - elasticsearch-ewe - elasticsearch-ewt ports: - 9200:9200 - 8080:8080 - 8000:8000 volumes: - /var/run/docker.sock:/var/run/docker.sock networks: - elasticsearch-internal-network - traefik-external-network volumes: elasticsearch_data_eel: elasticsearch_data_elk: elasticsearch_data_emu: elasticsearch_data_ewe: elasticsearch_data_ewt: networks: elasticsearch-internal-network: internal: true traefik-external-network:
Cluster status.
$ curl http://localhost:9200/_cluster/health?pretty
{ "cluster_name" : "elasticsearch-cluster", "status" : "green", "timed_out" : false, "number_of_nodes" : 5, "number_of_data_nodes" : 5, "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 }
Node list.
$ curl http://localhost:9200/_cat/nodes?v
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name 172.30.0.3 75 99 27 1.62 2.87 3.45 di - elasticsearch-ewt 172.30.0.2 68 99 27 1.62 2.87 3.45 di - elasticsearch-ewe 172.30.0.4 35 99 27 1.62 2.87 3.45 mdi * elasticsearch-emu 172.30.0.6 69 99 27 1.62 2.87 3.45 mdi - elasticsearch-elk 172.30.0.5 46 99 27 1.62 2.87 3.45 mdi - elasticsearch-eel
Please read about node roles in Elasticsearch 6.
Elasticsearch 7
Docker-compose for Elasticsearch 7.8.1. This cluster consists of five nodes, but only three are master eligible ones.
version: "3.3" services: elasticsearch-tapir: image: elasticsearch:7.8.1 environment: node.name: elasticsearch-tapir cluster.name: elasticsearch-cluster discovery.seed_hosts: elasticsearch-tetra,elasticsearch-tiger cluster.initial_master_nodes: elasticsearch-tapir,elasticsearch-tetra,elasticsearch-tiger bootstrap.memory_lock: "true" ES_JAVA_OPTS: "-Xmx512m -Xms512m" volumes: - elasticsearch_data_tapir:/usr/share/elasticsearch/data ulimits: memlock: soft: -1 hard: -1 networks: - elasticsearch-internal-network labels: - stack=elasticsearch7 - traefik.http.routers.elasticsearch.rule=PathPrefix(`/`) - traefik.http.services.elasticsearch.loadbalancer.server.port=9200 - traefik.http.services.elasticsearch.loadbalancer.healthcheck.path=/_cluster/health?local=true - traefik.http.services.elasticsearch.loadbalancer.healthcheck.interval=15s - traefik.http.services.elasticsearch.loadbalancer.healthcheck.timeout=10s elasticsearch-tetra: image: elasticsearch:7.8.1 environment: node.name: elasticsearch-tetra cluster.name: elasticsearch-cluster discovery.seed_hosts: elasticsearch-tapir,elasticsearch-tiger cluster.initial_master_nodes: elasticsearch-tapir,elasticsearch-tetra,elasticsearch-tiger bootstrap.memory_lock: "true" ES_JAVA_OPTS: "-Xmx512m -Xms512m" volumes: - elasticsearch_data_tetra:/usr/share/elasticsearch/data ulimits: memlock: soft: -1 hard: -1 networks: - elasticsearch-internal-network labels: - stack=elasticsearch7 - traefik.http.routers.elasticsearch.rule=PathPrefix(`/`) - traefik.http.services.elasticsearch.loadbalancer.server.port=9200 - traefik.http.services.elasticsearch.loadbalancer.healthcheck.path=/_cluster/health?local=true - traefik.http.services.elasticsearch.loadbalancer.healthcheck.interval=15s - traefik.http.services.elasticsearch.loadbalancer.healthcheck.timeout=10s elasticsearch-tiger: image: elasticsearch:7.8.1 environment: node.name: elasticsearch-tiger cluster.name: elasticsearch-cluster discovery.seed_hosts: elasticsearch-tapir,elasticsearch-tetra cluster.initial_master_nodes: elasticsearch-tapir,elasticsearch-tetra,elasticsearch-tiger ES_JAVA_OPTS: "-Xmx512m -Xms512m" volumes: - elasticsearch_data_tiger:/usr/share/elasticsearch/data ulimits: memlock: soft: -1 hard: -1 networks: - elasticsearch-internal-network labels: - stack=elasticsearch7 - traefik.http.routers.elasticsearch.rule=PathPrefix(`/`) - traefik.http.services.elasticsearch.loadbalancer.server.port=9200 - traefik.http.services.elasticsearch.loadbalancer.healthcheck.path=/_cluster/health?local=true - traefik.http.services.elasticsearch.loadbalancer.healthcheck.interval=15s - traefik.http.services.elasticsearch.loadbalancer.healthcheck.timeout=10s elasticsearch-trout: image: elasticsearch:7.8.1 environment: node.name: elasticsearch-trout cluster.name: elasticsearch-cluster discovery.seed_hosts: elasticsearch-tapir,elasticsearch-tetra,elasticsearch-tiger cluster.initial_master_nodes: elasticsearch-tapir,elasticsearch-tetra,elasticsearch-tiger bootstrap.memory_lock: "true" node.master: "false" ES_JAVA_OPTS: "-Xmx512m -Xms512m" volumes: - elasticsearch_data_trout:/usr/share/elasticsearch/data ulimits: memlock: soft: -1 hard: -1 networks: - elasticsearch-internal-network labels: - stack=elasticsearch7 - traefik.http.routers.elasticsearch.rule=PathPrefix(`/`) - traefik.http.services.elasticsearch.loadbalancer.server.port=9200 - traefik.http.services.elasticsearch.loadbalancer.healthcheck.path=/_cluster/health?local=true - traefik.http.services.elasticsearch.loadbalancer.healthcheck.interval=15s - traefik.http.services.elasticsearch.loadbalancer.healthcheck.timeout=10s elasticsearch-tayra: image: elasticsearch:7.8.1 environment: node.name: elasticsearch-tayra cluster.name: elasticsearch-cluster discovery.seed_hosts: elasticsearch-tapir,elasticsearch-tetra,elasticsearch-tiger cluster.initial_master_nodes: elasticsearch-tapir,elasticsearch-tetra,elasticsearch-tiger bootstrap.memory_lock: "true" node.master: "false" ES_JAVA_OPTS: "-Xmx512m -Xms512m" volumes: - elasticsearch_data_tayra:/usr/share/elasticsearch/data ulimits: memlock: soft: -1 hard: -1 networks: - elasticsearch-internal-network labels: - stack=elasticsearch7 - traefik.http.routers.elasticsearch.rule=PathPrefix(`/`) - traefik.http.services.elasticsearch.loadbalancer.server.port=9200 - traefik.http.services.elasticsearch.loadbalancer.healthcheck.path=/_cluster/health?local=true - traefik.http.services.elasticsearch.loadbalancer.healthcheck.interval=15s - traefik.http.services.elasticsearch.loadbalancer.healthcheck.timeout=10s traefik: image: traefik:2.3 command: - --entrypoints.web.address=:9200 - --providers.docker=true - --providers.docker.constraints=Label(`stack`,`elasticsearch7`) - --api.insecure - --accesslog=true depends_on: - elasticsearch-tapir - elasticsearch-tetra - elasticsearch-tiger - elasticsearch-trout - elasticsearch-tayra ports: - 9200:9200 - 8080:8080 volumes: - /var/run/docker.sock:/var/run/docker.sock networks: - elasticsearch-internal-network - traefik-external-network volumes: elasticsearch_data_tapir: elasticsearch_data_tetra: elasticsearch_data_tiger: elasticsearch_data_trout: elasticsearch_data_tayra: networks: elasticsearch-internal-network: internal: true traefik-external-network:
Cluster status.
$ curl http://localhost:9200/_cluster/health?pretty
{ "cluster_name" : "elasticsearch-cluster", "status" : "green", "timed_out" : false, "number_of_nodes" : 5, "number_of_data_nodes" : 5, "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 }
Node list.
$ curl http://localhost:9200/_cat/nodes?v
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name 172.30.0.4 20 97 26 6.13 3.95 3.75 dilmrt * elasticsearch-tetra 172.30.0.5 47 97 26 6.13 3.95 3.75 dilrt - elasticsearch-tayra 172.30.0.3 62 97 26 6.13 3.95 3.75 dilrt - elasticsearch-trout 172.30.0.6 20 97 26 6.13 3.95 3.75 dilmrt - elasticsearch-tiger 172.30.0.2 33 97 26 6.13 3.95 3.75 dilmrt - elasticsearch-tapir
Please read about node roles in Elasticsearch 7.