Od VM do PaaS

Usługi chmurowe, laboratorium 3


Agenda

  1. Stan startowy i Resource Group projektu
  2. App Service Plan i Web App
  3. App Settings
  4. Paczka ZIP i wdrożenie
  5. Test przez HTTPS
  6. Log stream
  7. Konfiguracja, restart, stop: co z danymi?
  8. Porównanie VM i PaaS, koszt
  9. Raport i sprzątanie

Architektura: przed i po

przed (po cleanup L02):
    Azure: brak zasobów kursu

L02 dla porównania:
    Internet -> Public IP -> NSG -> VM -> systemd -> gunicorn :8000 -> CloudNotes
po L03:
    Client -> HTTPS -> App Service (app-cloudnotes-<SUFFIX>, plan F1)
                         -> gunicorn -> CloudNotes (SQLite i pliki w /tmp instancji)

App Service: dwa zasoby

ZasóbRolaOdpowiednik z L02
App Service Plancompute: system, poziom, liczba instancji, cenaVM i jej rozmiar
Web Appaplikacja: kod, runtime, konfiguracja, adresaplikacja i unit systemd

Płacisz za plan, nie za aplikację.

Kategoria: Application Platform (PaaS) Azure App Service / AWS Elastic Beanstalk / Google App Engine


Zasoby projektu zostają

RodzajGdzieCykl życia
tymczasowerg-labNNusuwane na końcu zajęć
projekt CloudNotesrg-cloudnoteszostają, jeśli są tanie
drogie elementy projekturg-cloudnotesusuwane, odtwarzane z checkpointu

Od dziś potrzebny jest <SUFFIX>: adres app-cloudnotes-<SUFFIX>.azurewebsites.net musi być globalnie unikalny.


Koszt

PlanCenaUwagi
F1 Free, Linux0 USDwspółdzielone compute, limit CPU na dobę, 1 instancja, brak Always On, brak SLA
B1 Basic, Linuxokoło 0,018 USD/h, około 13 USD/miesiąctylko wariant awaryjny
  • F1: grupa rg-cloudnotes zostaje do L04
  • B1: usuwasz grupę na końcu zajęć

Krok 1, 3: start i Resource Group

az provider register --namespace Microsoft.Web --wait
az group create --name rg-cloudnotes --location <REGION>

Krok 4: App Service Plan

az webapp list-runtimes --os linux --output tsv | grep PYTHON
az appservice plan create --resource-group rg-cloudnotes --name plan-cloudnotes-<SUFFIX> \
  --location <REGION> --is-linux --sku F1
L02 (IaaS)L03 (PaaS)
rozmiar Standard_B2ats_v2poziom F1
obraz Ubuntu--is-linux
VNet, subnet, NSG, IP, dysk—

Krok 5: Web App

az webapp create --resource-group rg-cloudnotes --plan plan-cloudnotes-<SUFFIX> \
  --name app-cloudnotes-<SUFFIX> --runtime "PYTHON:3.12" --https-only true

az resource list --resource-group rg-cloudnotes \
  --query "[].{name:name, type:type}" --output table
  • https://app-cloudnotes-<SUFFIX>.azurewebsites.net: strona domyślna, z HTTPS
  • 2 zasoby (na L02: 6)
  • Bez kodu mamy już: system, Python, DNS, certyfikat, load balancer

Krok 6: App Settings

az webapp config appsettings set --resource-group rg-cloudnotes --name app-cloudnotes-<SUFFIX> \
  --settings APP_ENVIRONMENT=app-service SCM_DO_BUILD_DURING_DEPLOYMENT=true
def setting(name, default=None):
    return os.environ.get(name) or default
  • App Settings -> zmienne środowiskowe procesu
  • APP_ENVIRONMENT: czyta aplikacja
  • SCM_DO_BUILD_DURING_DEPLOYMENT: czyta mechanizm wdrożenia (build, pip install)
  • L02: Environment= w unicie. Kod ten sam.

Krok 7: paczka ZIP

git archive HEAD:project/src --format=zip --output=cloudnotes-app.zip

unzip -l ~/cloudnotes-app.zip
  • app.py i requirements.txt w korzeniu paczki
  • Bez .venv/ i __pycache__/
  • Paczka = artefakt wdrożeniowy, powtarzalny dla commita

Krok 8: wdrożenie

time az webapp deploy --resource-group rg-cloudnotes --name app-cloudnotes-<SUFFIX> \
  --src-path ~/cloudnotes-app.zip --type zip
ZIP -> Kudu -> Oryx build (venv, pip install)
    -> kontener Python 3.12 -> gunicorn --bind=0.0.0.0 --timeout 600 app:app

Portal: Deployment Center -> Logs -> Running oryx build

Plan Free: kilka minut cierpliwości.


Krok 9: test przez HTTPS

curl -s https://app-cloudnotes-<SUFFIX>.azurewebsites.net/health | jq
curl -s -o /dev/null -w "%{http_code} %{redirect_url}\n" \
  http://app-cloudnotes-<SUFFIX>.azurewebsites.net/health
  • healthy, environment: app-service
  • HTTP -> 301 -> HTTPS
  • Dodaj notatki (jedna z załącznikiem), wygeneruj raport
  • Backendy: sqlite, local, sync. Dane nadal na instancji.

