Hoy hemos montado un cluster ElasticSearch listo para producción usando contenedores Docker. Hemos visto en la practica lo que nos simplifica la vida con el escalado usar Docker, y eso que ni siquiera lo hemos usado con Kubernetes o Docker Swarm.
Conceptos básicos sobre Clusters
Para no repetirme me voy a remitir al post “Instalación de un cluster de Apache Kafka paso a paso
” donde explicamos los conceptos como nodo, replica, partición(En ElasticSearch es Shard), etc.
Repito que es muy importante ver como funcionan varias tecnologías(En este caso ElasticSearch y Kafka) para tener una visión amplia y saber realmente como funcionan los cluster y el escalado.
Creación de la imagen Docker
El primer paso es montar la imagen Docker. En este caso hemos partido de una carpeta con lo siguiente: Una carpeta llamada ‘/soft’ donde tenemos ElasticSearch tal como viene de fábrica, un fichero llamado ‘Dockerfile’ y una carpeta llamada ‘/config’ con dos ficheros que pasaremos a explicar ahora:
El primer fichero de la carpeta ‘/config’ es el fichero de configuración principal de ElasticSearch ‘/config/elasticsearch-7.9.2/config/elasticsearch.yml’ y tenemos que configurar lo siguiente:
cluster.name: my-application network.host: 0.0.0.0 discovery.seed_hosts: ["172.17.0.1", "172.17.0.2", "172.17.0.3", "172.17.0.4", "172.17.0.5"] cluster.initial_master_nodes: ["master-1"]
Donde ‘cluster.name’ es el nombre del cluster y todos los nodos del cluster deben tener el mismo, ‘network.host’ es el host del que resuelve las peticiones(Con este valor resuelve todos), el ‘discovery.seed_hosts’ serán las IPs donde el nodo buscará el cluster y ‘cluster.initial_master_nodes’ es un listado de nombres de los hosts que inicialmente serán nodos master.
A parte de esta configuración, en el script de arranque ‘/config/start.sh’ añadiremos dos propiedades mas: ‘node.name’ con el nombre del nodo(Tiene que ser único por cada nodo) y ‘node.master’ con valores true/false en función de si se trata de un nodo master o no. El script queda de la siguiente manera:
#!/bin/bash export JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64" echo "node.name: $NODENAME" >> /opt/elasticsearch-7.9.2/config/elasticsearch.yml if [ "$NODEMASTER" == "" ]; then echo "node.master: false" >> /opt/elasticsearch-7.9.2/config/elasticsearch.yml else echo "node.master: true" >> /opt/elasticsearch-7.9.2/config/elasticsearch.yml fi /opt/elasticsearch-7.9.2/bin/elasticsearch
El script inicializa la variable ‘JAVA_HOME’, añade la configuración de las nuevas propiedades al fichero de configuración en función de lo que encuentre en las variables de entorno y arranca Elasticsearch.
Y con todo esto, el siguiente ‘Dockerfile’ será el que nos compilará la imagen:
FROM ubuntu:18.04 RUN apt-get --fix-missing update RUN apt-get -y install openjdk-11-jdk COPY ./soft /opt COPY ./config /opt RUN chmod -R 777 /opt # Add none root user RUN useradd usr && echo "usr:usr" | chpasswd && adduser usr sudo USER usr CMD /opt/start.sh
Finalmente creamos la imagen ejecutando el siguiente comando de Docker(Compila la imagen y le llama elasticcluster):
sudo docker build . -t elasticcluster
Arrancar los contenedores
Ahora que ya tenemos creada la imagen ya podemos empezar a arrancar nodos, pero antes tendremos que inicializar la configuración del servidor. El motivo, es que por temas de optimización ElasticSearch obliga a configurar lo siguiente:
# Deshabilitar swapping sudo swapoff -a # Memória virtual sudo sysctl -w vm.max_map_count=262144 # Number or threads sudo sysctl -w fs.file-max=65536
Ya podemos empezar a arrancar algun nodo Master con el siguiente comando:
sudo docker run --rm -e NODENAME=master-1 -e NODEMASTER=1 elasticcluster
Y algunos nodos sin ser master(Recordad que cada nodo tiene que tener un nombre diferente):
sudo docker run --rm -e NODENAME=nodo-1 elasticcluster
Trasteando con el Cluster
Ya podemos empezar a trastear con el cluster. Si todo ha ido bien tenemos que poder trabajar con los mismos datos en cualquiera de los nodos(El cluster se encarga de gestionar el enrutado, etc.). Aquí algunas de las peticiones que le hemos hecho a ElasticSearch:
# Hemos creado un índice llamado 'test' con dos shards y una replica por shard curl -XPUT http://172.17.0.3:9200/test -d ' { "settings": { "number_of_shards": 2, "number_of_replicas":1 }}' -H 'Content-Type: application/json' # Con esta petición comprobamos el estado y ubicación de los shards y las replicas curl -XGET http://172.17.0.3:9200/_cat/shards/ # Hemos añadido contenido al índice curl -XPOST '172.17.0.3:9200/test/_bulk?pretty' -d' { "index" : {} } { "num": "2015/56", "cliente": 13, "importe":189 } { "index" : {} } { "num": "2015/57", "cliente": 45, "importe":190 } ' -H 'Content-Type: application/json' # Hemos buscado el contenido del índice curl -XGET 172.17.0.3:9200/test/_search
Como veis, con el cluster bien configurado el escalado es fácil para el equipo de operaciones y totalmente transparente para el equipo de desarrollo. Contadme que tal en los comentarios.
Hola!
No veo el Dockerfile, por favor nos ayudas a publicarlo? Sería de gran ayuda.
Saludos cordiales.
Eps! Fue un descuido. Ya lo tenéis.
Hola Alberto! Lo primero gracias, por el artículo y el video. Por cierto, te he dejado este comentario en otro artículo (logstash). Perdón.
Al seguir los pasos descritos en el video, (estoy trabajando en un mac) cuando trato de acceder a la url en la que se levanta tanto el nodo máster como el resto, no logro acceder a elastic… Puede ser que sea necesario configurar algún setting the red al crear la imagen de docker? Saludos,