DAS_2023_1/arutunyan_dmitry_lab_2/README.md

132 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## Лабораторная работа 2. Вариант 4.
### Задание
- Разработать два приложения такие, что результат первого является исходными данными для второго.
- Изучить файлы сборки образов `docker` и разработать их для созданных приложений.
- Собрать файл `docker-compose.yaml` для запуска приложений. Разобраться с монтированием каталогов из хост-системы.
Вариант задания:
- `worker-1` - Берёт из каталога `/var/data` случайный файл и перекладывает его в `/var/result/data.txt`.
- `worker-2` - Сохраняет произведение первого и последнего числа из файла `/var/data/data.txt` в `/var/result/result.txt`.
### Как запустить
В директории с файлом характеристик `docker-compose.yaml` выполнить команду:
```
docker-compose -f docker-compose.yaml up
```
Это запустит `docker-compose`, который развернёт в общем контейнере 2 контейнера с сервисами по собранным из `Dockerfile` образам.
### Описание работы
#### Подготовка файлов
В корневой папке лабораторной работы создадим две директории: `data` и `result`. Директория `data` будет являться удалённой директорией с входными файлами для 1го приложения.
Входные файлы и их содержание:
```
rand0.txt - 42, 17, 99, 23, 76
rand1.txt - 55, 12, 88, 37, 61
rand2.txt - 29, 83, 44, 68, 91
rand3.txt - 10, 57, 72, 33, 94
```
Директория `result` будет служить далённой директорией с входными файлами для 2го приложения и удалённой директорией для выходного файла 1го приложения, поэтому оставляем её пустой.
#### Разработка приложения Worker-1
Согласно заданию, `worker-1` берёт из каталога `/var/data` случайный файл и перекладывает его в `/var/result/data.txt`.
Приложение реализовано на языке Java.
Код логической части приложения:
```java
Files.move(files[rm.nextInt(files.length)].toPath(),
new File(result_directory).toPath(), StandardCopyOption.REPLACE_EXISTING);
```
Для сборки образа и запуска приложения в контейнере создадим `Dockerfile`:
```dockerfile
FROM openjdk:21-jdk
RUN ["mkdir", "/var/data"]
RUN ["mkdir", "/var/result"]
COPY src/Main.java /opt/app/Main.java
WORKDIR /opt/app
RUN ["javac", "Main.java"]
CMD ["java", "Main"]
```
В данном файле с помощью функции `RUN` мы передаём в `bash` среду созданного контейнера комманды создания входных и выходных директорий `mkdir /var/data` и `mkdir /var/result`. После этого мы задаём в контейнере рабочую директорию, копируем исполняемый класс приложения в рабочую директорию и компилируем его. При запуске контейнера с помощью функции `CMD` указыыаем действие `java Main` запуска приложения.
#### Разработка приложения Worker-2
Согласно заданию, `worker-2` сохраняет произведение первого и последнего числа из файла `/var/data/data.txt` в `/var/result/result.txt`.
Приложение реализовано на языке Java.
Код логической части приложения:
```java
Scanner scanner = new Scanner(data_file);
int[] num = Arrays.stream(scanner.nextLine().split(", "))
.mapToInt(Integer::parseInt)
.toArray();
scanner.close();
FileWriter writer = new FileWriter(result_file);
writer.write(num[0] * num[num.length - 1] + "");
writer.close();
System.out.println("" + (num[0] * num[num.length - 1]));
```
Для сборки образа и запуска приложения в контейнере создадим `Dockerfile`:
```dockerfile
FROM openjdk:21-jdk
RUN ["mkdir", "/var/data"]
RUN ["mkdir", "/var/result"]
COPY src/Main.java /opt/app/Main.java
WORKDIR /opt/app
RUN ["javac", "Main.java"]
CMD ["java", "Main"]
```
Логика сборки образа приложения `worker-2` идентична логике приложения `worker-1`.
#### Разворачивание приложений
Конфигурации `worker-1` в `docker-compose.yaml`:
```yaml
worker-1:
build:
context: /worker-1
dockerfile: Dockerfile
volumes:
- .\data:/var/data
- .\result:/var/result
```
Где `build` указывает на метод сборки образа в котором: `context` указывает на корневую директорию приложения, а `dockerfile` указывает на путь к `Dockerfile`,`volumes` устанавливает локальную папку `data` как папку входных файлов `/var/data`, а локальную папку `result` - как папку выходных файлов `/var/result`.
Конфигурации `worker-2` в `docker-compose.yaml`:
```yaml
worker-2:
depends_on:
- worker-1
build:
context: /worker-2
dockerfile: Dockerfile
volumes:
- .\result:/var/data
- .\result:/var/result
```
Где `depends_on` указывает на зависимость от 1го приложения и возможность запуска только после него, `build` указывает на метод сборки образа в котором: `context` указывает на корневую директорию приложения, а `dockerfile` указывает на путь к `Dockerfile`,`volumes` устанавливает локальную папку `result` как папку входных файлов `/var/data` и как папку выходных файлов `/var/result` одновременно.
#### Запуск приложений
Выполнение команды docker-compose и log-журнал контейнеров:
![](pic1.png "")
![](pic2.png "")
Файлы директоиии `data` и их содержание:
```
rand0.txt - 42, 17, 99, 23, 76
rand2.txt - 29, 83, 44, 68, 91
rand3.txt - 10, 57, 72, 33, 94
```
Файлы директоиии `result` и их содержание:
```
data.txt - 55, 12, 88, 37, 61
result.txt - 3355
```
### Видео
https://youtu.be/WASbBhDiAwg