Dokumentacja infrastruktury - deikare/iot-system GitHub Wiki

Opis infrastruktury

Data flow - podział logiczny

your-UML-diagram-name

Data flow - podział logiczny kompaktowy

your-UML-diagram-name

W tak zaprezentowanej architekturze użytkownik zarządza konfiguracją wszystkich urządzeń oraz sterowaniem urządzeniami wykonawczymi z poziomu frontendu. Hub wysyła do bazy danych influxdb pomiary z czujników oraz komunikaty o stanie urządzeń wykonawczych po otrzymaniu sterowania. Dane te są następnie przesyłane do części backendu odpowiedzialnej za zarządzanie danymi z urządzeń (dane są wysyłane po zapytaniu przez backend-data, który z kolei wysyła te dane dalej frontendowi). Sqlite-data-buffor służy jako bufor utrzymujący dane z huba na wypadek zerwania połączenia hub - baza danych. Z drugiej strony, hub jest jednocześnie podłączony pod Kafkę jako konsument konfiguracji oraz sterowań urządzeniami wykonawczymi (Kafka służy tutaj jako broker danych). Backend-device-configs obsługuje także zapisywanie konfiguracji urządzeń podpiętych do hubów do bazy sqlite-device-configs.

Opis urządzeń podłączanych pod system

Konfiguracja oraz diagnostyka dowolnego urządzenia

  • zarządzanie listą dostępnych urządzeń oraz ustawienie ich funkcji - czujnik / urządzenie wykonawcze
  • stan urządzenia - urządzenie włączone / wyłączone
  • parametry diagnostyczne - ostatnio widziany w systemie (rozumiane jako moment ostatniej generacji danych do bazy influxdb)

Dodatkowa konfiguracja czujników

  • zarządzanie listą generowanych pomiarów dla każdego czujnika - dostępne są na rynku czujniki, które jednocześnie generują na przykład pomiar ciśnienia, temperatury, wilgotności
  • dla każdego z dostępnych pomiarów ustawienie częstości generacji danych - zakładamy, że hub połączony jest z czujnikami na zasadzie master -> slave - to hub wymusza generację danych w czujniku

Dodatkowa konfiguracja urządzeń wykonawczych

  • zarządzanie listą sterowań każdym urządzeniem wykonawczym - dla każdego urządzenia wykonawczego użytkownik definiuje możliwe sterowania oraz komunikaty zwracane po otrzymywaniu sterowania - na przykład w przypadku sterowania bramą lista może mieć postać:
    • sterowanie: "open" - komunikaty zwrotne: "OK, gate opened", "ERROR, no response", "ERROR, gate was opened"
    • sterowanie: "close" - komunikaty zwrotne: "OK, gate closed", "ERROR, no response", "ERROR, gate was closed"

Sposób połączenia komponentów - schemat ideowy

your-UML-diagram-name

Sposób połączenia komponentów - schemat fizyczny

your-UML-diagram-name

Hub traktujemy jako urządzenie lokalne, do którego podłączone są urządzenia. Cała reszta aplikacji zlokalizowana jest w chmurze - dlatego należy generować certyfikat dla każdego nowego huba, ale wystarczy podpisać jednorazowo certyfikatami składniki systemu zlokalizowane w chmurze.

Fizyczna agregacja komponentów:

  • msg_broker składa się z serwerów Kafki oraz Zookeeperów
  • hub zawiera bufor sqlite-data-buffer
  • backend składa się z dwóch części logicznych - backend-device-configs oraz backend-data - na poprzednim diagramie przedstawione było logiczne połaczenie backendu, oprócz tego backend zawiera bazę sqlite-device-configs

Komponenty sqlite są zgrupowane w ten sposób, ponieważ baza sqlite jest bazą, która fizycznie jest zrealizowana jako zapis do plików - sqlite nie wymaga oddzielnego serwera w odróżnieniu od MySQL lub na przykład PostgreSQL. Wybrano taką bazę, ponieważ z założenia nie będzie ona przechowywać bardzo dużych wolumenów danych.

Funkcjonalności komponentów

Hub

  • łączenie z backendem w przypadku nowego hubu
  • konsumowanie z Kafki nowych konfiguracji urządzeń oraz sterowań czujnikami wysyłanych z aplikacji webowej
  • symulowanie czujników i urządzeń wykonawczych oraz wysyłanie takich danych do influxdb
  • w przypadku braku połączenia z influxdb buforowanie danych do wysłania w sqlite-data-buffer

