У цій статті ми покажемо, як створити найпростіший мікросервіс на Python Framework FastAPI і запустити його в docker контейнері. Спочатку розглянемо, як завантажити і запустити готовий контейнер і базові команди з управління контейнером в docker, а потім перейдемо до створення свого образу з мікросервісом.
Нагадаємо, що Докер – це програмне забезпечення, що дозволяє упакувати додаток і все його залежності в єдиний модуль. Важлива перевага – процес розгортання програми, зібраного в контейнер, добре інтегрується в CI / CD pipline.
Якщо коротко, плюси використання Docker:
- Це дозволяє нам переносити додаток на інші операційні системи з підтримкою cgroups;
- Більш ефективно дозволяє навантажити host машину. Чи не створюється віртуальне залізо, як при використанні віртуальних машин;
- Відмінно інтегрується в CI / CD pipline;
- Додається ще один рівень абстракції, що дозволяє використовувати на одному хості різні версії мов, бібліотек, etc.
Основні команди управління docker engine
У статті ми опустимо процес установки docker в Linux (припускаємо, що ви вже зробили це). Давайте для початку переконаємося, що у вас встановлена і працює служба docker. Виконайте в терміналі команду
sudo systemctl status docker
Висновок повинен бути приблизно такий:
● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; disabled; vendor preset: enabled) Active: active (running) since Tue 2021-02-16 16:14:48 +05; 4h 58min ago Docs: https://docs.docker.com Main PID: 20976 (dockerd) Tasks: 57 CGroup: /system.slice/docker.service ├─20976 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock ├─27968 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5432 -container-ip 172.17.0.2 -container-port 5432 └─28315 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 18000 -container-ip 172.17.0.3 -container-port 18000
Якщо сервіс Docker не запущено, висновок команди буде приблизно такою:
● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; disabled; vendor preset: enabled) Active: inactive (dead) since Tue 2021-02-16 21:17:32 +05; 1s ago Docs: https://docs.docker.com Process: 20976 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock (code=exited, status=0/SUCCESS) Main PID: 20976 (code=exited, status=0/SUCCESS)
Спробуйте запустити службу наступною командою
sudo systemctl start docker
Якщо все пройшло без помилок, можна переходити до наступного кроку.
Якщо вивелося таке повідомлення:
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.
значить служба не запустилася і потрібно дивитися журнал і розбиратися з проблемою. Наступна команда виведе вміст журналу сервісу dockerd:
sudo journalctl -xe /usr/bin/dockerd
Запуск першого контейнера в Docker
Отже, у вас запущено Docker і ви можете запустити перший контейнер. Виконайте в консолі команду:
sudo docker pull busybox
Даною командою, ми завантажили готовий образ busybox з сервера Docker Hub. Docker hub – це публічно репозиторій docker образів. Він надає можливість зберігати свої image, обмінюватися ними з іншими людьми. В даному репозиторії зібрані безліч готових образів з популярним ПО. Зайнятий – це зібране в одному виконуваному файлі набір утиліт unix.
sudo docker run -it --rm busybox sh
Даною командою ми запустили контейнер, за допомогою опції -це ми підключили інтерактивний tty в контейнер і запустили командну оболонку ш. ключ —Rm дозволяє автоматично видалити контейнер при виході з інтерактивного режиму.
Всередині контейнера busybox доступні основні команди unix / linux.
Припустимо можна подивитися список директорій:
Для виходу з контейнера виконайте команду:
exit
Наступна команда дозволяє переглянути список доступних локально образів:
sudo docker images
В кінці списку недавно викачаний busybox.
Подивитися список запущених контейнерів можна командою:
sudo docker ps -a
Також можна передати фільтр:
sudo docker ps --filter status="exited"
Дана команда, виведе всі контейнери зі статусом exited. Це контейнери, які зупинені, але не видалені.
Це короткий набір команд, які використовуються для запуску контейнера, підключення інтерактивного tty в контейнер і входу всередину контейнера.
Запуск nginx контейнера з образу docker hub
Наступного кроком, ми зберемо свій image на основі готового образу. Для цього створимо папку в директорії поточного користувача.
mkdir nginx
cd nginx
У цій папці створимо файл index.html і Dockerfile такого змісту
index.html
<html> <title>Docker test</title> <body>I am working in Docker</body> </html>
Докерфайл
FROM nginx COPY index.html /usr/share/nginx/html
У файлі Докерфайл за допомогою директиви FROM ми вказали що потрібно використовувати використовувати image nginx. Команда COPY дозволяє скопіювати з поточної директорії файл index.html в папку / usr / share / nginx / html в образі.
Виконайте в директорії nginx команду:
sudo docker build . --tag mynginx
Дана команда завантажить з docker hub офіційний образ nginx останньої доступної версії. Новий локальний образ буде позначений тегом mynginx: latest
Тепер можна запустити контейнер, використовуючи зібраний image:
sudo docker run -p 8080:80 -d --name nginx_test mynginx
Даною командою ми запустили контейнер. опція -с потрібна щоб прокинути порт 80 контейнера на порт host машини 8080. Варіант -d дозволяє запустити контейнер у фоновому режимі без прив’язки до поточної консолі, опція —Назви задає ім’я контейнера.
Щоб перевірити роботу nginx в образі, відкрийте браузер і перейдіть за адресою http://localhost:8080/
. Перед вами повинна відкритися html сторінка, яку ми скопіювали в контейнер.
Щоб зупинити контейнер, виконайте:
sudo docker stop nginx_test
Щоб видалити контейнер:
sudo docker rm nginx_test
Створюємо простий мікросервіс на python framework FastAPI
Створимо структуру проекту:
~# mkdir fpdc
~# cd fpdc
Створимо в директорії fpdc два файли requirements.txt і main.py. Файл main.py буде точкою входу для запуску програми, файл requirements.txt – це залежності.
Додамо в файл requirements.txt наступні залежності:
fastapi==0.63.* uvicorn==0.13.*
Світоріг – це легкий asgi сервер. За допомогою нього можна запускати веб сервіси, написані з використання fastapi, django, flask та інших.
вміст файлу main.py
from fastapi import FastAPI app = FastAPI(title="Test microsevice") @app.get("/api/v1/hello") def hello(name: str = ""): return {"msg": f"Hello {name}"}
Даною рядком ми створюємо asgi додаток:app = FastAPI(title="Test microsevice")
Після ми створюємо функцію обробник маршруту (router):@app.get("/api/v1/hello")
def hello(name: str = ""):
return {"msg": f"Hello {name}"}
Рядок над функцією – це декортатор, він додає маршрут в наш додаток.
Тепер створимо Dockerfile зі наступному вмістом:
FROM python:3.7.7-slim
RUN mkdir /app
COPY ./main.py /app
WORKDIR /app/
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["uvicorn", "--host", "0.0.0.0", "main:app"]
Dockerfile – схожий на makefile, в ньому так само вказані команди, але тільки для зборки контейнера. Давайте розберемо команди докладніше.
FROM
– дана інструкція задає базовий образ (image) для збирання.
RUN
– виконує довільні shell команди. В даному випадку, створює директорію / app
COPY
– копіює файли з хост машини в докер контейнер.
EXPOSE
– вказує, що контейнер слухає порт 8000 при запуску.
CMD
– вказує, яку команду виконати при запуску контейнера.
В даному прикладі, ми запускаємо сервер uvicorn, вказавши, що він буде прослуховувати всі інтерфейси і що потрібно запустити наш додаток.
Мінімальний сервіс створений, можна зібрати контейнер.
sudo docker build . --tag microsevice_v1
І запустити вийшов сервіс:
sudo docker run -p 8000:8000 -d --name micro_v1 microsevice_v1
Роботу сервісу можна перевірити з консолі:
curl -X GET "http://127.0.0.1:8000/api/v1/hello" -H "accept: application/json"
curl -X GET "http://127.0.0.1:8000/api/v1/hello?name=World%20" -H "accept: application/json"
Або можна зайти в браузер і виконати дані запити. Великим плюсом фреймворка FastAPI є те, що він автоматично генерує документацію до API, яка доступна за адресою:
http://localhost:8000/docs/
Мінімальний працює мікросервіс створений і запущений в docker контейнері. Наступного статтях функціонал буде розширено, створимо композицію сервісів, підключимо базу даних, додамо frontend. Надалі ми плануємо запустити даний сервіс в середовищі kubernetes.