Skip to content

Instantly share code, notes, and snippets.

@wsoula
Created February 21, 2018 20:27
Show Gist options
  • Save wsoula/a4434233e5c63b0044236e026c1ffa1a to your computer and use it in GitHub Desktop.
Save wsoula/a4434233e5c63b0044236e026c1ffa1a to your computer and use it in GitHub Desktop.
Run a 3 node consul cluster. Then, using the elasticsearch-consul-discovery plugin, create a 3 node elasticsearch cluster
docker-entrypoint.sh
```
#!/bin/bash
set -e
# Files created by Elasticsearch should always be group writable too
umask 0002
run_as_other_user_if_needed() {
if [[ "$(id -u)" == "0" ]]; then
# If running as root, drop to specified UID and run command
exec chroot --userspec=1000 / "${@}"
else
# Either we are running in Openshift with random uid and are a member of the root group
# or with a custom --user
exec "${@}"
fi
}
# Allow user specify custom CMD, maybe bin/elasticsearch itself
# for example to directly specify `-E` style parameters for elasticsearch on k8s
# or simply to run /bin/bash to check the image
if [[ "$1" != "eswrapper" ]]; then
if [[ "$(id -u)" == "0" && $(basename "$1") == "elasticsearch" ]]; then
# centos:7 chroot doesn't have the `--skip-chdir` option and
# changes our CWD.
# Rewrite CMD args to replace $1 with `elasticsearch` explicitly,
# so that we are backwards compatible with the docs
# from the previous Elasticsearch versions<6
# and configuration option D:
# https://www.elastic.co/guide/en/elasticsearch/reference/5.6/docker.html#_d_override_the_image_8217_s_default_ulink_url_https_docs_docker_com_engine_reference_run_cmd_default_command_or_options_cmd_ulink
# Without this, user could specify `elasticsearch -E x.y=z` but
# `bin/elasticsearch -E x.y=z` would not work.
set -- "elasticsearch" "${@:2}"
# Use chroot to switch to UID 1000
exec chroot --userspec=1000 / "$@"
else
# User probably wants to run something else, like /bin/bash, with another uid forced (Openshift?)
exec "$@"
fi
fi
# Parse Docker env vars to customize Elasticsearch
#
# e.g. Setting the env var cluster.name=testcluster
#
# will cause Elasticsearch to be invoked with -Ecluster.name=testcluster
#
# see https://www.elastic.co/guide/en/elasticsearch/reference/current/settings.html#_setting_default_settings
declare -a es_opts
while IFS='=' read -r envvar_key envvar_value
do
# Elasticsearch env vars need to have at least two dot separated lowercase words, e.g. `cluster.name`
if [[ "$envvar_key" =~ ^[a-z0-9_]+\.[a-z0-9_]+ ]]; then
if [[ ! -z $envvar_value ]]; then
es_opt="-E${envvar_key}=${envvar_value}"
es_opts+=("${es_opt}")
fi
fi
done < <(env)
# The virtual file /proc/self/cgroup should list the current cgroup
# membership. For each hierarchy, you can follow the cgroup path from
# this file to the cgroup filesystem (usually /sys/fs/cgroup/) and
# introspect the statistics for the cgroup for the given
# hierarchy. Alas, Docker breaks this by mounting the container
# statistics at the root while leaving the cgroup paths as the actual
# paths. Therefore, Elasticsearch provides a mechanism to override
# reading the cgroup path from /proc/self/cgroup and instead uses the
# cgroup path defined the JVM system property
# es.cgroups.hierarchy.override. Therefore, we set this value here so
# that cgroup statistics are available for the container this process
# will run in.
export ES_JAVA_OPTS="-Des.cgroups.hierarchy.override=/ $ES_JAVA_OPTS"
# Determine if x-pack is enabled
if bin/elasticsearch-plugin list -s | grep -q x-pack; then
# Setting ELASTIC_PASSWORD is mandatory on the *first* node (unless
# LDAP is used). As we have no way of knowing if this is the first
# node at this step, we can't enforce the presence of this env
# var.
if [[ -n "$ELASTIC_PASSWORD" ]]; then
[[ -f config/elasticsearch.keystore ]] || run_as_other_user_if_needed "bin/elasticsearch-keystore" "create"
run_as_other_user_if_needed echo "$ELASTIC_PASSWORD" | bin/elasticsearch-keystore add -x 'bootstrap.password'
fi
fi
if [[ "$(id -u)" == "0" ]]; then
# If requested and running as root, mutate the ownership of bind-mounts
if [[ -n "$TAKE_FILE_OWNERSHIP" ]]; then
chown -R 1000:0 /usr/share/elasticsearch/{data,logs}
fi
fi
consul agent -retry-join consul1 -client 0.0.0.0 -data-dir /var/lib/consul &
sed -i s/@hostname@/`hostname`/g /var/lib/consul/service.json.template
sed -i s/@ip@/`hostname -I | awk '{print $1}'`/g /var/lib/consul/service.json.template
sleep 10
curl --request PUT --data @/var/lib/consul/service.json.template 0.0.0.0:8500/v1/agent/service/register
sleep 30
run_as_other_user_if_needed /usr/share/elasticsearch/bin/elasticsearch "${es_opts[@]}"
```
service.json.template
```
{
"ID":"svc-@hostname@",
"Name":"svc-elasticsearch",
"Address":"@ip@",
"Port":9300,
"Check":{
"HTTP":"http://@hostname@:9200/_cat",
"Interval":"5s"
}
}
```
Dockerfile
```
FROM docker.elastic.co/elasticsearch/elasticsearch:6.2.1
RUN /usr/share/elasticsearch/bin/elasticsearch-plugin install -b https://github.com/vvanholl/elasticsearch-consul-discovery/releases/download/6.2.1.0/elasticsearch-consul-discovery-6.2.1.0.zip
RUN curl -OL https://releases.hashicorp.com/consul/1.0.6/consul_1.0.6_linux_amd64.zip && \
unzip consul_1.0.6_linux_amd64.zip && \
mv consul /usr/local/bin/consul && \
mkdir /var/lib/consul
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
COPY service.json.template /var/lib/consul
# Below is from elasticsearch Dockerfile as we are using a copy of their entrypoint
# Openshift overrides USER and uses ones with randomly uid>1024 and gid=0
# Allow ENTRYPOINT (and ES) to run even with a different user
RUN chgrp 0 /usr/local/bin/docker-entrypoint.sh && \
chmod g=u /etc/passwd && \
chmod 0775 /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
```
docker-compose.yml
```
version: "3"
services:
consul1:
image: consul
container_name: consul1
#hostname: consul1
ports:
- "8400:8400"
- "8500:8500"
- "8600:53"
command: "agent -server -bootstrap-expect 3 -ui -client 0.0.0.0"
consul2:
image: consul
container_name: consul2
#hostname: consul2
#expose:
# - "8400"
# - "8500"
# - "8600"
command: "agent -server -retry-join consul1 -client 0.0.0.0"
depends_on:
- consul1
consul3:
image: consul
container_name: consul3
#hostname: consul3
#expose:
# - "8400"
# - "8500"
# - "8600"
command: "agent -server -retry-join consul1 -client 0.0.0.0"
depends_on:
- consul1
elasticsearch1:
image: wsoula-elasticsearch-consul
container_name: elasticsearch1
hostname: elasticsearch1
environment:
- cluster.name=docker-cluster-wsoula
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- discovery.zen.hosts_provider=consul
- discovery.consul.service-names=svc-elasticsearch
- discovery.consul.local-ws-host=http://consul1
#- discovery.consul.healthy=false
- discovery.zen.minimum_master_nodes=2
- xpack.security.enabled=false
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- esdata1:/usr/share/elasticsearch/data
ports:
- "9200:9200"
- "9300:9300"
depends_on:
- consul1
- consul2
- consul3
elasticsearch2:
image: wsoula-elasticsearch-consul
container_name: elasticsearch2
hostname: elasticsearch2
environment:
- cluster.name=docker-cluster-wsoula
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
#- discovery.type=consul
- discovery.zen.hosts_provider=consul
- discovery.consul.service-names=svc-elasticsearch
- discovery.consul.local-ws-host=http://consul1
#- discovery.consul.healthy=false
#- "discovery.zen.ping.unicast.hosts=elasticsearch1,elasticsearch3"
- discovery.zen.minimum_master_nodes=2
- xpack.security.enabled=false
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- esdata2:/usr/share/elasticsearch/data
expose:
- "9200"
- "9300"
depends_on:
- elasticsearch1
elasticsearch3:
image: wsoula-elasticsearch-consul
container_name: elasticsearch3
hostname: elasticsearch3
environment:
- cluster.name=docker-cluster-wsoula
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
#- discovery.type=consul
- discovery.zen.hosts_provider=consul
- discovery.consul.service-names=svc-elasticsearch
- discovery.consul.local-ws-host=http://consul1
#- discovery.consul.healthy=false
#- "discovery.zen.ping.unicast.hosts=elasticsearch2,elasticsearch1"
- discovery.zen.minimum_master_nodes=2
- xpack.security.enabled=false
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- esdata3:/usr/share/elasticsearch/data
expose:
- "9200"
- "9300"
depends_on:
- elasticsearch2
volumes:
esdata1:
driver: local
esdata2:
driver: local
esdata3:
driver: local
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment