diff --git a/.gitignore b/.gitignore index b6e4761..f68d109 100644 --- a/.gitignore +++ b/.gitignore @@ -1,129 +1,29 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -pip-wheel-metadata/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -.python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/LinuxPractice2.iml b/.idea/LinuxPractice2.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/LinuxPractice2.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/git_toolbox_blame.xml b/.idea/git_toolbox_blame.xml new file mode 100644 index 0000000..7dc1249 --- /dev/null +++ b/.idea/git_toolbox_blame.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..07115cd --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5a6372d --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/PlayWithDocker.iml b/PlayWithDocker.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/PlayWithDocker.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..c747736 --- /dev/null +++ b/app.py @@ -0,0 +1,39 @@ +from flask import Flask, request, jsonify + +app = Flask(__name__) + +# Список для хранения задач в памяти +tasks = [] +next_id = 1 + + +@app.route("/tasks", methods=['POST']) +def create_task(): + global next_id + data = request.get_json() + description = data['description'] + task = {'id': next_id, 'description': description} + tasks.append(task) + next_id += 1 + return jsonify(task), 201 + + +@app.route("/tasks", methods=['GET']) +def get_all_tasks(): + return jsonify(tasks) + + +@app.route("/tasks/", methods=['PUT']) +def update_task(id): + data = request.get_json() + description = data['description'] + + for task in tasks: + if task['id'] == id: + task['description'] = description + return jsonify(task) + + return jsonify({'error': 'Task is not found'}), 404 + + +app.run(host='0.0.0.0', port=5000) diff --git a/config/A.sh b/config/A.sh new file mode 100644 index 0000000..5223edd --- /dev/null +++ b/config/A.sh @@ -0,0 +1,55 @@ +#!/bin/bash +echo "Configuring adapter for VM A" +ip link add macvlan1 link eth0 type macvlan mode bridge +ip address add dev macvlan1 192.168.29.10/24 +ip link set macvlan1 up +echo "Configuration ended" +echo "Routing VM A to VM C" +ip route add 192.168.10.0/24 via 192.168.29.1 + +echo "Installation of FLASK" +pip install flask + +echo "Creating web-server" +touch app.py + +cat << EOF > app.py +from flask import Flask, request, jsonify + +app = Flask(__name__) + +# Список для хранения задач в памяти +tasks = [] +next_id = 1 + +@app.route("/tasks", methods=['POST']) +def create_task(): + global next_id + data = request.get_json() + description = data['description'] + task = {'id': next_id, 'description': description} + tasks.append(task) + next_id += 1 + return jsonify(task), 201 + +@app.route("/tasks", methods=['GET']) +def get_all_tasks(): + return jsonify(tasks) + +@app.route("/tasks/", methods=['PUT']) +def update_task(id): + data = request.get_json() + description = data['description'] + + for task in tasks: + if task['id'] == id: + task['description'] = description + return jsonify(task) + + return jsonify({'error': 'Task is not found'}), 404 + +app.run(host='0.0.0.0', port=5000) +EOF + +echo "Run server" +python app.py diff --git a/config/B.sh b/config/B.sh new file mode 100644 index 0000000..6ea19da --- /dev/null +++ b/config/B.sh @@ -0,0 +1,12 @@ +#!/bin/bash +echo "Configuring adapter for subnet A" +ip link add macvlan1 link eth0 type macvlan mode bridge +ip address add dev macvlan1 192.168.29.1/24 +ip link set macvlan1 up +echo "Configuration ended" + +echo "Configuring adapter for subnet C" +ip link add macvlan2 link eth0 type macvlan mode bridge +ip address add dev macvlan2 192.168.10.1/24 +ip link set macvlan2 up +echo "Configuration ended" diff --git a/config/C.sh b/config/C.sh new file mode 100644 index 0000000..851dcda --- /dev/null +++ b/config/C.sh @@ -0,0 +1,17 @@ +#!/bin/bash +echo "Configuring adapter for VM C" +ip link add macvlan1 link eth0 type macvlan mode bridge +ip address add dev macvlan1 192.168.10.100/24 +ip link set macvlan1 up +echo "Configuration ended" +echo "Routing VM C to VM A" +ip route add 192.168.29.0/24 via 192.168.10.1 + +echo "GET-request" +curl "http://192.168.29.10:5000/tasks" + +echo "POST-request" +curl -X POST "http://192.168.29.10:5000/tasks -H 'Content-Type: application/json' -d '{'description': 'My first task'}'" + +echo "PUT-request" +curl -X PUT "http://192.168.29.10:5000/tasks/1 -H 'Content-Type: application/json' -d '{'description': 'Updated task description'}'" \ No newline at end of file diff --git a/images/1.png b/images/1.png new file mode 100644 index 0000000..014debb Binary files /dev/null and b/images/1.png differ diff --git a/images/10.png b/images/10.png new file mode 100644 index 0000000..598c7b1 Binary files /dev/null and b/images/10.png differ diff --git a/images/11.png b/images/11.png new file mode 100644 index 0000000..d871e06 Binary files /dev/null and b/images/11.png differ diff --git a/images/2.png b/images/2.png new file mode 100644 index 0000000..e4bcdd1 Binary files /dev/null and b/images/2.png differ diff --git a/images/3.png b/images/3.png new file mode 100644 index 0000000..f60efc1 Binary files /dev/null and b/images/3.png differ diff --git a/images/4.png b/images/4.png new file mode 100644 index 0000000..a39d2f7 Binary files /dev/null and b/images/4.png differ diff --git a/images/5.png b/images/5.png new file mode 100644 index 0000000..ee919c7 Binary files /dev/null and b/images/5.png differ diff --git a/images/6.png b/images/6.png new file mode 100644 index 0000000..3695081 Binary files /dev/null and b/images/6.png differ diff --git a/images/7.png b/images/7.png new file mode 100644 index 0000000..29dfa16 Binary files /dev/null and b/images/7.png differ diff --git a/images/8.png b/images/8.png new file mode 100644 index 0000000..5af3d31 Binary files /dev/null and b/images/8.png differ diff --git a/images/9.png b/images/9.png new file mode 100644 index 0000000..840fefc Binary files /dev/null and b/images/9.png differ diff --git a/report.md b/report.md new file mode 100644 index 0000000..2fff6ce --- /dev/null +++ b/report.md @@ -0,0 +1,206 @@ +## Отчет по работе с Линуксом + +### _1. Создание контейнеров в Play-with-docker_ + +Работа производилась в Play-with-docker (https://labs.play-with-docker.com/). Сначала создаются три контейнера нажатием кнопки `ADD NEW INSTANCE`. + +