Krok 10: log stream

az webapp log config --resource-group rg-cloudnotes --name app-cloudnotes-<SUFFIX> \
  --docker-container-logging filesystem
az webapp log tail --resource-group rg-cloudnotes --name app-cloudnotes-<SUFFIX>

Drugi terminal:

curl -s -o /dev/null -w "%{http_code}\n" https://app-cloudnotes-<SUFFIX>.azurewebsites.net/debug/error
  • Aplikacja pisze na stdout, platforma zbiera
  • L02: journalctl po SSH. L03: API, CLI, portal.
  • 500 = aplikacja działa i ma błąd -> logi

Krok 11: zmiana konfiguracji

az webapp config appsettings set --resource-group rg-cloudnotes --name app-cloudnotes-<SUFFIX> \
  --settings APP_ENVIRONMENT=app-service-test
curl -s https://app-cloudnotes-<SUFFIX>.azurewebsites.net/health | jq "{environment, instance, started_at}"
curl -s https://app-cloudnotes-<SUFFIX>.azurewebsites.net/api/notes | jq ".notes | length"
przedpo
environmentapp-serviceapp-service-test
started_atstarynowy
notatki40

Na koniec przywróć APP_ENVIRONMENT=app-service.


Krok 12: restart

az webapp restart --resource-group rg-cloudnotes --name app-cloudnotes-<SUFFIX>
Ścieżka w kontenerzeCykl życia
/tmp, system konteneraznika przy restarcie
/home (m.in. /home/site/wwwroot)trwały udział sieciowy planu
  • CloudNotes trzyma dane w /tmp/cloudnotes -> restart kasuje stan
  • PaaS zdjął z nas serwer, nie rozwiązał problemu stanu
  • SQLite w /home? Udział sieciowy, wiele instancji: zły pomysł

Rozwiązanie: Object Storage (L04), Managed Database (L05)


Krok 13: stop

az webapp stop --resource-group rg-cloudnotes --name app-cloudnotes-<SUFFIX>
curl -s -o /dev/null -w "%{http_code}\n" https://app-cloudnotes-<SUFFIX>.azurewebsites.net/health
az webapp start --resource-group rg-cloudnotes --name app-cloudnotes-<SUFFIX>
AkcjaKoszt płatnego planu
az webapp stopnadal naliczany
zmiana planu na F10
usunięcie planu0

403 - This web app is stopped odpowiada platforma, nie CloudNotes.


Krok 14: VM a PaaS

ZadanieL02: VML03: App Service
sieć, reguły, publiczny IPja?
HTTPS i certyfikatbrak?
system i aktualizacjeja?
Python, zależności, Gunicornja?
konfiguracjaEnvironment=?
logijournalctl po SSH?
stan po restarcieznika?

Ceny B1 szukasz w cenniku (pełne polecenie w instrukcji). Sweden Central: około 13,14 USD/miesiąc.


Kompromisy PaaS

Zyskujemy:

  • brak zarządzania systemem, runtime i serwerem aplikacji
  • HTTPS, DNS, logi, restart procesu: od platformy
  • powtarzalne wdrożenie artefaktu

Tracimy:

  • wybór systemu i dowolnych pakietów systemowych
  • tylko obsługiwane wersje runtime i sposób uruchamiania
  • limity planu, mechanizmy specyficzne dla dostawcy

Weryfikacja

Raport ~/l03-report.txt (polecenie w instrukcji):

  • plan F1 (lub B1), Linux
  • aplikacja Running, httpsOnly, PYTHON|3.12
  • dokładnie 2 zasoby w rg-cloudnotes
  • App Settings: APP_ENVIRONMENT=app-service, SCM_DO_BUILD_DURING_DEPLOYMENT=true
  • /health przez HTTPS: healthy
  • HTTP -> 301
  • cena B1 z cennika

Sprzątanie

Wariant F1: grupa zostaje.

az appservice plan show --resource-group rg-cloudnotes --name plan-cloudnotes-<SUFFIX> --query "sku.name" --output tsv
rm ~/cloudnotes-app.zip
az group list --tag course=cloud-services --query "[].{name:name, lab:tags.lab}" --output table

Wariant B1: usuń grupę.

az group delete --name rg-cloudnotes --yes --no-wait
az group wait --name rg-cloudnotes --deleted
az group exists --name rg-cloudnotes

Odtworzenie na L04: sekcja „Odtworzenie stanu cp03-app-service”.


Podsumowanie

  • Plan = compute i koszt, Web App = aplikacja
  • Dostarczam kod i konfigurację, platforma resztę
  • Paczka ZIP to artefakt, build robi platforma
  • App Settings = zmienne środowiskowe; zmiana restartuje aplikację
  • Logi: stdout, zbiera platforma
  • stop aplikacji nie zatrzymuje kosztu planu
  • Restart kasuje stan lokalny, także w PaaS

Następnie: L04, pliki poza instancją (Blob Storage).

 

Imię Nazwisko

OPIS