Elasticsearch 8 Cluster Installation

In dieser Schritt-für-Schritt-Anleitung zeigen wir Ihnen, wie Sie einen Elasticsearch-Cluster mit 3 Nodes und Kibana einrichten können. Zusätzlich dazu wird ein NGINX-Reverse-Proxy und Let's Encrypt für die SSL-Terminierung verwendet.

Voraussetzungen

  • mindestens 3x Elasticsearch-Server (Debian, nur vorinstalliert, mit vorinstalliertem NGINX Reverse Proxy, Standardkonfiguration)
  • Für diese Anleitung wird ein SSH-Zugang via root vorausgesetzt


Wir empfehlen für das Clustering von Elasticsearch ein privates Netzwerk bzw. eines unserer VPC-Netzwerke zu benutzen.


Der Artikel berücksichtigt keine Verteilung der verschiedenen Elasticsearch-Rollen auf verschiedene Server. Alle Server werden in der Anleitung als Master Nodes eingerichtet!



Vorbereitung Node 1

Limitierung des nutzbaren Arbeitsspeichers

Um die Lauffähigkeit auch bei einem größeren Workload zu gewährleisten, empfehlen wir Ihnen, den Arbeitsspeicher grundsätzlich zu limitieren, damit es zu keinem OOM-Kill (Out-Of-Memory) kommen kann.


Wir nutzen die folgende Formel (max. Server-RAM - 3 GiB = Elasticsearch-RAM-Limit) um einen Server mit 8 GiB Arbeitsspeicher die nachstehenden Begrenzungen zu hinterlegen:

nano /etc/elasticsearch/jvm.options.d/creoline.options


Fügen Sie den folgenden Teil ein und passen Sie die Werte ggf. entsprechend an:

# min ram
-Xms5g

# max ram
-Xmx5g


Elasticsearch-Grundkonfiguration Node 1 anpassen:

Zunächst muss der erste Node des Clusters grundlegend konfiguriert werden. Wichtig ist zu beachten, dass die folgenden Änderungen nur auf dem ersten Node durchgeführt werden und auch nur hier der Elasticsearch-Server aktiviert und gestartet wird.

Öffnen Sie die Elasticsearch-Server-Konfiguration wie folgt.

nano /etc/elasticsearch/elasticsearch.yml


Ändern Sie die Konfiguration folgendermaßen:

cluster.name: <cluster-name>

node.name: <Server-Name> 

node.roles: [ master, data ]

network.host: <VPC-IP-Adresse>

discovery.seed_hosts: ["<node-1-VPC-IP>:9300", "<node-2-VPC-IP>:9300", "<node-3-VPC-IP>:9300"]

cluster.initial_master_nodes: ["<node-1-fqdn>", "<node-2-fqdn>", "<node-3-fqdn>"]

xpack.security.http.ssl:
  enabled: true
  keystore.path: certs/http.p12

http.host: <VPC-IP-Adresse>

# Allow other nodes to join the cluster from anywhere
# Connections are encrypted and mutually authenticated
#transport.host: 0.0.0.0


Speichern Sie die geänderte Konfiguration ab und aktivieren Sie den Elasticsearch-Dienst:

systemctl enable elasticsearch.service


Anschließend können Sie diesen starten:

systemctl restart elasticsearch.service


Anpassung NGINX-Konfiguration Node 1-3:

Falls eine von der Arbeitsdomain des Servers abweichende Domain verwendet werden soll, muss diese noch als Server-Name in der NGINX-Konfiguration ergänzt werden. Alternativ können Sie die Arbeitsdomain auch einfach durch Ihre Custom-Domain ersetzen:

nano /etc/nginx/conf.d/elasticsearch-proxy.conf
server {
    server_name localhost sXXXXX.creoline.cloud <Custom-Domain.tld>;


Anschließend muss noch die IP-Adresse für die Portweiterleitung auf Port 9200 auf die VPC-IP-Adresse des Servers angepasst werden und die SSL-Verifizierung für Proxy-Verbindungen deaktiviert werden. Hiermit wird vermieden, dass es durch die interne, mit SSL abgesicherte Kommunikation der Elasticsearch-Nodes und Kibana zu Fehlern kommt:

server {
    server_name localhost sXXXXX.creoline.cloud <Custom-Domain.tld>;

    location / {
#        proxy_pass http://127.0.0.1:9200;
        proxy_pass https://<VPC-IP-Adresse>:9200;
        proxy_ssl_verify off;


Damit die Änderungen aktiv werden, muss der NGINX-Dienst neu geladen werden:

systemctl reload nginx.service


Let's Encrypt-Zertfikat für Custom-Domain ausstellen:

Mit dem folgenden Befehl können Sie ein kostenloses SSL-Zertifikat von Let's Encrypt für Ihre Custom-Domain ausstellen:

certbot --nginx -d <Custom-Domain> --non-interactive --agree-tos -m <E-Mail technischer Ansprechpartner Kunde>


Custom-Domain Kibana Node 1:

Bei der Verwendung einer Custom-Domain muss diese auch in der Konfiguration von Kibana hinterlegt werden:

nano /etc/kibana/kibana.yml
#server.name: "XXXXXX.creoline.cloud"
server.name: <"Custom-Domain.tld">


Zusätzlich muss die IP-Adresse des Elasticsearch-Hosts bei den folgenden beiden Zeilen der Konfiguration angepasst werden, damit Kibana den Elasticsearch-Server über die VPC-IP-Adresse des Servers anspricht:

# This section was automatically generated during setup.
#elasticsearch.hosts: ['https://127.0.0.1:9200']
elasticsearch.hosts: ['https://<VPC-IP-Adresse>:9200']

#xpack.fleet.outputs: [{id: fleet-default-output, name: default, is_default: true, is_default_monitoring: true, type: elasticsearch, hosts: ['https://127.0.0.1:9200'], ca_trusted_fingerprint: e69ac43bd506dfae1d65962422a0746e899a9449751b0199f464e73d25028510}]
xpack.fleet.outputs: [{id: fleet-default-output, name: default, is_default: true, is_default_monitoring: true, type: elasticsearch, hosts: ['https://<VPC-IP-Adresse>:9200'], ca_trusted_fingerprint: e69ac43bd506dfae1d65962422a0746e899a9449751b0199f464e73d25028510}]


Starten Sie den Kibana-Dienst neu, damit die Änderungen aktiv werden:

systemctl restart kibana.service



Cluster-Einrichtung

Generieren Sie im nächsten Schritt einen Cluster-Enrollment-Token auf Node 1 und speichern sich diesen zwischen.

Dieser wird später zur Einbindung von Node 2 und Node 3 in den Cluster benötigt.

Sie können den Enrollment-Token wie folgt generieren:

 /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node

eyJ2ZXIiOiI4LjEyLjIiLCJhZHIiOlsiNS4xLjc4LjE3OjkyMDAiXSwiZmdyIjoiMDJjMGRkMDdlNDNjM2NmYTFlMzk3YTFmM
GM2MjIzOTM2YjMwYjYwZTk0ZGM5ODA3YTgxNzA0NzM3NTIxNzljZSIsImtleSI6IktRNHU5WTBCdUN2VlJ5bm0yRVJ4Ojd4Sj
c3UWoxUVdLQ054UXdSTDRWNUEifQ==


Anschließend müssen Sie noch einen Enrollment-Token für die spätere Intergeration der Kibana-Instanzen von Node 2 und Node 3 erstellen. Speichern Sie sich den ausgegebenen Token ebenfalls separat zwischen:

/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token --scope kibana

eyJ2ZXIiOiI4LjEyLjIiLCJhZHIiOlsiNS4xLjc4LjE3OjkyMDAiXSwiZmdyIjoiMDJjMGRkMDdlNDNjM2NmYTFlMzk3YTFmMGM
2MjIzOTM2YjMwYjYwZTk0ZGM5ODA3YTgxNzA0NzM3NTIxNzljZSIsImtleSI6IlVLTjc5WTBCVWtnSDVsMndzM3FIOnJibFk4Q2
5TU3ppXzdxNjlYT0lqSEEifQ==


Elasticsearch Cluster Join


Sollte der Elasticsearch-Server auf Node 2 oder 3 bereits einmal konfiguriert und gestartet worden sein, muss dieser zwangsläufig vollständig neu installiert werden, da schon nach einem einmaligen Start nach der Installation kein Cluster Join mehr möglich ist.


Führen Sie die folgenden Befehle aus, um Elasticsearch und Kibana zu deinstallieren, eventuell noch vorhandene Dateien zu bereinigen und erneuert zu installieren:

apt purge elasticsearch kibana

rm -rf /etc/elasticsearch
rm -rf /var/lib/elasticsearch
rm -rf /etc/kibana
rm -rf /var/lib/kibana

apt update && apt install -y elasticsearch kibana


Automatischen Service-Neustart aktivieren

Kopieren Sie den nachstehenden Befehl vollständig und führen Sie diesen aus:

echo "[Service]
Restart=on-failure" > /etc/systemd/system/elasticsearch.service.d/override.conf


Führen Sie anschließend den folgenden Befehl aus, damit die geänderte Konfiguration aktiv wird:

systemctl daemon-reload


Cluster Join Node 2 und 3

Führen Sie nach der Installation auf Node 2 und 3 direkt den folgenden Befehl aus, um den Cluster Join durchzuführen. Ersetzen Sie <Enrollment-Token-Node-1> durch den zuvor generierten Enrollment-Token für den Cluster Join:

/usr/share/elasticsearch/bin/elasticsearch-reconfigure-node --enrollment-token <Enrollment-Token-Node-1>


Danach sollte in der Konfigurationsdatei /etc/elasticsearch/elasticsearch.yml folgender Eintrag hinzugefügt worden sein:

discovery.seed_hosts: ["<VPC-IP-Adresse>:9300"] -> IP-Adresse entspricht der von Node 1!


Beachten Sie, dass durch den Cluster-Join nur noch die Zugangsdaten für den Benutzer elastic genutzt werden können, die durch Node 1 gesetzt wurden.



Einrichtung Node 2 + Node 3

Im weiteren Verlauf kann nach dem erfolgreichen Cluster Join die Konfiguration von Elasticsearch und Kibana angepasst werden.


Limitierung des nutzbaren Arbeitsspeichers

Beispiel für einen Server mit 8 GiB Arbeitsspeicher:

nano /etc/elasticsearch/jvm.options.d/creoline.options

Fügen Sie Folgendes ein:

# min ram
-Xms5g

# max ram
-Xmx5g


Elasticsearch-Grundkonfiguration Node 2 & 3 anpassen:

Jetzt kann die Elasticsearch-Konfiguration ähnlich wie bei Node 1 angepasst werden:

nano /etc/elasticsearch/elasticsearch.yml

Legen Sie die Einstellungen wie folgt fest und speicher Sie diese ab:

cluster.name: <cluster-name>

node.name: <Server-Name> 

node.roles: [ master, data ]

network.host: <10.20.0.x (VPC-Netzwerk/IP-Adresse)>

cluster.initial_master_nodes: ["<node-1-fqdn>", "<node-2-fqdn>", "<node-3-fqdn>"]

xpack.security.http.ssl:
  enabled: true
  keystore.path: certs/http.p12

http.host: <VPC-IP-Adresse>

# Allow other nodes to join the cluster from anywhere
# Connections are encrypted and mutually authenticated
#transport.host: 0.0.0.0


Elasticsearch + Kibana aktivieren und starten:

Damit die Änderungen aktiv werden, müssen Sie Elasticserach und Kibana aktivieren und starten:

systemctl daemon-reload
systemctl enable elasticsearch.service
systemctl start elasticsearch.service


Generieren der Kibana Encryption Keys

Generieren Sie die Kibana Encryption Keys wie folgt, damit Kibana im späteren Verlauf in der Lage ist, mit dem Elasticsearch-Dienst zu kommunizieren:

/usr/share/kibana/bin/kibana-encryption-keys generate -q >> /etc/kibana/kibana.yml


Grundkonfiguration Kibana:

Öffnen Sie die Kibana-Konfiguration auf Node 2 und Node 3:

nano /etc/kibana/kibana.yml

Passen Sie die Konfiguration wie folgt an.

Bei der Verwendung einer Custom-Domain muss diese auch für Kibana hinterlegt werden:

server.host: "127.0.0.1"
server.port: 5601
#server.name: "sXXXXX.creoline.cloud"
server.name: <"Custom-Domain.tld">
server.basePath: "/kibana"
server.rewriteBasePath: true
server.publicBaseUrl: "http://127.0.0.1/kibana"

Starten Sie Kibana neu, damit die Änderungen aktiv werden:

systemctl enable kibana.service
systemctl start kibana.service


Elasticsearch und Kibana auf Node 2 & 3 mit Node 1 verbinden

Falls Sie die Arbeitsdomain des Servers verwenden, könne Sie Kibana wie folgt im Browser aufrufen:

https://XXXXXX.creoline.cloud/kibana

Falls Sie eine Custom-Domain verwenden, können Sie Kibana wie folgt aufrufen:

https://<Custom-Domain.tld>/kibana

Fügen Sie in der nachfolgenden Ansicht den zuvor für Kibana generierten Enreollment-Token ein und bestätigen Sie die Angaben.


Kibana-Bestätigungscode zur Fertigstellung des Setups generieren

Den Bestätigungscode zum Abschluss der Kibana-Einrichtung können Sie wie folgt generieren. Führen Sie den Befehl auf dem Node aus, auf dem Sie gerade Kibana einrichten (Node 2 oder Node 3):

/usr/share/kibana/bin/kibana-verification-code


Tragen Sie den 6-stelligen Code ein und warten Sie, bis das Setup abgeschlossen ist.

Nach dem Abschluss des Setups sollte Folgendes in die kibana.yml eingefügt worden sein:

# This section was automatically generated during setup.
elasticsearch.hosts: ['https://<VPC-IP-Node-1>:9200']
elasticsearch.serviceAccountToken: AAEAAWVsYXN0aWMva2liYW5hL2Vucm9sbC1wcm9jZXNzLXRva2VuLTE3NDQ4Nzc5MjI0NTY6TWxDY2JtUEtTa0NONkxkeTVaN0VkUQ
elasticsearch.ssl.certificateAuthorities: [/var/lib/kibana/ca_1744877923188.crt]
xpack.fleet.outputs: [{id: fleet-default-output, name: default, is_default: true, is_default_monitoring: true, type: elasticsearch, hosts: ['https://<VPC-IP-Node-1>:9200'], ca_trusted_fingerprint: e69ac43bd506dfae1d65962422a0746e899a9449751b0199f464e73d25028510}]



Abschluss des Cluster-Setups

Cluster-Setup finalisieren

Nachdem Kibana eingerichtet wurde, ist das Cluster Setup annähernd fertig.

Es müssen nun folgende abschließende Änderungen an der elasticsearch.yml auf allen Nodes vorgenommen werden:


Die folgenden Anpassungen müssen spätestens vor Inbetriebnahme des Clusters in den Produktivbetrieb, frühestens nach dem ersten Neustart aller Elastic-Nodes, nachdem der Cluster initial aufgesetzt wurde, erfolgen, da hier ansonsten ein potenzielles Sicherheitsrisiko entstehen kann.


nano /etc/elasticsearch/elasticsearch.yml

→ cluster.initial_master_nodes auskommentieren

# Additional nodes can still join the cluster later
#cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]

→ discovery.seed_hosts anpassen (Node 2 & 3 hinzufügen)

# Discover existing nodes in the cluster
discovery.seed_hosts: ["VPC-IP-Node-1:9300", "VPC-IP-Node-2:9300", "VPC-IP-Node-3:9300"]


Elasticsearch neu starten:

systemctl restart elasticsearch.service


Checks durchführen

Überprüfung der Inter-Node-Kommunikation via curl:

curl -k -XGET "https://<FQDN>/_cat/nodes?v" -u elastic
Enter host password for user 'elastic':
ip        heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
<VPC-IP-Node-1>   9          99   1    0.00    0.03     0.06 dm        *      Node-1
<VPC-IP-Node-2>  11          91   3    0.17    0.11     0.09 dm        -      Node-2
<VPC-IP-Node-3>   4          92   2    0.16    0.18     0.12 dm        -      Node-3


Health-Check durchführen via curl:

curl -k -XGET "https://<FQDN>/_cat/health?v" -u elastic
Enter host password for user 'elastic':
epoch      timestamp cluster     status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1710497165 10:06:05  cluster-name green           3         3     61  30    0    0        0             0                  -                100.0%


Alternativ können Sie die folgenden URLs auch in Ihrem Browser aufrufen, um nach einer erfolgreichen Authentifizierung die entsprechenden Ausgaben zu erhalten:

https://XXXXX.creoline.cloud/_cat/nodes?v
https://XXXXX.creoline.cloud/_cat/health?v



Empfehlungen Cloud-Firewall

Wir empfehlen Ihnen, die folgenden Firewall-Regeln in dieser Reihenfolge in der Cloud-Firewall für alle Cluster-Nodes zu hinterlegen:


  • Zugriff auf Port 443 nur für bestimmte IPv4/IPv6-Adressen erlauben
  • Zugriff auf Port 22 nur für bestimmte IPv4/IPv6-Adressen erlauben
  • Zugriff auf Port 9200 auf dem WAN-Interface explizit sperren
  • Zugriff auf Port 9300 auf dem WAN-Interface explizit sperren
  • Zugriff auf Port 5601 auf dem WAN-Interface explizit sperren
  • Alle weiteren Zugriffe verbieten