+ +Рисунок 1 - Контейнеры в Play-With-Docker +

+ +Далее подключимся к нодам через терминал с помощью ssh соединения: + +

+ +Рисунок 2 - Подключение к нодам через терминал в Ubuntu +

+ +Настроим сеть при помощи `ipvlan`. Добавим по одному адаптеру на каждый из контейнеров А и С: + +* ВМ A - IP 192.168.29.10 с маской 255.255.255.0 +* ВМ C - 192.168.10.100 с маской 255.255.255.0 + +

+ +Рисунок 3 - Адаптер контейнера A +

+ +

+ +Рисунок 4 - Адаптер контейнера С +

+ + +Также контейнеру B добавим 2 адаптера: + +* 192.168.29.1 с маской 255.255.255.0 +* 192.168.10.1 с маской 255.255.255.0 + +

+ +Рисунок 5 - Адаптеры контейнера B +

+ +### _2. Маршрутизация_ + +Настройка маршрутов. Укажем на контейнере A отсылать пакеты на контейнер C через адаптер `macvlan1` на контейнере B. + +* Контейнер A: `ip route add 192.168.10.0/24 via 192.168.29.1` + +

+ +

+
Рисунок 6 - Пинг с контейнера A на C
+ +Для контейнера С укажем отсылать пакеты на контейнер А через адаптер `macvlan2` на контейнере B. + +* Контейнер C: `ip route add 192.168.29.0/24 via 192.168.10.1` + +

