Dokumentacja infrastruktury - deikare/iot-system GitHub Wiki
Opis infrastruktury
Data flow - podział logiczny
Data flow - podział logiczny kompaktowy
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
Sposób połączenia komponentów - schemat fizyczny
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 Kafkidocker-compose up -d reverse-proxy
- uruchomienie Traefikadocker-compose up -d influxdb
- uruchomienie bazy danych Influxdbdocker-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