Skip to content
Snippets Groups Projects
README.md 5.62 KiB
Newer Older
Philipp Reinhard's avatar
Philipp Reinhard committed
# Dokumentation

## Aufbau

Der Microservice ist mit der Library `Flask` programmiert worden. Der Source Code für den Service liegt in der Datei `app.py`. Die `docker-compose.yaml` wird zum lokalen Testen des Zusammenspiels zwischen dem gestellten MDB-Service und dem erstellen Service benötigt. Diese Datei wird für das Deployment in Kubernetes nicht benötigt. Die `Dockerfile` erstellt aus dem Python Code ein deploybares Image zum deployen in Kubernetes oder direkt in Docker. Lokal zum testen liegt außerdem eine `.env` Datei vor, die für das lokale testen mit Python die Umgebungsvariablen bereitstellt und eine virtuelle Python Umgebung. Die `requirements.txt` beinhaltet die benötigten Python Bibliotheken, die während dem Image-Bau Prozess installiert werden müssen.

Philipp Reinhard's avatar
Philipp Reinhard committed
### Ablauf
Philipp Reinhard's avatar
Philipp Reinhard committed

Beim Starten der Flask App wird darauf geschaut, ob die Umgebungsvariable `PYTHON_ENV` gesetzt ist. Wenn die Variable leer oder auf `development` gesetzt ist, wird der Flask interne Webserver benutzt. Dieser ist nur für das Testen einer Flask App gedacht (`PYTHON_ENV` wird in der Dockerfile zu `production` gesetzt). Aus dem Grund wurde die Bibliothek `waitress` verwendet, wenn die Variable auf `production` gesetzt wird um einen stabilen production-ready Webserver zu erstellen. Dabei kann durch die Umgebungsvariable `PORT` der Port gesetzt werden. Standardmäßig ist dieser auf `8080` gesetzt.

### Healthcheck

Der Healthcheck ist ein einfacher GET-Request, auf der die API mit dem HTTP Status `200` antwortet, wenn die API diesen Request erhält.

### getByName

Der gesamte Inhalt der `getByName` Funktion ist von einem `try/except` umgeben, um generelle Fehler abzufangen und dem Sender eine vernünftige Fehlernachricht zu senden (Status Code 500). Es wird der Parameter `name` aus der Anfrage entnommen und einen API Request an den MDB-Service gestellt mit dem APIKEY aus den Umgebungsvariablen, sowie dem Namen aus der initialen Request. Sollte der MDB-Service einen 401 Status zurückgeben, wird dieser Status Code weiter an den initialen Sender "durchgereicht". Auch bei einem Timeout (ab 2 Sekunden Wartezeit) wird ein Fehlernachricht an den initialen Sender gegeben. Sollen die Anfrage erfolgreich gewesen sein, wird überprüft, ob die Zahl von Records größer als 0 ist. Wenn nicht, wird ein Status Code 204 `No Content` an den initialen Sender gegeben. Sollte die Antwort vom MDB-Service Records beinhalten, werden die `id` und der `titel` extrahiert und an den initialen Sender gesendet.
Philipp Reinhard's avatar
Philipp Reinhard committed

## Testing

### CURL

Durch den folgenden Curl-Befehl kann die API getestet werden:

```
curl http://localhost:<port>/api/v1/getByName?name=Scholz
```

Philipp Reinhard's avatar
Philipp Reinhard committed
### Lokal

Um den Service lokal zu testen muss eine virtuelle Umgebung erstellt werden: `python -m venv venv`. In dieser Umgebung müssen die Bibliotheken installiert werden mit: `pip install -r requirements.txt`. Eine lokale Umgebungsdatei (z.b. `.env`) muss mit folgendem Inhalt erstellt werden:
Philipp Reinhard's avatar
Philipp Reinhard committed
```
PORT=8080 # Port, auf dem die Anwendung läuft
APIKEY=<key> # API-Token für den MDB-Service
SERVICE_URL=http://localhost:8001/api/v1 # URL vom MDB-Service
```

Danach kann man mit `python app.py` die Flask App starten.
Philipp Reinhard's avatar
Philipp Reinhard committed

### Docker

Um den Service mit Docker zu betreiben, muss zunächst ein Docker Image erstellt werden mit folgendem Befehl: `docker build . -t abgabe:2`. Als nächsten Schritt kann entweder die `docker-compose.yaml` Datei benutzt werden mit folgendem Befehl: `docker compose up` oder der Service muss mit folgendem Befehl gestartet werden:
Philipp Reinhard's avatar
Philipp Reinhard committed

```
Philipp Reinhard's avatar
Philipp Reinhard committed
docker run -d --name abgabe \
  -p 8080:8080 \
  -e APIKEY=<key> \
  -e SERVICE_URL=http://mdb-data:8001/api/v1 \
Philipp Reinhard's avatar
Philipp Reinhard committed
  --network dhbw \
Philipp Reinhard's avatar
Philipp Reinhard committed
```

### Kubernetes

Um den Service mit Minikube betreiben zu können muss zunächst aus dem `k8s` Ordner alle Dateien mit dem Befehl `kubectl create -f <file>` ausgeführt werden. Dabei muss `configmap.yaml` vor `deployment.yaml` ausgeführt werden. Dadurch wird der MDB-Service in Minikube gestartet. Durch den Service sind die Pods innerhalb des Kubernetes Netzwerks über die URL `mdb-service` erreichbar. Damit Minikube das lokal gebaute Image finden kann, muss der Befehl `minikube image load abgabe:2` ausgeführt werden. Dabei wird das Image in Minikube geladen. Nun müssen die gleichen Befehle wie beim MDB-Service für den `abgabe` Ordner ausgeführt werden. In der ConfigMap werden alle nötigen Umgebungsvariablen gesetzt, die der Service braucht um zu funktionieren (`SERVICE_URL`). Mit den Secrets wird das Secret `APIKEY` gesetzt. Damit man nun auf den Service von außerhalb zugreifen kann muss der Befehl `minikube service abgabe --url` benutzt werden. Dieser öffnet einen Port von Minikube, auf dem man dann auf die REST API zugreifen kann.
Philipp Reinhard's avatar
Philipp Reinhard committed

#### Beschreibung der Konfigurationen in abgabe.yaml
Philipp Reinhard's avatar
Philipp Reinhard committed

Es wird eine ConfigMap erstellt, unter dem Namen `abgabe-config`. In dieser ConfigMap wird das Attribut `SERVICE_URL` gesetzt.
Philipp Reinhard's avatar
Philipp Reinhard committed

Es wird ein Secret erstellt, unter dem Namen `abgabe-secret`. In diesen Secrets wird das Attribute `APIKEY` gesetzt.
Es wird ein Deployment erstellt mit dem Image `abgabe:1` und mit dem Namen `abgabe`. Die Replicas werden auf 1 gesetzt, damit nur 1 Pod erstellt wird. Es wird außerdem der Port `8080` freigegeben und es werden die Umgebungsvariablen aus der ConfigMap gesetzt. Am Ende wird noch eine readinessProbe erstellt. Dabei überprüft Kubernetes, ob der Pod schon bereit ist, indem ein REST Call an /health gesendet wird. Und wenn der Service antwortet, ist der Pod erfolgreich gestartet.
Philipp Reinhard's avatar
Philipp Reinhard committed

Es wird ein Service erstellt mit dem Typ NodePort. Durch ein NodePort wird im Kubernetes Cluster ein Port freigegebenen und es werden alle Anfragen auf das Deployment mit dem Namen `abgabe` weitergeleitet.