ELK na Raspberry Pi 4

Instalacja najnowszej wersji (7.8.0) całego ELK zajeła mi sporo czasu, wpierw próbowałem na RPi 2 i 3, ale wymiękłem, nie dość że problemów co nie miara to jeszcze ograniczona ilość pamięci RAM zmuszała do odpalenia aplikacji z naprawdę małą jej ilością.

RPi4 daje nam wreszcie odpowiednią ilość pamięci by móc się pobawić elastikiem, oraz 64bitowy procesor co też nie jest bez znaczenia 🙂

Przygotowanie:

  1. Ustawienie zmiennej środowiskowej JAVA_HOME
    export JAVA_HOME=/usr/lib/jvm/default-java

Elasticsearch

Tutaj napotkałem chyba najwięcej problemów, ale większość z nich okazała się rozwiązana przez społeczność:

  1. Import klucza PGP
    wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
  2. Ściągnięcie pakietu w wersji no-jdk
    wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.8.0-no-jdk-amd64.deb
  3. Instalacja ściągniętego pakietu z wymuszeniem
    dpkg -i --force-all --ignore-depends=lib6 elasticsearch-7.8.0-no-jdk-amd64.deb
  4. Konfiguracja elasticsearch.yml
    1. network.host: 0.0.0.0
    2. discovery.seed_hosts: []
    3. xpack.ml.enabled: false
    4. bootstrap.system_call_filter: false
    5. node.master: true
    6. node.data: true
    7. node.ingest: true
    8. discovery.type: single-node
  5. Konfiguracja jvm.options
    1. -Xms1g
    2. -Xmx1g
  6. Konfiguracja /etc/defaults/elasticsearch
    1. JAVA_HOME=/usr/lib/jvm/default-java
  7. Start
    1. service elasticsearch start

Potencjalne problemy:

Brak odpowiedzi podczas startu elastica
Może tak być że ręczny start usługi elastica nie będzie chciał się zakończyć, bezpiecznie można to przerwać, a elastic w tle dalej będzie startował/działał.

apt – libc6:amd64 not installable
Podczas instalacji kazaliśmy ignorować brak zależności libc6, w efekcie apt rozpoznaje elastica jako nie w pełni zainstalowanego. Aby sobie z tym poradzić należy w pliku /var/lib/dpkg/status odnaleźć sekcję elasticsearch’a Package: elasticsearch a następnie w niej w sekcji Depends: usunąć wpis libc6, (włącznie ze spacją i przecinkiem :)).

NoClassDeffFoundError: Could not initialize class com.sun.jna.Native

  1. Instalacja AdoptOpenJdk
    1. wget -qO - https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | sudo apt-key add -
    2. echo "deb https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ buster main" | tee -a /etc/apt/sources.list.d/adoptopenjdk.list
    3. apt update
    4. apt install adoptopenjdk-11-hotspot
  2. Instalacja libjna-java
    1. apt install libjna-java
  3. Upewnienie się iż dysk gdzie elasticsearch ma tmp jest zamontowany z flagą exec
    1. /etc/default/elasticsearch
      1. ES_TMPDIR=...
    2. mount – sprawdzenie czy przy lokalizacji wskazanej w ES_TMPDIR nie ma flagi noexec, jeśli jest to należy przemontować dysk *warto pamiętać iż exec powinien być na końcu wpisu fstab, gdyż user go nadpisuje flagą noexec
  4. Podmiana biblioteki JNI
    1. mv /usr/share/elasticsearch/lib/jna-4.5.1.jar /usr/share/elasticsearch/lib/jna-4.5.1.jar.old
    2. wget -P /usr/share/elasticsearch/lib https://mvnrepository.com/artifact/net.java.dev.jna/jna/4.5.1

Kibana

Też nie ma tragedii, na co trzeba zwrócić uwagę to nodejs, który z wersji kibany nie jest kompatybilny z naszą architekturą procesowa (dla przypomnienia – ARM :P).
Podmianę można zrobić na kilka sposobów, ja postanowiłem zainstalować w systemie własnego node’a (10.19.0) i w konfiguracji zmienić jego lokalizację.
Aby tego dokonać trzeba zmodyfikować skrypt bash startowy kibany (/usr/share/kibana/bin/kibana) podając w linii 16 lokalizację nodejs’a dla zmiennej NODE.

  1. Instalacja NodeJS
    apt-get install nodejs
  2. Ściągnięcie kibany
    wget https://artifacts.elastic.co/downloads/kibana/kibana-7.8.0-amd64.deb
  3. Instalacja kibany z wymuszeniam
    dpkg -i --force-all kibana-7.8.0-amd64.deb
  4. Zmiana ścieżki dla nodejs /usr/share/kibana/bin/kibana
    NODE="/usr/bin/node"
  5. Uruchomienie kibany
    service kibana start
  6. Domyślnie kibana powinna działać na porcie 5601
    http://ip_address:5601/

Potencjalne problemy:

../node/bin/node: Exec format error
Wersja nodeJS wskazana kibanie jest niekompatybilna z architekturą. Musimy zaopatrzyć się w wersję dla architektury ARM i wskazać ją w konfiguracji (punkt 4).

Logstash

Tutaj sprawa wygląda dosyć prosto jeśli chodzi o proces instalacji. Natomiast w sumie to logstash zajął mi najwięcej czasu z uwagi na walkę z wyciekiem pamięci.

  1. Ściągnięcie pakietu
    wget https://artifacts.elastic.co/downloads/logstash/logstash-7.8.0.deb
  2. Instalacja
    dpkg -i logstash-7.8.0.deb
  3. Konfiguracja logstash.yml
    1. config.reload.automatic: true
    2. config.reload.interval: 10s
  4. Skopiowanie pliku architektury CPU dla FFI w JRubym
    1. Kopiujemy plik
      /usr/share/logstash/logstash-core/lib/jars/jruby-complete-9.2.11.1.jar/META-INF/jruby.home/lib/ruby/stdlib/ffi/platform/arm-linux/types.conf
      do lokalizacji
      /usr/share/logstash/logstash-core/lib/jars/jruby-complete-9.2.11.1.jar/META-INF/jruby.home/lib/ruby/stdlib/ffi/platform/arm-linux/platform.conf
  5. Start
    service logstash start

Potencjalne problemy:

File /sys/fs/cgroup/cpu/cpu.cfs_period_us cannot be found…

  1. Trzeba utworzyć pliki w strukturze katalogów ../sys/fs/cgroup/cpu/ o nazwie i zawartości jak poniżej
    1. cpu.cfs_period_us
      1000000
    2. cpu.cfs_quota_us
      -1
    3. cpu_stat
      nr_periods 0
      nr_throttled 0
      throttled_time 0
  2. Wskazać nową lokalizację w jvm.options
    1. -Dls.cgroup.cpu.path.override=../../../../<path>/sys/fs/cgroup/cpu/"

Wycieki pamięci

Przez jakiś czas nie mogłem się uporać z wyciekami pamięci logstasha. Remedium była ponowna instalacja wszystkiego oraz użycie innego JVM’a. Aktualnie całość działa zarówno na AdoptOpenJDK 11, jak i Bellsoft JDK 11.

Jeśli wszystko poszło dobrze powinieneś mieć działający cały stack ELK i możesz przystąpić do konfiguracji źródeł z których ELK ma czerpać dane. Dobrej zabawy 🙂