Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
.idea
venv/
65 changes: 2 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,2 @@
# Введение
Данная практика посвещена базовым принципам Docker. Для выполнения практики необходимо использовать 3 виртуальные машины Linux.

# Задание

Необходимо развернуть следующую систему:

![image](assets/images/DockerTask.png)

Симуляторы сенсоров, развернутые в докер контейнерах, публикуют сообщения на Mqtt брокер. Сервис Consumer подписывается на все сообщение,
опубликованные в брокере, и заносит их в базу данных временных рядов. Сервис dashboard отображает графики полученных данных от сервисов.

Для выполнения данного задания необходимо:
1. Использовать три виртуальные машины из предыдущей практики. Установить на каждой docker и docker-compose.

2. Linux A.
1. Разработать скрипты - симулятор технологических данных. Создать класс Sensor, а также наследников этого класса (указать 4 реально существующих типа датчиков, например, температура, давление, потребляемый ток).
2. В основной программе реализовать клиента, который подключается к mqtt брокеру и публикует сообщения.
3. Конфигурацию типов датчиков вывести через переменные среды
4. Запуск реализовать с помощью докер контейнеров. Для запуска нескольких типов использовать docker-compose.
5. В итоге сделать 4 типа датчиков, запустить 6 контейнеров разных типов, где задается:
* тип датчика
* название датчика
* дискретность публикации сообщений
* (ДОП ЗАДАЧА, НЕОБЯЗАТЕЛЬНО) тип формулы (подумайте как можно через конфигурацию повлиять на характер генерации нового числа)
* в формуле предусмотрите в качестве операнда дату вашего рождения (например умножение на год рождения или месяц)
* (ДОП ЗАДАЧА, НЕОБЯЗАТЕЛЬНО) тип топика (json формат (topic - /sensor/type, value {"name":"sensor1", "value": 22.4} ) или значение в конкретный топик (topic - /sensor/type/value, value - 22.4))
6. Залить на свою страницу в докерхаб созданный image контейнера в публичный репозиторий.

3. Linux B
1. Развернуть mosquitto брокер с помощью docker. Настроить проброс портов, необходимый для работы приложения.
2. Настроить конфигурационный файл для брокера. Использовать volume для подгрузки файла в докер.
3. В файрволе открыть порт, необходимый для работы брокера.
4. Linux C
1. Развернуть influxdb (1.8 версия), telegraf, grafana с помощью docker-compose
2. Настроить подписку телеграфа на mqtt топики брокера
3. Сохранять все сообщения в influxdb
4. В grafana вывести дашборды с текущими значениями всех датчиков и агрегированными показаниями (среднее значение по всем датчикам) - сделать скриншот
5. Необходимо создать volume для каждого контейнера с конфигурационными файлами. (ДОП ЗАДАЧА, НЕОБЯЗАТЕЛЬНО) При пересоздании контейнеров конфигурация дашбордов должна сохранится (без самих данных).
6. В конфигурационных файлах ссылаться по alias контейнеров (не по ip адресам)
5. При загрузки задания в гит репозиторий создать две ветки develop и master. В master загрузить только readme - задание.
В ветку develop - загружаем сделанное задание. Как только отправляете мне на проверку задание, создаете пул реквест в ветку мастер и назначаете меня ревьювером. Таким образом я смогу комментировать ваш репозиторий.
6. Оформить инструкцию в виде Markdown файла. Приложить конфигурационные файлы в репозиторий.
Критерием успеха выполнения задания будет являтся также написанная инструкция по запуску ваших контейнеров. То есть, если я загружу с докерхаба ваш image, запущу docker-compose файлы на своих виртуальных машинах, и при этом смогу зайти в интерфейс и посмотреть дашборд с потоком данных, то задание выполнено.

Репозиторий оформить следующим образом:
- root
- assets
- images - картинки для отчета
- vms
- client
- simulator - код симулятора и докерфайл
- gateway
- mosquitto - папка с конфигом для mosquitto + sh скрипт по запуску докера
- server
- grafana - конфиги для тома графаны
- influxdb - конфиги для тома инфлукса
- telegraf - конфиги для тома телеграфа
- docker-compose.yml