+ +

+
Рисунок 7 - Пинг с контейнера С на А
+ +### _3. Создание и запуск сервера_ + +На контейнере A развернем сервер на Flask. Установим `Flask` через `pip`: +``` +pip install Flask +``` + +Напишем сервер на Python (рисунок 8): + +

+ +

+
Рисунок 8 - Код сервера
+ +Теперь запустим его (рисунок 9) + +

+ +

+
Рисунок 9 - Запуск Flask сервера
+ +Теперь проверим работу GET, POST, PUT запросов. +С контейнера C выполним запросы через `curl` (рисунок 10): +``` +curl 192.168.20.10:5000 +``` + +

+ +Рисунок 10 - Проверка работы GET, POST, PUT запросов +

+ +Посмотрим также логи запросов на сервере (рисунок 11). + +

+ +Рисунок 11 - Логи запросов на сервере +

+ +### _4. Скрипты_ + +Для автоматического выполнения предыдущих этапов напишем скрипты конфигурации для каждого из контейнеров: + +Скрипт для контейнера A + +```sh +#!/bin/bash +echo "Configuring adapter for VM A" +ip link add macvlan1 link eth0 type macvlan mode bridge +ip address add dev macvlan1 192.168.29.10/24 +ip link set macvlan1 up +echo "Configuration ended" +echo "Routing VM A to VM C" +ip route add 192.168.10.0/24 via 192.168.29.1 + +echo "Installation of FLASK" +pip install flask + +echo "Creating web-server" +touch app.py + +cat << EOF > app.py +from flask import Flask, request, jsonify + +app = Flask(__name__) + +# Список для хранения задач в памяти +tasks = [] +next_id = 1 + +@app.route("/tasks", methods=['POST']) +def create_task(): + global next_id + data = request.get_json() + description = data['description'] + task = {'id': next_id, 'description': description} + tasks.append(task) + next_id += 1 + return jsonify(task), 201 + +@app.route("/tasks", methods=['GET']) +def get_all_tasks(): + return jsonify(tasks) + +@app.route("/tasks/", methods=['PUT']) +def update_task(id): + data = request.get_json() + description = data['description'] + + for task in tasks: + if task['id'] == id: + task['description'] = description + return jsonify(task) + + return jsonify({'error': 'Task is not found'}), 404 + +app.run(host='0.0.0.0', port=5000) +EOF + +echo "Run server" +python app.py +``` + +Скрипт для контейнера B + +```sh +#!/bin/bash +echo "Configuring adapter for subnet A" +ip link add macvlan1 link eth0 type macvlan mode bridge +ip address add dev macvlan1 192.168.29.1/24 +ip link set macvlan1 up +echo "Configuration ended" + +echo "Configuring adapter for subnet C" +ip link add macvlan2 link eth0 type macvlan mode bridge +ip address add dev macvlan2 192.168.10.1/24 +ip link set macvlan2 up +echo "Configuration ended" + +``` + +Скрипт для контейнера C + +```sh +#!/bin/bash +echo "Configuring adapter for VM C" +ip link add macvlan1 link eth0 type macvlan mode bridge +ip address add dev macvlan1 192.168.10.100/24 +ip link set macvlan1 up +echo "Configuration ended" +echo "Routing VM C to VM A" +ip route add 192.168.29.0/24 via 192.168.10.1 + +echo "GET-request" +curl "http://192.168.29.10:5000/tasks" + +echo "POST-request" +curl -X POST "http://192.168.29.10:5000/tasks -H 'Content-Type: application/json' -d '{'description': 'My first task'}'" + +echo "PUT-request" +curl -X PUT "http://192.168.29.10:5000/tasks/1 -H 'Content-Type: application/json' -d '{'description': 'Updated task description'}'" +```