Pro aplikaci jsem zvolil velmi jednoduchý Twitter like mikroblogovací systém, který jsem pojemoval Bleeper. Backendová část poskytuje REST API pro získání příspěvků a vytvoření nového příspěvku. Frontendová část zobrazuje uživatelům posledních 10 příspěvků a umožňuje přidání nového příspěvku.
Pro realizaci obou částí jsem zvolil Python, ale namísto Flasku jsem použil framework FastAPI, který je modernější a mám s ním větší zkušenosti. Backend pro práci s databází využívá SQLAlchemy (stejně jako Flask). Frontend využívá šablonovací engine Jinja2, čímž jsou stránky statické. Pro komunikaci frontendu s backendem jsem použil knihovnu httpx, která narozdíl od requests podporuje asynchronní volání.
Jakožto databázi jsem použil MariaDB. Setup tabulek je prováděn automaticky pomocí SQLAlchemy, není tedy potřeba žádný samostatný SQL skript.
Pro spuštění samostatné aplikace je potřeba mít nainstalovaný Python s balíčky z requirements.txt. Následně lze obě části spustit ve složce ./app/{část_aplikace} pomocí:
fastapi run
Docker compose script obsahuje 3 služby - frontend, backend a MariaDB databázi. Všechny 3 služby mají nastaveny příslušné env proměnné. Frontend a backend se navíc buildí přímo z lokálních Dockerfile. Služby jsou propojeny pomocí 2 sítí - backend_network (pro komunikaci backendu a databáze) a frontend_network (pro komunikaci frontendu a backendu). Tímto způsobem je zajištěno, že databáze není přímo přístupná z frontendu. Služby mají také správnou návaznost, kde frontend závisí na backendu a backend na databázi. Databáze má perzistentní volume pro uchování dat.
Dle zadání je backend 5x replikován. Celá aplikace je dostupná pouze přes frontend na portu 8080.
Pro spuštění aplikace pomocí Docker compose je potřeba mít nainstalovaný Docker a Docker compose. Následně lze aplikaci spustit ve složce ./docker pomocí:
docker compose up
Před samotným provisioningem je potřeba mít vytvořený SSH klíč bez passphrase. Buďto lze přepsat placeholder soubory v ./provision-vm/ssh vlastním klíčem nebo upravit konfiguraci Terraformu na vlastní klíč v ./provision-vm/terraform/terraform.tfvars.
Pro přístup k OpenNebula API je potřeba mít vytvořený uživatelský účet s API tokenem. Tyto údaje je potřeba vložit do ./provision-vm/terraform/terraform.tfvars místo placeholder hodnot.
Pro provisioning VM byl použit Terraform s OpenNebula providerem. Konfigurace vytváří jednu VM s přidělenou statickou IP adresou, 2 CPU, 2GB RAM a 10GB diskem. Také je součástí konfigurace vytvářen inventory soubor pro Ansible, který obsahuje IP adresy vytvořených VM a cestu k nakonfigurovanému SSH klíči.
Pro spuštění provisioningu je potřeba mít nainstalovaný Terraform a správné hodnoty v terraform.tfvars. Následně lze provisioning spustit ve složce ./provision-vm/terraform pomocí:
terraform init
terraform plan
terraform apply
A případně zničit pomocí:
terraform destroy
Pro konfiguraci VM byl použit Ansible. Playbook obsahuje 3 role - common, docker a app. Role common instaluje základní nástroje (mc, curl, jq, rsync). Role docker instaluje Docker a Docker compose. Role app kopíruje Docker konfiguraci aplikace na VM a spouští aplikaci pomocí Docker compose.
Pro spuštění Ansible playbooku je potřeba mít nainstalovaný Ansible.
Následně lze playbook spustit ve složce ./provision-vm/ansible pomocí:
ansible-playbook -i inventory.yaml site.yml
Pro nasazení pomocí Kubernetes jsem vytvořil 3 deploymenty - frontend, backend a mariadb. Ke každému deploymentu se vytváří i příslušná služba, která je definována ve stejném YAML souboru. Frontend je replikován 3x, backend 5x a databáze je pouze jedna. Ingress je definován ve vlastním souboru. Definice využívají veřejně dostupný image aplikace nahraný do mého Docker Hubu.
Pro nasazení aplikace do Kubernetes clusteru je potřeba mít nainstalovaný kubectl a přístup k funkčnímu clusteru. Na linuxu by mělo vše fungovat s Minikube, na Windows jsem ale s problémy se sdílením sítě musel přejít na Docker Desktop built-in Kubernetes cluster, aby byl reachable ingress.
Také je nutné zajistit, aby byl nainstalován NGINX Ingress Controller:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
Aplikaci lze poté nasadit pomocí:
kubectl apply -f db.yaml
kubectl apply -f backend.yaml
kubectl apply -f frontend.yaml
kubectl apply -f ingress.yaml
Ve složce ./kubernetes.
Poté je aplikace dostupná na adrese http://localhost.