- report.md - Отчет markdown

P.S. опираться можно на данную [статью](https://coderlessons.com/articles/programmirovanie/raspberry-pi-iot-datchiki-influxdb-mqtt-i-grafana)
# Docker-Practice
Sensor & MQTT & Telegraf & InfluxDB & Grafana & Docker
Binary file added assets/image/Grafana - Created Dashborads.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image/Grafana - Dashboards.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image/Grafana Data Panel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image/Grafana Data.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image/Grafana No data.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image/Grafana Panel No data.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image/Linux A - sudo docker compose ps.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image/Linux C - mqtt consumer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image/Linux C - sudo docker compose ps.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/image/MQTT Explorer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
117 changes: 117 additions & 0 deletions report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@

# Отчет по практической работе

Развертывание системы сбора и визуализации данных на базе Docker, MQTT, InfluxDB, Telegraf и Grafana

Описание проекта:
Симуляторы сенсоров, развернутые в докер контейнерах, публикуют сообщения на Mqtt брокер. Сервис Consumer подписывается на все сообщение, опубликованные в брокере, и заносит их в базу данных временных рядов. Сервис dashboard отображает графики полученных данных от сервисов.
# Предварительные требования

Перед выполнением практической работы №2 следует проверить необходимые требования:
- Три виртуальные машины из прошлой практики "Базовые принципы администрирования Linux": Linux A, Linux B и Linux C.
- Разработку вести в VS Code (с созданным виртуальным окружением) или в другой альтернативной программе;
- Установленные docker и docker compose на каждую ВМ (https://docs.docker.com/engine/install/ubuntu/);
- Репозиторий на Github c двумя ветками: master и develop;
- Установленные Git на каждую ВМ;
- Клонировать репозиторий на каждую ВМ и VS Code (можно по SSH ключам);
- Установить MQTT Explorer с официального сайта (https://mqtt-explorer.com/)
# Linux A (Client)


!!!Перед запуском контейнера, следует отредактировать конфигурационный файл (.env), лежащий в директории vms/client/simulator. В графе "DOCKERHUB_USERNAME" следует указать свой логин в Docker HUB!!!

После этого запустите виртуальную машину и перейдите в рабочую директорию:
```
cd /ВАШ_РЕПОЗИТОРИЙ/vms/client/simulator
```
Запустите контейнеры:
```
sudo docker compose up -d
```
Посмотрите контейнеры с помощью команды:
```
sudo docker compose ps
```

![1](assets/image/Linux%20A%20-%20sudo%20docker%20compose%20ps.png)


# Linux B
_________
Запустите контейнер broker:
```
sudo docker compose up -d
sudo docker compose ps
```
![2](assets/image/Linux%20B%20-%20creatd%20broker%20container.png)

Проверим с помощью MQTT Explorer:
![3](assets/image/MQTT%20Explorer.png)
# Linux C

Запустите виртуальную машину и перейдите в рабочую директорию:
```
cd /ВАШ_РЕПОЗИТОРИЙ/vms/server
```

Запустите контейнер:

```
sudo docker compose up -d
```

Посмотрите контейнеры:
```
sudo docker compose ps
```

Если они запустились, то следует вести следующие команды, чтобы создать базу данных:

```
sudo docker exec -it influxdb influx
```

```
create database sensors
create user telegraf with password 'telegraf' with all privileges
show users

exit
```
![4](assets/image/Linux%20C%20-%20sudo%20docker%20compose%20ps.png)

Возможно, придется перезапустить контейнер telegraf следующей командой:

```
sudo docker compose restart telegraf
```

Можно просмотреть данные с помощью следующей команды:
```
sudo docker exec -it influxdb influx
use sensors
show measurements
select * from mqtt_consumer limit 5
```

![5](assets/image/Linux%20C%20-%20mqtt%20consumer.png)


# Проверка работы

1. На запущенной ВМ Linux C узнайте IP (Сетевой мост);
2. Откройте браузер (Например, Google Chrome);
3. Перейдите по следующему адресу Grafana: http://<IP_Linux_C_сетовой мост>:3000;
4. Перейдя по ссылке, Вам нужно ввести логин и пароль (admin/admin);
5. Перейдите в раздел Dashboards:

![6](assets/image/Grafana%20-%20Dashboards.png)

6. Откройте его (он загрузится автоматически):
![7](assets/image/Grafana%20-%20Created%20Dashborads.png)
7. Перейдите в дашборд "Docker Pratice":
![8](assets/image/Grafana%20No%20data.png)
8. Нужно выбрать в каждом панели mqtt_consumer и данные появятся:
![9](assets/image/Grafana%20Data%20Panel.png)
9. Готовый результат:
![10](assets/image/Grafana%20Data.png)
6 changes: 6 additions & 0 deletions vms/client/simulator/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
DOCKERHUB_USERNAME=ormask
MQTT_BROKER_HOST=192.168.31.160
MQTT_BROKER_PORT=1883
BIRTH_DAY=21
BIRTH_MONTH=5
BIRTH_YEAR=2003
19 changes: 15 additions & 4 deletions vms/client/simulator/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
FROM python:alpine3.19
# ставим легкий python - образ
FROM python:3.11-slim

# создаем рабочую папку
WORKDIR /app

# копируем файл req-s.txt в app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "main.py"]

# устанавливаем библиотеку paho-mqtt из req-s.txt
RUN pip install --no-cache-dir -r requirements.txt

# копируем код sensor.py и main.py
COPY app ./app

# при запаске контейнера запустить main.py
CMD ["python", "app/main.py"]
66 changes: 66 additions & 0 deletions vms/client/simulator/app/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import json
import os
import time
import paho.mqtt.client as mqtt
from datetime import datetime

from vms.client.simulator.sensors import SENSOR_CLASSES

#MQTT
MQTT_HOST = os.getenv("MQTT_HOST")
MQTT_PORT = int(os.getenv("MQTT_PORT"))

SENSOR_NAME = os.getenv("SENSOR_NAME")
SENSOR_TYPE = os.getenv("SENSOR_TYPE")
FORMULA_TYPE = os.getenv("FORMULA_TYPE")
TOPIC_MODE = os.getenv("TOPIC_MODE")
PUBLISH_INTERVAL = int(os.getenv("PUBLISH_INTERVAL"))

BIRTHDAY_DAY = int(os.getenv("BIRTHDAY_DAY"))
BIRTHDAY_MONTH = int(os.getenv("BIRTHDAY_MONTH"))
BIRTHDAY_YEAR = int(os.getenv("BIRTHDAY_YEAR"))

sensor_class = SENSOR_CLASSES.get(SENSOR_TYPE)

# Проверяем, что класс сенсора существует
if sensor_class is None:
raise ValueError(f"Такого сенсора не существует: {SENSOR_TYPE}")

sensor = sensor_class(name = SENSOR_NAME,
sensor_type=SENSOR_TYPE,
formula_type=FORMULA_TYPE,
birthday_day=BIRTHDAY_DAY,
birthday_month=BIRTHDAY_MONTH,
birth_year=BIRTHDAY_YEAR)

client = mqtt.Client(client_id=SENSOR_NAME)
client.connect(MQTT_HOST, MQTT_PORT, 60)

print(f"Подключен к брокеру MQTT по {MQTT_HOST}, {MQTT_PORT}")

# Бесконечный цикл отправки
while True:

#Генерируем новое число
value = sensor.generate_value()

if TOPIC_MODE == "json":
topic = f"sensors/{sensor.sensor_type}"

payload = {
"name": sensor.name,
"sensor_type": sensor.sensor_type,
"value": value,
"unit": sensor.unit_of_measurement,
}
client.publish(topic, json.dumps(payload))

elif TOPIC_MODE == "value":
topic = f"sensors/{sensor.sensor_type}/{sensor.name}/value"
client.publish(topic, value)

else:
raise ValueError(f"Неправильный режим: {TOPIC_MODE}")

print(f"{value} в {topic}")
time.sleep(PUBLISH_INTERVAL)
Loading