Backend

  • autentykacja - tls
  • routing zapytań
  • walidacja danych używana przy:
    • odczytach z influxa
    • odczytach / zapisach do sqlite
    • wysyłania uaktualnień konfiguracji i komunikatów sterujących urządzeniami wykonawczymi do Kafki

Frontend

  • wyświetlanie użytkownikowi danych z różnych hubów
  • udostępnianie zarządzania urządzeniami
  • sterowanie urządzeniami wykonawczymi

Kafka

  • przyjmowanie kolejnych konfiguracji, sterowań urządzeniami wykonawczymi dla poszczególnych hubów
  • wystawianie ich do konsumpcji przez huba - konsumenta takich sterowań / konfiguracji
  • uwierzytelnianie podłączonych hubów

Zookeeper

  • administrowanie Kafką

Influxdb

  • przechowywanie danych z urządzeń
  • wysyłanie ich do backendu
  • scalanie jednakowych danych po upływie określonego czasu - zmniejszanie objętości starych odczytów

Traefik

  • serwer reverse-proxy uwierzytelniający połączenia hub - Influxdb
  • dodatkowa warstwa bezpieczeństwa ukrywająca bazę danych

Opis implementacji infrastruktury:

Składniki systemu

  • całość infrastruktury uruchamiana jest jako kontenery Dockera
  • wzajemna weryfikacja i szyfrowanie za pomocą mTLSa odbywa się przy komunikacji pomiędzy node'ami Zookeperów, brokerami Kafki, Zookeeper - Kafka, hub - Influxdb (w tym przypadku nie ma bezpośredniego połączenia, a wzajemne uwierzytelnianie odbywa się dzięki Traefikowi
  • są włączone trzy serwery Kafki oraz Zookeepera - w ten sposób Kafki oraz Zookeepery nie zatrzymają działania mimo awarii jednej Kafki lub/oraz jednego Zookeepera

Sposób uruchamiania infrastruktury:

Generowanie certyfikatów:

  • ./ca-generate-certs.sh - skrypt generujący CA - certyfikat oraz klucz CA, a także dodaje cert CA do truststore'a montowanego we wszystkich składnikach Kafki
  • ./zoo-generate-certs.sh - skrypt generujący certyfikat oraz klucz Zookeepera (procesów administrujących Kafką), a także tworzy keystore i truststore dla każdego node'a Zookeepera
  • ./kafka-generate-certs.sh - skrypt generujący certyfikaty oraz klucze brokerów Kafki, a także tworzy keystore i truststore dla każdego node'a Kafki
  • ./kafka-client-generate-certs.sh - skrypt generujący certyfikaty oraz klucze klientów Kafki, a także tworzy keystore i truststore dla każdego klienta
  • ./traefik-generate-certs.sh - skrypt generujący certyfikat oraz klucz Traefika
  • ./curl-generate-certs.sh - skrypt generujący certyfikat oraz klucz do uruchamiania curla - po uruchomieniu bazy można spingować bazę danych komendą curl -v --cacert certs/ca/ca.crt --cert certs/curl/curl.crt --key certs/curl/curl.key -H Host:influxdb.docker.localhost https://localhost

Uruchamianie infrastruktury:

  • docker-compose up -d zoo1 zoo2 zoo3 - uruchomienie Zookeeperów
  • w oddzielnej konsoli docker-compose logs -f - uruchamia się w ten sposób proces wyświetlający logi wszystkich kontenerów
  • docker-compose up -d kafka1 kafka2 kafka3 - uruchomienie brokerów Kafki
  • docker-compose up -d reverse-proxy - uruchomienie Traefika
  • docker-compose up -d influxdb - uruchomienie bazy danych Influxdb
  • docker-compose up -d influxdb-init - uruchomienie procesu inicjalizującego Influxdb

Testy

  • curl -H Host:backend --cacert certs/ca/ca.crt --cert certs/curl/curl.crt --key certs/curl/curl.key https://localhost/hubs
  • curl -H Host:influxdb --cacert certs/ca/ca.crt --cert certs/curl/curl.crt --key certs/curl/curl.key https://localhost/hubs
  • sudo ./mvnw spring-boot:build-image