This commit is contained in:
nlitkowski 2022-01-05 01:08:54 +01:00
commit e248075771
47 changed files with 3617 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*/.ipynb_checkpoints/*

307
01_Intro/01_01.ipynb Normal file
View File

@ -0,0 +1,307 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Praktyczne zastosowania chmury obliczeniowej - wprowadzenie do zajęć"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Wprowadzenie do chmury obliczeniowej\n",
"\n",
"Co to jest chmura? Wielu z nas spotkało się z tym pojęciem podczas codziennych czynności, takich jak na przykład zapisywanie zdjęć w telefonie. Intuicyjnie domyślaliśmy się wtedy, iż zapisanie czegoś w chmurze oznacza, że plik nie będzie znajdował się fizycznie w pamięci naszego urządzenia, a zostanie gdzieś przesłany. Choć przechowywanie plików to zapewne najbardziej rozpoznawana w społeczeństwie usługa oferowana w modelu chmury obliczeniowej, nie jest ona ani historycznie pierwszą, ani nie dominuje rynku.\n",
"\n",
"Zadaniem tych zajęć jest przedstawienie i usystematyzowanie pojęcia chmury obliczeniowej. W szczególności przedstawione zostaną jej kluczowe cechy, typy oraz modele, wraz z odniesieniem do najczęstszych zastosowań. Ważnym aspektem podczas omawiania usług chmurowych jest też aspekt finansowy, gdyż to on stanowi jedną z kluczowych cech wyróżniających ten model obliczeń.\n",
"\n",
"W toku dalszych zajęć, poszczególne modele omówione zostaną z większą dokładnością. Przewidzane są również różne ćwiczenia praktyczne pokazujące w jaki sposób wchodzić w interakcję z chmurą obliczeniową w celu realizacji najczęstszych zadań.\n",
"\n",
"## Czym jest chmura obliczeniowa\n",
"\n",
"Jednoznaczne odpowiedzenie na tak postawione pytanie nie jest proste. Co więcej z każdym rokiem, wraz rozwojem dostępnych usług, zadanie to staje się coraz trudniejsze. W podstawowym ujęciu chmura obliczeniowa, czy też przetwarzanie w chmurze (ang. cloud computing) to model dostarczania szeroko rozumianej infrastruktury informatycznej (zasobów obliczeniowych, dysków, sieci, oprogramowania). Przed popularyzajcą modelu przetwarzania w chmurze, dostęp do poszczególnych elementów infrasturktury uzyskiwany był niezależnie od różnych dostawców:\n",
"\n",
"- zasoby obliczeniowe (serwer): kupowane na własność lub wynajmowane, przechowywane we własnych serwerowaniach (ang. on premises) lub w dedykowanych centrach danych (kololacja)\n",
"- dyski: kupowane na własność, konieczność zapewnienia replikacji, redundacji danych oraz wymiany sprzętu\n",
"- sieć: wysoko wydajna sięć przyłączana do siedziby firmy lub łącząca firmę z centrum danych\n",
"- oprogramowanie: kupowane w modelu licencyjnym (ograniczonym czasowo lub nie)\n",
"\n",
"Chmura obliczeniowa zmienia zupełnie sposób myślenia o infrastrukturze. Najlepiej zmianę tę zobrazować można to na przykładzie rynku muzycznego. Przed 2010 rokiem kluczową rolę w dystrubucji muzyki odgrywały płyty kompaktowe (i inne fizyczne nośniki danych), które były praktycznie jedynym możliwym sposobem na zapoznanie się z twórczością artystów. Słuchacz (użytkownik) musiał dokonać zakupu płyty, dzięki czemu uzyskiwał nieograniczony dostęp do wszystkich utworów muzycznych, które zawierała. Taki model sprzedaży można nazwać *włanościowym* (ang. ownership), gdyż stajemy się wyłącznymi właścicielami nośnika. W 2006 roku Szwedzka firma Spotify rozpoczęła pracę nad nowym modelem sprzedaży muzyki. Zamiast kupować poszczególne płyty, zaoferowała ona miesięczny abonament (subskrypcję) w ramach którego użytkownicy mogli słuchać bez ograniczeń dowolnych dostępnych utworów. Nie uzyskiwali oni natomiast żadnych praw do tych utworów, rezygnacja z abonamentu oznaczała utratę dostępu do muzyki. Konieczne jest stałe opłacanie uslugi nawet jeśli chcemy odtworzyć wcześniej dostępny utwór. Taki model można nazwać modelem *dostępowym* (ang. access), gdyż otrzymujemy w nim nielimitowany dostęp bez zdobywania trwałych praw do zasobów.\n",
"\n",
"W podobny sposób zmienił się i wciąż zmienia rynek IT. Kupowaną na własność infrastrukturę informatyczną i oprograwmowanie, zastępuję się wynajmowanymi zasobami, dostępnymi bez ograniczeń i na żądanie, wtedy kiedy są potrzebne. W ten sposób analogicznie jak na rynku muzycznym zmienia się też sposób płatności. Zamiast dużych wydatków początkowych na zakup infrastruktury i oprogramowania, koszty rozkładane są w czasie na cały czas działalności firmy. Te dwie cechy (dostępnośc na żądanie i płatność wedle użycia) wydają się być kluczowymi cechami wyróżniającymi model przetwarzania w chmurze. Fakt ten znajduje też odzwierciedlenie w definicjach chmury obliczeniowej formułowanych przez różne instytucje. Przykładowo Narodowy Instytut Standaryzacji i Technologii Stanów Zjednoczonych (NIST) definiuje przetwarzanie w chmurze jako [NIST]:\n",
"\n",
"> Cloud computing is a model for enabling ubiquitous, convenient, **on-demand** network access to a shared pool of configurable computing resources (e.g., networks, servers, storage, applications, and services) that can be rapidly provisioned and released with minimal management effort or service provider interaction. \n",
"\n",
"Firma Amazon, dostawca największej publicznej chmury obliczeniowej definiuje ją jako [AWS]:\n",
"\n",
"> Cloud computing is the **on-demand** delivery of IT resources over the Internet with **pay-as-you-go** pricing.\n",
"\n",
"Firma Microsoft, dostawca drugiej największej chmury obliczeniowej [MS]:\n",
"\n",
"> Cloud computing is the delivery of computing services—including servers, storage, databases, networking, software, analytics, and intelligence—over the Internet (\"the cloud\") to offer faster innovation, **flexible resources**, and economies of scale. You typically **pay only for cloud services you use**, helping you lower your operating costs, run your infrastructure more efficiently, and scale as your business needs change.\n",
"\n",
"\n",
"Pojęcie chmury obliczeniowej jest jednak bardzo szerokie, dlatego zamiast pojedynczej definicji, dużo łatwiej jest wyróżnić kluczowe cechy jakie je charakterysują [NIST]:\n",
"- **zasoby na żądanie** (ang. on-demand): klient może w dowolnym momencie, samodzielnie i automatycznie bez udziału obsługi uzyskać dostęp do oferowanych usług\n",
"- **dostęp przez sieć**: uslugi oferowane są za pośrednictwem sieci komputerowej (np. Internetu)\n",
"- **współdzielone zasoby** (ang. resource pooling): zasoby sprzętowe są współdzielone pomiędzy wielu klientów i udostępniane w środowisku zwirtualizowanym\n",
"- **elastyczność**: zasoby można tworzyć i usuwać szybko i bez ograniczeń ilościowych, dostępne są różne opcje skalowania infrastruktury\n",
"- **kontrola zużycia zasobów**: dostępne są szczegółowe statystyki zużycia poszczególnych zasobów o dużej rozdzielczości (najczęściej sekundowej), co pozwala na optymalizację kosztów usług\n",
"\n",
"\n",
"Poszczególne cechy realizowane mogą być w różnym stopniu. Przykładowo **kontrola zużycia zasobów** może być oferowana w rozliczaniu sekundowym, minutowym czy godzinnym (raczej nie spotyka się usług o dłuższym okresie). Sposób tworzenia **zasobów na żądanie** też może być zróżnicowany, praktycznie zawsze jest to dostęp do panelu administracyjnego za pośrednictwem przeglądarki internetowej, bardzo często dostępne jest też narzędzie CLI, rzadziej biblioteki programistyczne integrujące usługi chmurowe z różnymi językami programowania, czy API dostępowe w stylu REST.\n",
"\n",
"Trudność w jednolitym zdefiniowaniu chmury obliczeniowej wynika głównie z mnogości modeli i różnorodności oferowanych usług. Można wyróżnić 3 główne modele chmury obliczeniowej [NIST]:\n",
"- **Software as a Service** (SaaS): Usługa oferowana klientowi polega na zapewnieniu możliwość korzystania z aplikacji dostawcy działających w infrastrukturze chmury. Aplikacje są dostępne z różnych urządzeń klienckich za pośrednictwem interfejsu klienta, takiego jak przeglądarka internetowa (np. poczta e-mail oparta na sieci WWW) lub interfejsu programu. Konsument nie zarządza ani nie kontroluje podstawowej infrastruktury chmury, w tym sieci, serwerów, systemów operacyjnych, pamięci masowej, a nawet możliwości poszczególnych aplikacji, z możliwym wyjątkiem ograniczonych ustawień konfiguracji aplikacji specyficznych dla użytkownika.\n",
"- **Platform as a Service** (PaaS): Usługa oferowana klientowi polega na zapewnieniu możliwość wdrożenia w infrastrukturze chmury aplikacji utworzonych lub nabytych przez klienta, utworzonych przy użyciu języków programowania, bibliotek oraz usług obsługiwanych przez dostawcę. Konsument nie zarządza ani nie kontroluje bazowej infrastruktury chmury, w tym sieci, serwerów, systemów operacyjnych lub pamięci masowej, ale ma kontrolę nad wdrożonymi aplikacjami i ewentualnie konfiguracją środowiska uruchominiowego aplikacji.\n",
"- **Infrastructure as a Service** (IaaS): Usługa oferowana klientowi polega na zapewnieniu przetwarzania, przechowywania, sieci i innych podstawowych zasobów obliczeniowych, w których konsument może wdrażać i uruchamiać dowolne oprogramowanie, które może obejmować systemy operacyjne i aplikacje. Konsument nie zarządza bazową infrastrukturą chmury ani nie kontroluje jej, ale ma kontrolę nad systemami operacyjnymi, pamięcią masową i wdrożonymi aplikacjami; i ewentualnie ograniczoną kontrolę nad wybranymi komponentami sieciowymi (np. zapory sieciowe).\n",
"\n",
"Poniższy diagram przedstawia podstawowe modele chmury w odniesieniu do posiadania własnej infrastruktury i korzystania z usługi kolokacji. Widać, że modele chmury obliczeniowej układają się w hierarchię, w której kolejne modele zwięszają zakres obowiązków dostwacy. Przykładowo w modelu SaaS, znajdującym się na szczycie hierarchi, klient odpowiada tylko za dane przetwarzane w systemie, podczas gdy wszystko inne zapewniane jest przez dostawcę.\n",
"\n",
"![Diagram przedstawia główne modele chmury obliczeniowej (IaaS, PaaS, SaaS) w raz z zaznaczeniem składowych infrastryktury (pomieszczenia, zasilanie i sieć, sprzęt, wirtualizacja, guest OS, środowisko uruchomieniowe, aplikacja, dane użytkownika) i podmiotem za nią odpowiedzialnego. Jako punkt odniesienia na diagramie umieszczono też dwa warianty posiadania własnej infrastruktury (infrastrukura na miejscu oraz kolokacja). Przy infrastrukturze na miejscu dwórca systemu informatycznego odpowiedzialny jest za wszystko, podczas gdy przy kolokacji nie musi zarządzać pomieszczeniem oraz siecią i zasilaniem. Gdy infrastruktura znajduje się w chmurze IaaS twórca aplikacji zwolniony jest konieczności zarządzania sprzętem i wirtualizacją. W modelu PaaS twórca zarządza już tylko aplikacją i danymi użytkownika, podczas gdy w modelu SaaS, tylko danymi.](obrazy/typy_chmury.png)\n",
"\n",
"Więcej informacji na ten temat poszczególnych modeli zostanie przedstawione w poszczególnych zajęciach.\n",
"\n",
"## Rodzaje chmury obliczeniowej\n",
"\n",
"Modele chmury definują jakie usługi są świadczone oraz podział odpowiedzialności pomiędzy dostawcę i klienta. Z drugiej strony rodzaje chmury określają w jaki sposób usługa chmury jest świadczona. Wyróżniamy trzy rodzaje:\n",
"* **chmura publiczna**:\n",
"\n",
" Najpopularniejszy rodzaj chmury obliczeniowej, zasoby oferowane są w sposób współdzielony pomiędzy różnych kientów za pośrednictwem publicznego Internetu.\n",
"\n",
"* **chmura prywatna**:\n",
"\n",
" Wszystkie zasoby dedykowane są tylko jednemu klientowi, najczęściej są one fizycznie odzielone od innych zasobów dostawcy lub nawet zlokalizowane w siedzibie klienta. Szczególnym przypadkiem chmury prywatnej jest sytuacja, w której wewnętrzny dział IT oferuje firmie kompleksową, prywatną platrofmę chmurową. Przykład takiej infrastruktury przedstawiony został tutaj [ALL].\n",
"\n",
"* **chmura hybrydowa**:\n",
"\n",
" Połączenie chmury publicznej i hybrydowej. W chmurze hybrydowej część zasobów zlokalizowana jest w zasobach chmury publicznej, a część w chmurze prywatnej lub w klasycznej własnej infrastrukturze. Kryteria przydziału zasobów do lokalizacji mogą być różne: wrażliwość danych, łatwość migracji, staż oprogramowania itp."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Zalety chmury\n",
"\n",
"Zanim przedstawione zostaną kluczowe zalety chmury obliczeniowej konieczne jest zrozumienie charakterystyki finansowej usług oferowanych w chmurze. Jak już zostało to wspomniane przetwarzanie w chmurze zamienia początkowe koszty inwestycyjne na ciągłe opłaty za wykorzystane zasoby. Wcale nie jest oczywiste dlaczego taka zmiana ma być korzystna dla konsumenta. Pojęcie *całkowitego kosztu posiadania* (ang. TCO) pozwala porównać koszty posiadania własnej infrastruktury oraz chmury obliczeniowej. Całkowity koszt posiadania to suma kosztów (bezpośrednich i pośrednich) jakie firma będzie musiała ponieść na utrzymanie infrasturktury w danej perspetywie czasowej. Często błędnie przyjmuje się, że wiodącym kosztem posiadania własnej infrastruktury jest zakup sprzętu i oprogramowania. Założenie to jest słuszne tylko w bardzo krótkiej perspektywie czasowej. W dłuższym okresie uwidaczniaja się inne składowe TCO. W zależności od typu zasobu wyróżnić można następujące koszty wchodzące do TCO:\n",
"\n",
"- zasoby obliczeniowe: szafy, serwery; licencje na oprogramowanie; prad, chłodzenie\n",
"- zasoby dyskowe: dyski; zarzadzanie danymi, replikacja; prad, chłodzenie\n",
"- sieci komputerowe: urządzenia sieciowe; administracja; prad\n",
"\n",
"Dla każdego zasobu istotnym kosztem jest też zapewnienie wykwalifikowanej obsługi IT, ochrony oraz pomieszczenia/budynku. Przykładowa kalkulacja TCO została zamieszczona w materiałach poświęconych modelowi IaaS.\n",
"\n",
"Wracając do tematu głównych zalet usług chmurowych:\n",
"\n",
"1. **Zastąpienie początkowych kosztów inwestycyjnych kosztami operacyjnymi** (CapEx -> OpEx)\n",
"\n",
" W przypadku posiadania własnej infrastruktury konieczne są duże wydatki inwestycyjne na początku (ang. capital expenditure, CapEx). Następnie konieczne jest ponoszenie **stabilnych** kosztów utrzymania przez cały czas działania infrastruktury (ang. operational expenditure, OpEx). Wykorzystanie chmury obliczeniowej zupełnie likwiduje konieczność ponoszenia kosztów początkowych, przenosząc je na **zmienne** koszty utrzymania. Ta zminność stanowi jednocześnie wielką okazję i ryzyko. Początkowo koszty są zawsze małe co pozwala przeznaczyć środki w początkowym okresie funkcjonowania na rozwój. Koszty te mogą jednak rosnąć bardzo szybko wraz ze wzrostem zapotrzebowania. Dlatego tak ważne jest odpowiednie projektowanie systemów informatycznych, tak aby wdrożone w chmurze aplikacje nie tylko działały poprawnie ale również skalowały się w sposób efektywny finansowo.\n",
"\n",
"1. **Wykorzystanie efektu skali** (ang. economies of scale)\n",
"\n",
" Dostawca chmury obliczeniowej oferuje takie same usługi bardzo wielu klientom jednocześnie. Jest więc w stanie wdrożyć optymalizacje, które w ogromnej skali przynoszą wielkie oszczędności.\n",
" > **Ciekawostka**: Najwięksi dostawcy chmury obliczeniowej projektują własne układy scalone, procesory itp., co pozwala im znacznie zredukować koszty sprzętu.\n",
" \n",
" > **Ciekawostka**: Amazon dzięki zwiększeniu skali obniżył ceny niektórych usług w okresie 2006-2019 nawet 75 krotnie.\n",
"\n",
"1. **Infrastruktura zawsze dopasowana do potrzeb**\n",
"\n",
" W przypadku budowania własnej infrastruktury największym początkowym wyzwaniem jest zwymiarowanie potrzebnych zasobów. Niedoszacowanie, ograniczy możliwość realizacji celów biznesowych i wymusi konieczność szybszej wymiany sprzętu. Przeszacowanie prowadzi natomiast do zwiększonych kosztów początkowych, co zmniejsza środki na rozwój przedsiębiorstwa. Ogólnie częściej zauważa się tendencję do przewymiarowania infrastruktury, przez co znaczna jej część nie zostaje nigdy wykorzystana (szczególnie zasoby dyskowe).\n",
" \n",
"1. **Zwiększona elastyczność i zwinność**\n",
"\n",
" W klasycznym modelu, uzyskanie dostępu do nowego serwera może wymagać od kilku godzin do kilku miesięcy oczekiwania (sprzęt trzeba zamontować w serwerowni, skonfigurować, a często również kupić). Oprócz czasu utraconego na oczekiwanie, ogranicza to też możliwość eksperymentowania z nowymi rozwiązaniami. Przykładowo, wyobraźmy sobie, że jeden z zespołów chce sprawdzić czy wykorzystanie serwerów z GPU sprawdzi się przy rozwiązaniu danego problemu. Kupuje serwer, buduje go a następnie konfiguruje (co trwa 2 tygodnie), tylko po to by stwierdzić, po 2 dniach eksperymentów, że oprogramowanie, które wykorystuje nie skaluje się dobrze w modelu obliczeń SIMD. Chmura obliczeniowa zachęca do ekspetymentowania, gdyż dowolne zasoby można wynajać na godziny (a często nawet sekudny).\n",
" \n",
"1. **Brak wydatków na utrzymanie serwerowni**\n",
"\n",
" Posiadanie własnej infrastruktury nieodłącznie wiąże się z posiadaniem własnej serwerowni, która z pewnością generuje spore koszty utrzymania. Koszty te są tym większe im bardziej niezawodna musi być nasza serwerownia (większa redundancja zasobów, infrsastruktury, więcej personelu, itp.). Wymusza to ciągłe utrzymanie kompromisu pomiędzy bezpieczeństwem danych i kosztami. Tylko największe organizacje stać na utrzymanie w pełni profesjonalnej i niezawodnej serwerowni. Zastosowanie chmury obliczeniowej znacząco ogranicza ten problem, profesjonalne zarządzanie zasobami dostępne jest dla wszystkich w równych cenach. Należy jednak nadal pamiętać, że zapewnienie większej redundancji i dostępności nadal jest bardziej kosztowne niż jej brak.\n",
"\n",
"1. **Globalna infrastruktura**\n",
"\n",
" W wielu zastosowaniach, odległość od klienta (fizyczna lub sieciowa) jest bardzo istotna dla zapewnienia zgodności z regulacjami prawnymi lub niskich czasów odpowiedzi i wysokiej wydajności aplikacji. Posiadając własną infrastrukturę jesteśmy istotnie ograniczeni do fizycznej lokalizacji naszego sprzętu. Ograniczone są też możliwości szerkopasmowego dostępu do głównych węzłów sieci Internet. Dostawcy usług chmurowych oferują bardzo często swoje usługi w bardzo wielu lokalizacjach, co pozwala oferować aplikację z praktycznie dowolnego miejsca na świecie bez dodatkowych kosztów czy nakładów organizacyjnych.\n",
"\n",
"\n",
"## Wady oraz ryzyka związane z wykorzystaniem chmury obliczeniowej\n",
"\n",
"Jak każda nowa technologia, chmura obliczeniowa niesie wiele nowych możliwości oraz ryzyk. Obserwując współczesne trendy chmura obliczeniowa jest obecnie używana powszechnie niemalże we wszystkich branżach. Istnieją jednak obszary, w których jej zastosowanie nie jest łatwe a nawet wskazane. Przykładowo dla systemu wymagającego stałej i bardzo dużej mocy obliczeniowej, bardziej opłacalny będzie zakup odpowiedniego serwera i skorzystanie z usługi kolokacji. Podobnie sytuacja wygląda w przypadku każdego dedykowanego niszowego sprzętu. Poniższa sekcja przedstawia główne wady i ryzka, które należy względnić podejmując decyzję o wykorzystaniu chmury obliczeniowej.\n",
"\n",
"\n",
"1. **Brak dostępności do chmury obliczeniowej**\n",
"\n",
" Można wyróżnić trzy główne sytuacje, w których zostajemy odcięci od chmury obliczeniowej:\n",
" * **brak dostępu do Internetu**: \n",
" Gdy nasi pracownicy lub klienci zostają odcięci od Internetu, nie mamy możliwości wykorzystania zasobów chmury obliczeniowej, nawet jeśli te działąją wtedy bez problemów\n",
" * **awaria po stronie dostawcy chmury**: \n",
" Choć te zdażają się bardzo rzadko, a ich zasięg jest znacznie ograniczony, to mimo wszystko jest to istotne ryzyko, które należy względnić. W zależności od stali awarii może ona obejmować od kilkuminutowej przerwy w dostępnie do wybranych usług po trwałą utratę wszystkich danych. Przykład takiej historii przedstawiony jest tutaj [TYPO].\n",
" * **embargo lub sakncje gospodarcze i polityczne**:\n",
" Dostawcy usług chmurowych to bardzo często wielkie międzynarodowe przedsięborstwa, jednak nawet one podelegają legislacji państw w których działają. Ponadto, niektóre firmy mogą blokować działalność niezgodną z ich profilem, polityką wewnętrzną, a nawet światopoglądem. Jest to zdecydowanie najpoważniejsze z zagrożeń. O ile przerwy w dostępie do Internetu są czasowe, awarie najczęściej nie mają poważnych stuktów, o tyle odmowa lub wypowiedzenie umowy przez dostawcę chmury, wymusza natychmiastowe przeniesienie wszyskich zasobów. Przykład takiej historii przedstawiony jest tutaj [PAR].\n",
"\n",
"1. **Bezpieczeństwo i prywatność**\n",
"\n",
" Wykorzystanie zasobów publicznej chmury obliczeniowej niesie istotne, nowe ryzyka związane z bezpieczeństwem i prywatnością. Wykorzystanie przez dostawcę współdzielonej infrastruktury, otwiera nasze zasoby i dane na możliwość ataku pochodzącego od innych użytkowniwków chmury. Wątpliwości budzi też często fakt, że dostawca ma praktycznie nieograniczony dostęp do wszystkich naszych danych. Szczególną uwagę zwraca się na wykorzystanie tych danych do doskonalenia własnych, publicznie dostępnych usług lub do celów marketingowych.\n",
"\n",
"1. **Podatność na ataki**\n",
"\n",
" Innym aspektem bezpieczeństwa jest wykorzystanie komunikacji przez Internet jako sposób dostępowy do zasobów. Umożliwia to przeprowadzenie ataków, które tradycyjnym modelu wymagały by fizycznego wtargnięcia do budynków firmy. Przykład historii firmy, która zbankrutowała po tym jak atakujący zyskali dostęp do ich zasobów chmurowych opisany został tutaj [CODE].\n",
"\n",
"1. **Ograniczona kontrola i elastyczność**\n",
"\n",
" Wybierając dostawcę chmury obliczeniowej, zdani jesteśmy na jego ofertę. Jeśli potrzebnej przez nas usługi nie ma w ofercie, istnieje bardzo nikła szansa, że zostanie ona wprowadzona specjalnie dla nas. Należy pamiętać, że niezależnie jak jesteśmy dużą organizacją, jesteśmy tylko jednym z tysięcy jak nie milionów klientów. Ograniczenia w szczególności dotyczą konfiguracji sprzętowej, dostępności oprogramowania i ich wersji. Kolejnym elementem wpływającym na ograniczenie kontroli jest dostęp do wsparcia technicznego. W standardzie dostępny jest system helpdeskowy, w którym czas odpowiedzi waha się od kilku godzin do nawet dni.\n",
"\n",
"1. **Uzależnienie się od dostawcy chmury obliczeniowej** (ang. vendor lock-in)\n",
"\n",
" Poszczególni dostawcy chmury obliczeniowej, choć najczęściej oferują analogiczne usługi, są silnie nie kompatybilni między sobą. Przeniesienie infrastruktury pomiędzy dostawcami, nie jest zadaniem łatwym ani tanim. Aby w pełni wykorzystać możliwości oferowane przez naszego dostawcę chmury, oprogramowanie zostaje zaprogramowane w sposób ściśle wiążący je z konkretnym dostawcą co praktycznie uniemożliwia migrację. Problem ten jest szczególnie widoczny w modelu PaaS i w podejściu Serverless.\n",
"\n",
" Odpowiedzią na ten problem jest tak zwane podejście multicloud. Jednak wciąż brakuje satysfakcjonujących rozwiązań, obecnych na rynku wystarczająco długo aby można było im zaufać. Ponadto, uniezależniając się od dostawcy chmury, uzależniamy się od dostawcy usługi multicloud.\n",
"\n",
"1. **Rosnące koszty**\n",
"\n",
" Koszty infrastruktury w modelu chmury obliczeniowej nie są stałe i zależą od bardzo wielu, często trudnych do przewidzenia czynników. Nagły sukces naszej aplikacji może przynieść drastyczny wzrost wykorzystania zasobów, a co za tym idzie kosztów chmury. Co więcej, koszty chmury często rosną szybciej niż przypływy z komercjalizacji naszego sukcesu. Historia firmy, która została zmuszona do ucieczki z chmury obliczeniowej na rzecz własnej infrastruktury jest opisana tutaj [BOX].\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Dostawcy chmury obliczeniowej\n",
"\n",
"W 2021 roku trzech największych graczy rynku usług publicznej chmury obliczeniowej to: Amazon Web Services (32% rynku), Microsoft Azure (19% rynku) oraz Google Cloud (7% rynku) [CAN]. Jednak podział ten nie daje pełni obrazu rynku. Przykładowo jeśli spojrzymy na chmurę w modelu SaaS to liderm jest Microsoft (17%), Salesforce (12%) i Adobe (10%) [SYN].\n",
"\n",
"Przedstawienie wyczerpującej listy istotnych dostawców chmury obliczeniowej nie mieści się w zakresie tych zajęć. Można przyjąć, że stabilna lista najważniejszych dostawców to:\n",
"* Amazon Web Services (AWS)\n",
"* Microsoft Azure\n",
"* Google Cloud\n",
"* Alibaba Cloud\n",
"* IBM Cloud\n",
"* Oracle\n",
"* Salesforce\n",
"* SAP\n",
"* Rackspace Cloud\n",
"* VMWare\n",
"\n",
"\n",
"## Dostęp do wybranych usług chmurowych\n",
"\n",
"Praktycznie wszystkie serwisy oferujące zasoby w modelu chmury obliczeniowej są usługami komercyjnymi przeznaczonymi dla firm lub profesjonalistów. Większość dostawców chcąc się zabezpieczyć przed nadużyciami wymaga na etapie rejestracji autoryzacji karty płatniczej. W ten sposób dostawca ma znacznie większą szansę dochodzenia swoich roszczeń. Innym podejściem jest zablokowanie kosztownych usług do czasu weryfikacji konta użytkownika np. poprzez opłacenie pierwszej faktury lub ponownie autoryzację karty płatniczej.\n",
"\n",
"Niestety takie ograniczenia znacząco ograniczają dostęp do zasobów chmury dla osób rozpoczynających swoją przygodę z tym modelem obliczeniowym. Jest to szczególnie uciążliwe w przypadku zajęć w modelu uniwersyteckim, gdzie grupa studentów wykorzystuje indywidualne zasoby w celu realizacji zleconych zadań. Niniejsza sekcja przedstawi rekomendowany sposób uzyskania dostępu do zasobów poszczególnych dostawców chmury obliczeniowej.\n",
"\n",
"> **Uwaga**: Najwygodniejszym rozwiązaniem jest założenie kont z podaniem rzeczywistych danych oraz aktywnej karty płatniczej. Omawiane na zajęciach serwisy to firmy z wieloletnim doświadczeniem, obdarzone zaufaniem przez tysiące klientów. Ryzyko nadużyć z ich strony należy traktować jako minimalne. Należy jednak pamiętać o ryzyku z naszej strony [NIE].\n",
"\n",
"> **Uwaga**: Konta u dostawców usłuch chmurowych są często atakowane. Uzyskanie dostępu do czyjegoś konta pozwala na utworzenie zasobów obliczeniowych, które następnie wykorzystywane są np. do kopania kryptowalut. Nawet kilkaminut pozwala zarobić atakującemu wystarczająco dużo, szczególnie jeśli uda mu się utworzyć setki lub tysiące maszyn do obliczeń. Takie kilka minut nieuprawnionego użycia może jednak wiązać się z ogromnymi kosztami. Zawsze należy ustawić ograniczenia w ilości zasobów i przede wszystkim zadbać o bezpieczeństwo swojego konta poprzez mocne hasło i najlepiej autoryzację dwu/wielo-składnikową.\n",
"\n",
"> **Uwaga**: Nie należy się obawiać obarczenia kosztami eksperymentów z rozwiązaniami chmurowymi jeśli przestrzega się jednej prostej zasady: po zakończeniu eksperymentu należy usunąć wszystkie zasoby, które zostały utworzone. Koszt działania zdecydowanej większości usług naliczany jest z dokładnością do sekundy, a ceny za godzinę pracy nawet najdroższych zasobów nie przekraczają 100 zł (najczęsciej jest to koszt rzędu 25 gr za godzinę).\n",
"\n",
"> **Uwaga**: Zawsze warto ograniczyć dostęp do zasobów do adresów IP z puli `150.254.0.0/16` (sieć Uniwersytecka). Jest to szczególnie istotne w przypadku usług, których cennik zakłada naliczanie opłat nie tylko za czas ale też za ilość przetworzonych danych (np. OCR)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Heroku\n",
"Heroku umożliwia rejestrację bez autoryzacji karty płatniczej oraz oferuje dostęp do wszystkich istotnych funkcji w ramach darmowego dostępu (oczywiście z istotnie ograniczonymi zasobami).\n",
"\n",
"Ponadto, możliwe jest skorzystanie z oferty [Heroku + GitHub](https://www.heroku.com/github-students), gdzie można uzyskać dwuletni grant w wysokości $84/rok. Konieczne jest przystąpienie do programu [GitHub Student Developer Pack](https://education.github.com/pack) oraz autoryzacja karty płatniczej. Nie jest to jednak wymagane do realizacji tych zajęć."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Hetzner\n",
"\n",
"Hetzner również umożliwia rejestrację bez podania danych karty płatniczej, podczas rejestracji wystarczy wybrać płatność przelewem bankowym lub PayPal. Należy jednak zauważyć, że Hetzner nie oferuje żadnych darmowych limitów czy zasobów. Każda utworzona maszyna wirtualna będzie wiązała się z naliczeniem opłat na koncie. Na szczęście podstawowe maszyny Hetzner są bardzo tanie, ich koszt to od 2 do 5 groszy za każdą godzinę działania.\n",
"\n",
"> Uwaga: Większość systemów informatycznych Hetzner nie obsługuje polskich znaków.\n",
"\n",
"> Uwaga: Hetzner oferuje program poleceń, w ramach którego można uzyskać 20 EUR startowego salda na koncie ważne przez rok. Zapytaj prowadzącego zajęcia o link aktywacyjny."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Linode\n",
"\n",
"Do rejestracji w Linode niezbędna jest autoryzacja karty płatniczej. Ponadto podobnie jak Hetzner Linode nie udostępnia żadnych zasobów za darmo. W tym przypadku podstawowe maszyny Linode kosztują około 5 groszy za godzinę.\n",
"\n",
"> Uwaga: Linode słynie z bardzo korzystnych cenowo maszyn z kartami graficznymi. Niestety w związku z ograniczoną ich dostępnością w 2021 roku dostęp do nich jest możliwy tylko po dodatkowej weryfikacji konta"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Amazon Web Services (AWS)\n",
"\n",
"Do rejestracji w AWS niezbędne jest autoryzowanie karty płatniczej. W zamian za to otrzymujemy roczny [pakiet darmowych zasobów](https://aws.amazon.com/free).\n",
"\n",
"W ramach kursu otrzymasz również dostęp AWS Academy Learner Lab, gdzie odtrzymasz pakiek środków umożliwiający realizację wszystkich zadań omawianych na zajęciach."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Microsoft Azure\n",
"\n",
"Microsoft oferuje dostęp do swoich zasobów w ramach inicjatywy [Azure for Students](https://azure.microsoft.com/pl-pl/free/students/), gdzie możliwe jest założenie konta bez potrzeby autoryzacji karty płatniczej. Ponadto otrzymacie jednorazowe środki w wysokości $100 ważne przez rok oraz dostęp do wielu darmowych usług. Dostęp można odnawiać co roku."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Rekomendowana literatura uzupełniająca\n",
"\n",
"* [CHK]: Chmura Krajowa. [Chmura obliczeniowa - co to jest i jak działa?](https://chmurakrajowa.pl/dziennik-chmurowy/czym-jest-chmura-obliczeniowa/) Dziennk chmurowy, odcinek 2. 2020.\n",
"* [PRE]: Hu Tunh-Hui. [A Prehistory of the Cloud](https://mitpress.mit.edu/books/prehistory-cloud). The MIT Press. 2016.\n",
"* [BOX]: Historia Dropbox:\n",
" * Akhil Gupta. [Scaling to exabytes and beyond](https://dropbox.tech/infrastructure/magic-pocket-infrastructure). Dropbox.tech blog. 2016\n",
" * Trevor Jones. [Dropbox is likely an outlier with its successful cloud data migration off AWS](https://searchaws.techtarget.com/blog/AWS-Cloud-Cover/Dropbox-is-likely-an-outlier-with-its-successful-cloud-data-migration-off-AWS). AWS Cloud Cover blog. 2018.\n",
"* [TYPO]: Rebecca Hersher. [Amazon And The $150 Million Typo](https://www.npr.org/sections/thetwo-way/2017/03/03/518322734/amazon-and-the-150-million-typo). npr. 2017\n",
"* [PAR]: Jonathan Shieber, Danny Crichton. [Amazon Web Services gives Parler 24-hour notice that it will suspend services to the company](https://techcrunch.com/2021/01/09/amazon-web-services-gives-parler-24-hour-notice-that-it-will-suspend-services-to-the-company). Tech Crunch. 2021.\n",
"* [CODE]: Paul Venezia. [Murder in the Amazon cloud](https://www.infoworld.com/article/2608076/murder-in-the-amazon-cloud.html). InfoWorld. 2014.\n",
"* [ALL]: Piotr Michoński, Piotr Betker. [#11 - Infrastruktura Allegro](https://podcast.allegro.tech/infrastruktura_Allegro/). Allegro Tech Podcast. 2021\n",
"* [NIE]: Niebezpiecznik.pl. [Ile kosztuje niewiedza w chmurze? Analiza 5 niepotrzebnie wysokich rachunków](https://niebezpiecznik.pl/post/ile-kosztuje-niewiedza-w-chmurze-analiza-5-niepotrzebnie-wysokich-rachunkow/). Niebezpiecznik.pl. 2021\n",
"\n",
"# Literatura\n",
"\n",
"* [NIST]: Peter Mell, Timothy Grance. [The NIST Definition of Cloud Computing](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-145.pdf). National Institute of Standards and Technology, Computer Security Division. Special Publication 800-145. 2011.\n",
"* [AWS]: Amazon. [What is cloud computing?](https://aws.amazon.com/what-is-cloud-computing/). Amazon Web Services overview, online 2021.\n",
"* [MS]: Microsoft. [What is cloud computing?](https://azure.microsoft.com/en-us/overview/what-is-cloud-computing/). Azure overview, online 2021.\n",
"* [SYN]: Synergy Research Group. [SaaS Spending Hits $100 billion Annual Run Rate; Microsoft Extends its Leadership](https://www.srgresearch.com/articles/saas-spending-hits-100-billion-annual-run-rate-microsoft-extends-its-leadership). online 2019\n",
"* [CAN]: Canalys. [Global cloud services market Q1 2021](https://www.canalys.com/newsroom/global-cloud-market-Q121). online 2021"
]
}
],
"metadata": {
"interpreter": {
"hash": "98b0a9b7b4eaaa670588a142fd0a9b87eaafe866f1db4228be72b4211d12040f"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

442
02_PaaS/02_01.ipynb Normal file
View File

@ -0,0 +1,442 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Wstęp do zajęć\n",
"\n",
"Niniejsze zajęcia poświęcone są chmurze obliczeniowej w modelu PaaS (Platform as a Service). Podstawowe informacje na temat tego modelu zostały przedstawione na wcześniejszych zajęciach. Do kluczowych cech usług w tym modelu należą:\n",
"* brak konieczności zarządzania systemem operacyjnym i zainstalowanym środowiskiem uruchomieniowym\n",
"* wysoki stopień automatyzacji, znaczna część konfiguracji odbywa się poprzez ustawienia domyślne i konwencję\n",
"* konieczność dopasowania aplikacji do wymagań platformy uruchomieniowej\n",
"* ograniczony dostep do pewnych zasobów np. brak możliwości zapisu plików, ograniczenie komunikacji do protokołu HTTP\n",
"\n",
"Dostępnych jest wiele usług działających w tym modelu PaaS. Do najpopularniejszych należą:\n",
"\n",
"* Google App Engine - historycznie pierwsza taka usługa, która przetrwała do dziś\n",
"* Amazon AWS Elastic Beanstalk - w pewnym sensie jest to nakładka na usługę AWS EC2\n",
"* Microsoft Azure App Service\n",
"* Salesforce Heroku - jeden z pierwszych i wciąż najpopularniejszy dostawca usług tego typu\n",
"* DigitalOcean App Platform\n",
"* Red Hat OpenShift PaaS\n",
"* The Mendix Low-Code Platform\n",
"* Dev Graph Engine Yard\n",
"\n",
"W czasie zajęć poznamy platformę **Heroku**, która bardzo dobrze obrazuje możliwości oferowane przez model PaaS. Co ważne, w odróżnieniu od wielu dostawców, Heroku oferuje tylko usługę w modelu PaaS.\n",
"\n",
"## Na czym polega PaaS\n",
"\n",
"Model chmury obliczeniowej PaaS zakłada przeniesienie na dostawcę usługi odpowiedzialności za praktycznie wszyskie elementy środowiska, w którym działa aplikacja. Dostawca oprócz sprzętu i infrastruktury, dostarcza system operacyjny, bazy danych oraz środowisko uruchomieniowe dla naszej aplikacji. \n",
"\n",
"W modelu tym tworzona aplikacja najczęściej musi być odpowiednio przygotowana aby mogła zostać uruchomiona w ściśle kontrolowanym środowisku. W początkowych etapach rozwoju był to chyba najczęściej podnoszony argument przeciw takiemu rozwiązaniu. Ścisłe związanie tworzonego oprogramowania z dostawcą usługi było postrzegane jako istotne ograniczenie i zagrożenie dla projektów informatycznych. Wraz z globalnym wzrostem wykorzystania usług chmury obliczeniowej wzrosła również akceptacja dla zwiększenia stopnia powiązania oprogramowania z dostawcą usług (ang. vendor lockin).\n",
"\n",
"Z drugiej strony sam stopień powiązania aplikacji z platformą uległ znacznemu zmniejszeniu. Obecnie większość usług działąjących w modelu PaaS (np. Heroku), pozwala uruchomić niemal dowolną aplikację, napisaną w dowolnej technologi, nawet jeśli nie była ona projektowana specjalnie z myślą o wdrożeniu w chmurze.\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Jak działa Platform as a Service\n",
"\n",
"W następującej części omówiona zostanie zasada działania usługi typu PaaS na przykładzie Heroku. Heroku jest bardzo reprezentatywne dla tego typu usług, dzięki czemu wiedzę tę będzie można zastosować do większości dostępnych usług tego typu.\n",
"\n",
"Zasadę działania Heroku można przedstawić z kilku perspektyw:\n",
"1. Perspektywa działania aplikacji\n",
"1. Perspektywa budowania i wdrażania aplikacji\n",
"1. Perspektywa wirtualizacji i infrastruktury"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Perspektywa działania aplikacji\n",
"\n",
"Aplikacja zbudowana z wykorzystaniem rozwiązania typu PaaS może składać się z wielu modułów. Każdy moduł może korzystać z innych usług i działać w inny sposób. Jednak cechą wspólną wszyskich aplikacji wdrażanych w modelu PaaS jest udostępnianie usług w protokole HTTP i to moduł realizujacy tę funkcjonalność jest najczęściej uważany za główny dla danej aplikacji (nie rzadko stanowi też jedyny moduł aplikacji). \n",
"\n",
"> **Heroku**: Przykładowo w Heroku taki moduł nazywany jest `web` i tylko on może przyjmować żądania HTTP pochodzące z zewnątrz.\n",
"\n",
"Usługa PaaS udostępnia nam adres *URL* naszej aplikacji. Ten adres nie prowadzi jednak bezpośrednio do naszego modułu głównego. Zamiast tego każde wysłane żądanie HTTP trafia do tak zwanego *routera*. Jest to centralny punkt usługi, którego zadanie polega na odnalezieniu właściwej aplikacji, do której kierowane jest zapytanie oraz przekazanie danych do odpowiedniej instancji modułu. \n",
"\n",
"> **Heroku**: Heroku posiada jeden centralny *router* w każdym z regionów, a wszystkie one korzystają z jednego punktu startowego (*entry point*): `herokuapp.com`.\n",
"\n",
"*Router* realizuje również proces tak zwanego równoważenia obciążenia (ang. *load-balancing*). Polega on na przekazywaniu żądań równolegle do różnych kopii (instancji) tego samego modułu. W ten sposób aplikacja może obsłużyć dowolnie wiele wiadomości jednocześnie bez obawy o znaczący wzrost czasu odpowiedzi. Aby to było możliwe konieczne jest przestrzeganie kilku zasad już na etapie projektowania aplikacji:\n",
"\n",
"1. Moduł musi być bezstanowy - nie powinien przechowywać żadnych informacji w pamięci czy na dysku. Całość stanu powinna być przechowywana w zewnętrznej usłudze (np. bazie danych).\n",
"1. Komunikacja z modułem musi być bezstanowa - każde żądanie do modułu musi zawierać wszystkie informacje niezbędne do jego realizacji (patrz założenia stylu REST).\n",
"1. Moduł musi być lekki - aby możliwe było szybkie uruchamianie nowych instancji oraz wyłączania tych już niepotrzebnych.\n",
"\n",
"Skalowanie takich bezstanowych modułów może odbywać się automatycznie lub manualnie, w zależności od potrzeb.\n",
"\n",
"> **Uwaga**: Więcej na tamat zasad jakie powinien spełniać projekt zoptymalizowany pod wdrożenie w modelu PaaS przedstawia koncepcja [The Twelve-Factor App](https://12factor.net/pl/).\n",
"\n",
"Gdy moduł główny naszej aplikacji otrzyma już żądanie HTTP, może przystąpić do jego obsługi. Kod naszej aplikacji jest uruchamiany w zależności od środowiska, w którym aplikacja została napisana. Można wyróżnić trzy główne sposoby wykonania tego kodu:\n",
"\n",
"1. Aplikacja samodzielnie uruchamia serwer HTTP nasłuchujący na odpowiednim porcie\n",
"1. Aplikacja jest przygotowana zgodnie z założeniami zewnętrznego serwera HTTP\n",
"1. Aplikacja dostarczana jest w postaci zbudowanego obrazu Docker\n",
"\n",
"Sposób pierwszy jest najpopularniejszy w przypadku języków kompilowanych (np. Go, Rust, Java), podczas gdy drugi jest najpopularniejszy w jezykach skryptowych (Python - uWSGI, Ruby - Unicorn). Sposób trzeci, jest stosunkowo młody, choć większość dostawców oferuje taką usługę, nie zawsze jest ona tak samo wspierana jak pierwsze dwa podejścia. Wybór sposobu uruchamiania aplikacji ma spore znaczenie na wymaganych zasobów. Przykładowo w rozwiązaniu 2. nie ma potrzeby aby proces odpowiedzialny za moduł aplikacji był stale uruchomiony, podczas gdy w pozostałych modelach jest to niezbędne.\n",
"\n",
"> **Heroku**: Potrafi automatycznie wykryć w jaki sposób uruchomić daną aplikację korzystając z bardzo wielu predefiniowanych profili.\n",
"\n",
"> **Heroku**: Obsługuje wszystkie trzy sposoby uruchamiania aplikacji, są one też w pełni wspierane.\n",
"\n",
"> **Heroku**: W ramach darmowego dostępu, wszystkie aplikacje hostowane na Heroku, są automatycznie usypiane jeśli nie są aktywne (nie otrzymują żądań HTTP) przez określony czas.\n",
"\n",
"Gdy odpowiedni proces aplikacji otrzymuje żądanie HTTP, obsługuje je zgodnie ze swoją implementacją. Co ważne może on w tym celu wykorzystywać:\n",
"* inne procesy w ramach tej samej aplikacji - przykładowo procesy robocze do wykonywania zadań w tle,\n",
"* usługi dodatkowe - w tej kategorii najczęściej znajdują się zarządzane bazy danych oraz zasoby dyskowe od dostawcy usługi PaaS,\n",
"* usługi zewnętrzne i zasoby Internetu - każda aplikacja może niemal dowolnie korystać z zasobów dostępnych przez sięć Internet.\n",
"\n",
"Na koniec obsługi żądania, zwracana jest odpowiedź HTTP, która przekazywana jest do *routera* i następnie do przeglądarki użytkownika aplikacji.\n",
"\n",
"![Schemat przedstawia architekturę usługi typu PaaS. Zaznaczono poszczególne warstwy infrastruktury: zasilanie i dostęp do sieci, sprzęt i dyski, system operacyjny, środowisko uruchomieniowe. Twórca aplikacji dostarcza tylko kod modułów (A, B, C, D) realizujących logikę biznesową systemu, które są odseparowane od pozostałych części systemu. Również serwer HTTP oraz skalowanie horyzontalne jest zapewniane przez dostawcę. Aplikacja może swobodnie łączyć się z innymi zasobami w Internecie oraz korzystać z usług dodatkowych takich jak: przechowywanie plików, autoryzacja czy baza danych.](obrazy/paas-runtime.png)\n",
"\n",
"Rysunek 1. Przykładowa architektura usługi typu PaaS. Dostawca zapewnia wszystko z wyjątkiem kodu aplikacji (moduły A, B, C i D)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Perspektywa budowania i wdrażania aplikacji\n",
"\n",
"Proces budowania i wdrażania aplikacji w wielu popularnych usługach typu PaaS oparty jest na repozytorium kodu. Aplikacja budowana jest po każdej zmianie wybranej gałęzi repozytorium.\n",
"\n",
"> **Heroku**: W przypadku Heroku, należy przesłać zmiany na specjalne, tworzone dla każdej aplikacji repozytorium hostowane na serwerach Heroku.\n",
"\n",
"Takie podejście do budowania aplikacji, wspomaga (a tak właściwie wymaga) wdrożenie modelu CI (ang. Continuous Integration, ciągła integracja). Budowanie aplikacji musi być w pełni zautomatyzowane i wykonywane w ściśle kontrolowanym środowisku. Platforma PaaS udostępnia schematy według, których budowane są aplikacje. Często też możliwe jest zdefiniowanie własnych schematów oraz budowanie aplikacji w dowolnym środowisku z wykorzystaniem kontenerów Docker.\n",
"\n",
"> **Heroku**: Heroku obsługuje większość popularnych języków programowania i frameworków: Node.js, Java, Python, PHP, Go i [wiele innych](https://devcenter.heroku.com/articles/buildpacks). Aplikację można też zbudować korzystając z kontenerów.\n",
"\n",
"Przykładowo w środowisku Python, zwyczajowo wszystkie zewnętrzne zależności powinny być opisane w pliku `requirements.txt`. Podczas zautomatyzowanego budowania aplikacji, odpowiedni schemat budowania dla języka Python, zainstaluje wszystkie wymagane zależności i dopiero wtedy przystąpi do budowania właściwej aplikacji.\n",
"\n",
"Zbudowana aplikacja jest łączona z konfiguracją a następnie pakowana i nazywana (np. nazwą, wersją, numerem comita w repozytorium, czy bieżącą datą) tworząc *wydanie* (ang. release). Kolejne wydania aplikacji tworzą rejestr do którego można tylko dodawać nowe elementy. W ten sposób zawsze istnieje możliwość powrotu do wersji wcześniejszej. Tak zdeponowane wydanie może następnie posłużyć do wykonania wdrożenia aplikacji. Jedna zbudowana aplikacja za sprawą różnych konfiguracji (np. testowa, produkcyjna) może prowadzić to wielu wydań. Każde wydanie może zostać uruchomione wielokrotnie czy to w ramach procesu skalowania, czy odtwarzania po awarii jednej z instancji.\n",
"\n",
"![Schemat przedstawia proces budowania, wydawania i uruchamiania aplikacji w modelu PaaS. Proces rozpoczyna się od comita na repozytorium kodu. Kod jest następnie przesyłany do zautomatyzowanego systemu budowania gdzie jest łączony z zależnościami oraz budowany. Tak zbudowanie oprogramowanie łączone jest następnie z konfiguracją tworząc wydanie. Wydanie aplikacji może zostać uruchomione w różnych środowiskach.](obrazy/paas-build.png)\n",
"\n",
"Rysunek 2. Przykładowy schemat procesu budowania aplikacji na potrzeby usługi w modelu Paas."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Perspektywa wirtualizacji i infrastruktury\n",
"\n",
"Korzystając z usług w modelu PaaS, warto też być świadomym jak fizycznie zorganizowana jest infrastrktura, z której korzystamy. Przedstawione tu informacje są bardzo ogólne, gdyż przyjęte rozwiązania techniczne różnią się u poszczególnych dostawców. Można jednak przyjąć, że przedstawiona organizacja jest wspólna dla większości usług.\n",
"\n",
"Przede wszystkim aplikacje uruchamiane w usłudze PaaS korzystają z w pełni zwirtualizowanego środowiska. Najczęściej jest to wirtualizacja kilku poziomowa. Na załączonym schemacie fizyczny serwer (o bardzo dużych zasobach obliczeniowych) jest hostem dla wielu maszyn wirtualnych. Pojedyncza maszyna wirtualna jest natomiast hostem dla bardzo wielu aplikacji wdrożonych w modelu PaaS. Każda z takich aplikacji może pracować we własnym zwirtualizowanym środowisku (np. kontenerze Docker). Całość połączona jest poprzez sieć wirtualną i zabezpieczona odpowiednio skonfigurowaną zaporą sieciową. *Router* jest odpowiedzialny za przesyłanie żądań HTTP do odpowiednich maszyn wirtualnych i dalej do kontenerów i aplikacji.\n",
"\n",
"Przy przydzielaniu zasobów stosuje się bardzo często tak zwany over-provisioning. Polega to na udostępnianiu większej ilości wirtualnych zasobów, niż jest fizycznie dostępne. Przyjmuje się założenie, że jest bardzo mało prawdopodobne aby jednocześnie wszystkie aplikacje potrzebowały 100% zadeklarowanych zasobów. Oczywiście w skrajnym przypadku może to powodować przerwy w działaniu niektórych aplikacji oraz spadki wydajności. Stąd tak ważna jest konfiguracja skalowania i instancji zapasowych. Z drugiej strony takie podejście pozwala drastycznie zmniejszyć koszty usługi. W porównaniu z dedykowanym serwerem redukcja kosztów może sięgać nawet 100x, a w porównaniu z zasobami wirtualnymi ale o dedykowanych zasobach 10x. Niektórzy dostawcy usług oferują wariant usługi w ramach, którego zasoby nie są współdzielone i/lub przydzielane wielokrotnie. Taka usługa jest znacznie droższa od standardowej, ale gwarantuje stabilną wydajność i dostępność nie zależnie od obciążenia zasobów usługodawcy.\n",
"\n",
"> **Heroku**: Jak już zostało to powiedziane wcześniej, Heroku nie utrzymuje swojej własnej dedykowanej infrastruktury. Korzysta natomiast z zasobów AWS, w szczególności z maszyn wirtualnych EC2, które stanowią podstawę mocy obliczeniowej dostępnej dla aplikacji. Jedna maszyna wirtualna nawet najsłabsza, może bez problemu obsłużyć wiele aplikacji. W ten sposób wdrożenie aplikacji na Heroku może nadal być bardziej opłacalne niż bezpośrednio na AWS EC2. Ciekawe opracowanie na ten temat znajduje się [tu](https://christopher.xyz/2019/01/23/heroku-dyno-sizes.html).\n",
"\n",
"![test](obrazy/paas-hardware.png)\n",
"Rysunek 3."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Zadania do realizacji w czasie zajęć\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Konfiguracja środowiska\n",
"\n",
"1. Zarejestruj się w usłudze Heroku korzystając z formularza pod adresem: <https://signup.heroku.com/>.\n",
"\n",
"1. Zainstaluj narzędzie do zarządzania aplikacjami w chmurze Heroku:\n",
"\n",
" ```bash\n",
" cd /dev/shm && wget https://cli-assets.heroku.com/heroku-linux-x64.tar.gz && tar xvf heroku-linux-x64.tar.gz\n",
" ```\n",
" > **Uwaga**: Oczywiście Heroku CLI możesz zainstalować w dowolnej lokalizacji w systemie, jeśli chcesz aby komenda `heroku` była dostępna globalnie w całym systemie zainstaluj ją w `/usr/local/bin`.\n",
"\n",
" > **Uwaga**: Katalog `/dev/shm` to dość specjalne miejsce w każdym współczesnym systemie linuxowym. Jest to dysk zlokalizowany w pamięci operacyjnej, w związku z czym jego zawartość jest czyszczona przy każdym wyłączeniu komputera. Ponadto pamiętaj że umieszczając tam duże pliki ograniczasz ilość pamięci operacyjnej dostępnej dla systemu i innych procesów.\n",
"\n",
"1. Zaloguj się w zainstalowanym narzędziu:\n",
"\n",
" ```bash\n",
" /dev/shm/heroku/bin/heroku login\n",
" ```\n",
"\n",
" Komanda ta może poprosić Cię o otwarcie w przeglądarce internetowej wyświetlonego linku w celu wykonania logowania do serwisu Heroku.\n",
"\n",
" > **Uwaga**: Dane logowania (login i hasło) nie zostaną zapisane na komputerze. Heroku (podobnie jak większość współczesnych serwisów dbających o bezpieczeństwo użytkowników) korzysta z tak zwanych *tokenów* dostępowych. Podając login i hasło, system weryfikuje Twoje uprawnienia, a następnie generuje specjalny token dostępowy, który następnie pozwala na dostęp do zasobów bez podawania/przechowywania hasła. Token może mieć ograniczone uprawnienia, a co najważniejsze można go unieważnić. Więcej informacji znajduje się w [dokumentacji Heroku](https://devcenter.heroku.com/articles/authentication)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## Przykładowa aplikacja\n",
"\n",
"1. Sklonuj repozytorium Git zawierające przykładowy projekt startowy w Javie (używający frameworka Spring):\n",
"\n",
"\n",
" ```bash\n",
" cd ~\n",
" git clone https://github.com/heroku/java-getting-started.git\n",
" cd java-getting-started\n",
" ```\n",
"\n",
"1. Utwórz nową aplikację na Heroku i wyświetl informacje o niej:\n",
"\n",
" ```bash\n",
" appName=$(/dev/shm/heroku/bin/heroku create --stack heroku-20 --region eu --json | jq -r '.name')\n",
" /dev/shm/heroku/bin/heroku apps:info $appName\n",
" ```\n",
" \n",
"\tNowo utworzoną aplikację zobaczymy także w interfejsie webowym pod adresem: <https://dashboard.heroku.com/apps>.\n",
"\n",
" > **Uwaga**: Tak naprawdę wystarczyłaby komenda `heroku create` (ewentualnie z własną nazwą tworzonej aplikacji), reszta powyższego polecenia przechwytuje nazwę nowo utworzonego projektu i zapisuję ją w zmiennej powłoki do późniejszego użycia.\n",
"\n",
" > **Uwaga**: Tworząc aplikację nie podaliśmy jej nazwy, Heroku generuje je automatycznie jako zbitki dwóch losowych słów z języka angielskiego.\n",
"\n",
" > **Uwaga**: Parametr `--stack` określa bazowy obraz kontenera na podstawie, którego utworzona zostanie aplikacja. Więcej informacji w [dokumentacji](https://devcenter.heroku.com/articles/stack).\n",
"\n",
"1. Polecenie `heroku create` nie tylko utworzyło aplikacje w infrastrukturze Heroku, ale jednocześnie zarejestrowało dodatkowe repozytorium docelowe (upstream) dla naszej aplikacji. Dzięki temu można bardzo łatwo wysłać kod aplikacji na serwery Heroku korzstając z narzędzia `git`:\n",
"\n",
" ```bash\n",
" git push heroku main\n",
" ```\n",
"\n",
"\tAplikacja powinna być dostępna po podanym na końcu linkiem. Link można też uzyskać w interfejsie webowym, jest on stały dla danej aplikacji.\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Modyfikacja aplikacji\n",
"\n",
"1. Dodamy teraz obsługę nowej ścieżki w naszej przykładowej aplikacji. Zmodyfikuj plik `src/main/java/com/example/Main.java` dodając:\n",
"\n",
" * w nagłówku pliku \n",
" ```java\n",
" import org.springframework.web.bind.annotation.PathVariable;\n",
" ```\n",
" * wewnątrz klasy Main\n",
" ```java\n",
" @RequestMapping(\"/hello/{name}\")\n",
" String hello(@PathVariable(value=\"name\") String name) {\n",
" return \"hello\";\n",
" }\n",
" \n",
" \n",
" ```\n",
"\n",
"1. Dodaj plik `src/main/resources/templates/hello.html` o następującej treści:\n",
"\n",
" ```html\n",
" <!DOCTYPE html>\n",
" <html xmlns:th=\"http://www.thymeleaf.org\" th:replace=\"~{fragments/layout :: layout (~{::body},'db')}\">\n",
" \n",
" <body>\n",
" <div class=\"container\">\n",
" <h1>Hello <span th:text=\"${name}\">name</span>!</h1>\n",
" </div>\n",
" </body>\n",
" </html>\n",
" ```\n",
"\n",
"1. Utwórz nowy commit i wyślij zmiany do Heroku.\n",
"\n",
" ```bash\n",
" git add src/main/resources/templates/hello.html\n",
" git commit -a -m 'Hello'\n",
" git push heroku main\n",
" ```\n",
"\n",
" Po krótkiej chwili aplikacja powinna zostać podmieniona.\n",
"\n",
" > **Wskazówka**: Kompletne logi z procesu kompilacji i wdrażania aplikacji dostępne są w interfejsie webowym.\n",
"\n",
"1. Aplikację można usunąć za pomocą interfejsu webowego lub z linii poleceń:\n",
"\n",
" ```bash\n",
" /dev/shm/heroku/bin/heroku apps:delete $appName\n",
" ```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Aplikacja od zera w Pythonie\n",
"\n",
"1. W tym zadaniu utworzymy aplikację od zera i uruchomimy ją w chmurze Heroku. Skorzystamy z gotowej przykładowej aplikacji wyświetlającej losowe strony.\n",
"\n",
"1. Stwórz nowy katalog i wewnątrz niego utwórz puste repozytorium `git`:\n",
"\n",
" ```bash\n",
" mkdir newApp\n",
" cd newApp\n",
" git init\n",
" ```\n",
"\n",
"1. Skopiuj do tego katalogu cztery pliki (`layout.jinja2`, `table.jinja2`, `lipsum.jinja2` i `main.py`) dołączone do materiałów do zajęć.\n",
"\n",
"1. Tworzymy nową aplikację na Heroku i wysyłamy naszą aplikację:\n",
"\n",
" ```bash\n",
" appName=$(/dev/shm/heroku/bin/heroku create --stack heroku-20 --region eu --json | jq -r '.name')\n",
" git add .\n",
" git commit -m 'Pierwsza wersja'\n",
" git push heroku master\n",
" ```\n",
"\n",
" Ostatnia linijka się nie powiedzie, bo Heroku nie wie co zrobić z wysyłanym kodem. Możesz też sprawdzić w interfejsie webowym co się stało.\n",
"\n",
"1. Heroku stara się automatycznie wykryć język aplikacji i odpowiednio ją skompilować/zbudować. Pisząc własną aplikację warto poczytać dokładnie jak to robi. Większość języków/frameworków ma pewne konwencje nazywania plików czy wyszczególniania zależności i wystarczy się do nich stosować, by Heroku obsłużyło je poprawnie. \n",
"\n",
" > **Uwaga**: Takie podejście znacząco ułatwia korzystanie z platformy, szczególnie początkującym użytkownikom. W dalszej części zajęć pokazane zostanie jak przejąć pełnie kontroli nad Heroku i podjąć wszystkie decyzje samodzielnie.\n",
"\n",
" Obecność pliku `requirements.txt` jest sygnałem dla Heroku, że mamy do czynienia z aplikację napisaną w Pythonie, a w tym pliku są zależności do zainstalowania przez managera pakietów `pip`. Tworzymy więc w naszym projekcie plik `requirements.txt` o zawartości:\n",
"\n",
" ```python\n",
" pyramid\n",
" pyramid-jinja2\n",
" pyramid-debugtoolbar\n",
" faker\n",
" uwsgi\n",
" ```\n",
"\n",
"\tNastępnie dodajemy go do repozytorium i wysyłamy do Heroku:\n",
"\n",
"\t```bash\n",
"\tgit add requirements.txt\n",
" git commit -m 'requirements.txt'\n",
" git push heroku master\n",
" ```\n",
"\n",
" Teraz powinniśmy widzieć jak ściągane są zależności naszej aplikacji i na końcu zobaczymy link pod jakim nasza aplikacja 'działa'. Odwiedź stronę w przeglądarce, czy strona działa zgodnie z oczekiwaniami?\n",
"\n",
"1. Logi naszej aplikacji można zawsze sprawdzić w interfejsie webowym. Można to też zrobić bezpośrednio z konsoli:\n",
"\n",
" ```bash\n",
" /dev/shm/heroku/bin/heroku logs -a $appName\n",
" ```\n",
"\n",
" Aplikacja co prawda się zbudowała, ale Heroku dalej nie wie jak ją uruchomić.\n",
"\n",
"1. Aby poinstruować Heroku jak zbudowaną aplikację uruchmić musimy utworzyć plik `Procfile` (uwaga na wielką literę) o zawartości:\n",
"\n",
"\t```\n",
" web: uwsgi --http-socket=:$PORT --die-on-term --module=main:app\n",
"\t```\n",
"\n",
" Mówimy w nim, że nasza aplikacja jest aplikacją webową i można ją uruchomić podanym poleceniem (to samo zadziałałoby lokalnie po utworzeniu odpowiedniego środowiska wirtualnego). Tutaj chcemy, by uWSGI nasłuchiwał na porcie o numerze pochodzącym ze zmiennej środowiskowej `PORT` (definiowanej przez Heroku).\n",
"\n",
"\tPo wysłaniu zmian do Heroku wszystko powinno już działać.\n",
"\n",
"1. Aplikację możemy łatwo usunąć:\n",
"\n",
" ```bash\n",
" /dev/shm/heroku/bin/heroku apps:delete $appName\n",
" ```\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Większa kontrola nad Heroku\n",
"\n",
"Heroku bardzo dobrze wykrywa domyślne ustawienia i konfiguracje. Czasem jednak to nie wystarcza. Struktura wdrażanej aplikacji może być zbyt złożona, lub dostosowana pod inną infrastrukturę. W takiej sytuacji pomocą służą pliki konfiguracyjne Heroku:\n",
"\n",
"* [Procfile](https://devcenter.heroku.com/articles/procfile) - samodzielnie sprawdza się dla najprostszych aplikacji, często działa w połączeniu z konfiguracją w `app.json`\n",
"* [app.json](https://devcenter.heroku.com/articles/app-json-schema) - pozwala definiować dodatkowe informacje na temat aplikacji oraz umożliwia zarządzanie dodatkami (np. bazą danych)\n",
"* [heroku.yml](https://devcenter.heroku.com/articles/build-docker-images-heroku-yml) - stworzony z myślą o wdrażaniu przy użyciu narzędzia `Docker`. Nie jest kompatybilny `Procfile`.\n",
"\n",
"\n",
"Przekształcimy teraz poprzednią aplikację tak aby uzyskać pełną kontrolę nad środowiskiem, w którym będzie działać. Wykorzystamy do tego narzędzie `Docker` i konfigurację z wykorzystaniem pliku `heroku.yml`.\n",
"\n",
"1. Dodaj plik `heroku.yml` o następującej treści:\n",
"\n",
" ```yaml\n",
" build:\n",
" docker:\n",
" web: Dockerfile\n",
" run:\n",
" web: uwsgi --http-socket=:$PORT --die-on-term --module=main:app\n",
" ```\n",
" Pierwsza część informuje Heroku w jaki sposób zbudować naszą aplikację, dla uzyskania pełnej elastyczności podajemy tylko nazwę pliku `Dockerfile` naszej aplikacji. W ten sposób możemy zrealizować dowolne operacje, skorzystać z dowolnych narzędzi.\n",
"\n",
" > **Wskazówka**: W sekcji `docker` można umieścić wiele pozycji, co umożliwi zbudowanie wielu obrazów docker.\n",
"\n",
" Druga część pliku odpowiada za określenie jak uruchomić naszą aplikację. Działa podobnie jak Procfile.\n",
"\n",
" > **Wskazówka**: W sekcji `run` można umieścić wiele pozycji, co umożliwi uruchomienie wielu procesów w ramach jednej aplikacji.\n",
"\n",
"1. Utwórz plik `Dockerfile` o następującej treści\n",
"\n",
" ```dockerfile\n",
" FROM python:3\n",
" WORKDIR /usr/src/app\n",
"\n",
" COPY requirements.txt ./\n",
" RUN pip install --no-cache-dir -r requirements.txt\n",
"\n",
" COPY . .\n",
" ```\n",
"\n",
" Bazujemy tu na oficjalnym obrazie Python. Na początek kopiujemy plik `requirements.txt` i instalujemy wszystkie zależności, następnie kopiujemy resztę projektu. Nie podajemy dyrektyw `ENTRYPOINT` ani `CMD`, gdyż zostaną one zastąpione przez konfigurację z sekcji `run` pliku `heroku.yml`.\n",
"\n",
"\n",
"\n",
"1. Usuwamy plik `Procfile`.\n",
"\n",
" ```bash\n",
" rm Procfile\n",
" ```\n",
"\n",
"1. Zmieniamy *stack* naszej aplikacji w Heroku tak aby oparta była ona o kontener:\n",
"\n",
" ```bash\n",
" /dev/shm/heroku/bin/heroku stack:set container\n",
" ```\n",
"\n",
"1. Dodajemy pliki do repozytorium i wysyłamy do Heroku. Nowa wersja strony powinna zostać zbudowana i uruchomiona. Zwróć uwagę na proces budowania, który obecnie pobiera i buduje odpowiednie obrazy dockerowe. Heroku nie korzysta już ze swoich domyślnych ustawień, zamiast tego buduje obraz docker zgodnie z dostarczaoną specyfikacją."
]
}
],
"metadata": {
"interpreter": {
"hash": "98b0a9b7b4eaaa670588a142fd0a9b87eaafe866f1db4228be72b4211d12040f"
},
"kernelspec": {
"display_name": "Python 3.9.5 64-bit ('base': conda)",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

212
02_PaaS/02_zadania.ipynb Normal file
View File

@ -0,0 +1,212 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Zadania domowe\n",
"\n",
"W ramach tego modułu do zdobycia są 4 punkty. Wszystkie zadania bazują na platformie Heroku. W przypadku rozwiązania (poprawnego) zadania 1.2 nie ma potrzeby wykonywania zadania 1.1.\n",
"\n",
"## Zadanie 1.1 (2 punkty)\n",
"Uruchom dowolną aplikacje na swoim koncie Heroku. Nazwa aplikacji musi być ustawiona na `uam-wmi-pzc-<INDEX>-z-1-1`. Strona musi być renderowana w całości po stronie serwera i zawierać w tagu body tylko bieżący czas UTC w formacie ISO 8601 (YYYY-MM-DDThh:mm:ss+00:00) jak w poniższym przykładzie:\n",
"\n",
"```html\n",
"<html>\n",
"<head>\n",
" <title>Rozwiązanie zadania PZC 1.1</title>\n",
"</head>\n",
"<body>\n",
"2021-07-29T11:15:02+00:00\n",
"</body>\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Sposób sprawdzania zadania\n",
"Poprawność wykonania zadania można sprawdzić korzystając ze skryptu. Konieczne jest podstawienie poprawego numeru indeksu w pierwszej lini skryptu."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: bs4 in /home/faculty/bikol/.local/lib/python3.7/site-packages (0.0.1)\n",
"Requirement already satisfied: beautifulsoup4 in /home/faculty/bikol/.local/lib/python3.7/site-packages (from bs4) (4.10.0)\n",
"Requirement already satisfied: soupsieve>1.2 in /home/faculty/bikol/.local/lib/python3.7/site-packages (from beautifulsoup4->bs4) (2.2.1)\n",
"\u001b[33mWARNING: You are using pip version 21.2.3; however, version 21.3 is available.\n",
"You should consider upgrading via the '/usr/bin/python3 -m pip install --upgrade pip' command.\u001b[0m\n",
"\n",
"========================================\n",
"\n",
"Zadanie 1.1 nie zaliczone\n",
"\n",
"========================================\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Błędny format daty:\n",
"test\n",
"2021-10-27T10:27:33+00:00\n"
]
}
],
"source": [
"from __future__ import print_function\n",
"\n",
"!pip3 install bs4 --user\n",
"\n",
"INDEX=\"329575\"\n",
"\n",
"from bs4 import BeautifulSoup\n",
"import urllib.request\n",
"from datetime import datetime\n",
"from datetime import timezone\n",
"import sys\n",
"\n",
"def eprint(*args, **kwargs):\n",
" print(*args, file=sys.stderr, **kwargs)\n",
"\n",
"def test_solution(index):\n",
" valid = False\n",
" try:\n",
" with urllib.request.urlopen('https://uam-wmi-pzc-'+index+'-z-1-1.herokuapp.com/') as response:\n",
" html = response.read()\n",
" soup = BeautifulSoup(html, 'html.parser')\n",
" try:\n",
" dateText = soup.body.get_text().strip()\n",
" try:\n",
" now = datetime.now(tz=timezone.utc)\n",
" date = datetime.fromisoformat(dateText)\n",
"\n",
" eprint(\"Data na stronie %s\"%date)\n",
" if abs(date - now).seconds < 1:\n",
" valid = True\n",
"\n",
" except:\n",
" eprint(\"Błędny format daty:\")\n",
" eprint(dateText)\n",
" except:\n",
" eprint(\"Nie udało się pobrać treści tagu <body>\")\n",
"\n",
" except urllib.error.URLError as e:\n",
" eprint(e.status)\n",
" \n",
" return valid\n",
"\n",
"print(\"\\n========================================\\n\")\n",
"if test_solution(INDEX):\n",
" print(\"Zadanie 1.1 zaliczone\")\n",
"else:\n",
" print(\"Zadanie 1.1 nie zaliczone\")\n",
"print(\"\\n========================================\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Zadanie 1.2 (4 punkty)\n",
"Celem tego zadania jest poznanie bardziej zaawansowanych możliwości wdrażania aplikacji na platformę Heroku. \n",
"\n",
"Zadanie polega na uruchomieniu na platformie Heroku systemu [Gitea](https://gitea.io/). W tym celu konieczne jest przygotowanie odpowiedniego [pliku YAML](https://devcenter.heroku.com/articles/build-docker-images-heroku-yml), który umożliwi utworzenie odpowiednich zasobów w ramach platformy Heroku oraz dokona ich konfiguracji.\n",
"\n",
"Jako punkt odniesienia proszę korzystać z oficjalnej instrukcji instalacji Gitea z wykorzystaniem Dockera w trybie rootless. W szczególności następujący plik `docker-compose.yml` zawiera wszystkie niezbędne informacje do wykonania zadania (należy go przetłumaczyć na plik `heroku.yml`):\n",
"\n",
"```YAML\n",
"version: \"2\"\n",
"\n",
"services:\n",
" server:\n",
" image: gitea/gitea:1.14.5-rootless\n",
" environment:\n",
" - GITEA__database__DB_TYPE=postgres\n",
" - GITEA__database__HOST=db:5432\n",
" - GITEA__database__NAME=gitea\n",
" - GITEA__database__USER=gitea\n",
" - GITEA__database__PASSWD=gitea\n",
" restart: always\n",
" volumes:\n",
" - ./data:/var/lib/gitea\n",
" - ./config:/etc/gitea \n",
" - /etc/timezone:/etc/timezone:ro\n",
" - /etc/localtime:/etc/localtime:ro\n",
" ports:\n",
" - \"3000:3000\"\n",
" - \"2222:2222\"\n",
" depends_on:\n",
" - db\n",
"\n",
" db:\n",
" image: postgres:13\n",
" restart: always\n",
" environment:\n",
" - POSTGRES_USER=gitea\n",
" - POSTGRES_PASSWORD=gitea\n",
" - POSTGRES_DB=gitea\n",
" volumes:\n",
" - ./postgres:/var/lib/postgresql/data\n",
"```\n",
"\n",
"\n",
"> **Wskazówka:**: Skorzystaj z usługi [Managed PostgreSQL from Heroku](https://www.heroku.com/postgres) oraz sekcji `setup` pliku `heroku.yml`.\n",
"\n",
"\n",
"### Sposób sprawdzania zadania\n",
"\n",
"Zadanie to sprawdzane będzie ręcznie, jesteś zobowiązany udostępnić:\n",
"\n",
"1. repozytorium Git zawierające całe rozwiązanie zadania\n",
"\n",
" Kod na repozytorium musi być kompletny, oraz umożliwiać automatyczne wdrożenie na platformę Heroku poprzez:\n",
" ```bash\n",
" heroku git:remote\n",
" git push heroku master\n",
" ```\n",
"\n",
" Zakładamy przy tym, że odpowiednia aplikacja Heroku została już utwożona i skonfigurowana pod odpowiedni *stack*.\n",
"\n",
"1. link do wdrożonej aplikacji\n",
"\n",
" Wdrożona Gitea powinna hostować przynajmniej jedno repozytorium git."
]
}
],
"metadata": {
"interpreter": {
"hash": "98b0a9b7b4eaaa670588a142fd0a9b87eaafe866f1db4228be72b4211d12040f"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

View File

@ -0,0 +1,43 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{% block title %}{{ title }}{% endblock %} ~ Jinja2 demo</title>
<script src="https://code.jquery.com/jquery-3.3.1.slim.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
<![endif]-->
{% block head %}{% endblock %}
</head>
<body>
<nav class="navbar navbar-expand-md navbar-light bg-light">
<a class="navbar-brand" href="{{ request.route_url('index') }}">Jinja2 demo</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Pages</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="{{ request.route_url('table', seed=''|rand_string) }}">Random table</a>
<a class="dropdown-item" href="{{ request.route_url('lipsum') }}">Lorem ipsum</a>
</div>
</li>
</ul>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-8 offset-md-2">
{% block content %}<p>Pick a subpage from the navigation bar above</p>{% endblock %}
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,10 @@
{% extends 'layout.jinja2' %}
{% block title %}Lorem ipsum{% endblock %}
{% block content %}
{% for p in paragraphs %}
<p>{{ p }}</p>
{% endfor %}
{% endblock %}

View File

@ -0,0 +1,57 @@
from pyramid.config import Configurator
from pyramid.view import view_config
import string
from faker import Faker
from jinja2 import contextfilter
import os
fake = Faker()
# A hack that allows to automatically generate random URLs in the template.
# The '@contextfilter' decorator is necessary, otherwise the result would be cached
@contextfilter
def randString(context, dummy):
return ''.join([fake.random.choice(string.ascii_letters + string.digits) for n in range(16)])
@view_config(route_name='index', renderer='layout.jinja2')
def index(request):
return {'title': 'Index'}
@view_config(route_name='lipsum', renderer='lipsum.jinja2')
def lipsum(request):
return {'paragraphs': fake.paragraphs(nb=fake.random.randint(5,10))}
@view_config(route_name='table', renderer='table.jinja2')
def random_table(request):
faker_state = fake.random.getstate()
seed = request.matchdict['seed']
fake.random.seed(seed)
number_of_columns = fake.random.randint(5,10)
columns = fake.words(nb=number_of_columns)
rows = []
for i in range(0, fake.random.randint(30,50)):
rows.append([fake.random.randint(0,1000) for i in range(0, number_of_columns)])
fake.random.setstate(faker_state)
return {'columns': columns,
'rows': rows}
config = Configurator(settings={'debugtoolbar.hosts': '0.0.0.0/0'})
config.add_route('index', '/')
config.add_route('lipsum', '/lipsum')
config.add_route('table', '/table/{seed}')
config.include('pyramid_jinja2')
thisDirectory = os.path.dirname(os.path.realpath(__file__))
config.add_jinja2_search_path(thisDirectory)
config.include('pyramid_debugtoolbar')
config.commit()
jinja2_env = config.get_jinja2_environment()
jinja2_env.filters['rand_string'] = randString
jinja2_env.autoescape = False
config.scan()
app = config.make_wsgi_app()
if __name__ == '__main__':
from wsgiref.simple_server import make_server
server = make_server('', 6543, app)
server.serve_forever()

View File

@ -0,0 +1,39 @@
{% extends 'layout.jinja2' %}
{% block title %}Table{% endblock %}
{% block head %}
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs4/dt-1.10.16/datatables.min.css"/>
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.16/datatables.min.js"></script>
<script>
$(document).ready( function () {
$('#table').DataTable();
} );
</script>
<style>
#table {
width: 100%;
}
</style>
{% endblock %}
{% block content %}
<table id="table">
<thead>
<tr>
{% for column in columns %}
<th>{{ column }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
{% for datum in row %}
<td>{{ datum }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

268
03_IaaS/03_01.ipynb Normal file
View File

@ -0,0 +1,268 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Wstęp do modułu\n",
"\n",
"W tym module zajmiemy się modelem IaaS (Infractructure as a Service) chmury obliczeniowej. Podstawowe informacje na jego temat zostały przedstawione na pierwszych zajęciach. Do kluczowych cech usług w tym modelu należą:\n",
"\n",
"* wykorzystanie wirtualizacji w celu udostępnienia zasobów obliczeniowych wielu użytkownikom jednocześnie\n",
"* dostęp i tworzenie zasobów z wykorzystaniem API\n",
"* pełna dowolność w konfiguracji oprogramowania (OS, środowisko uruchomieniowe)\n",
"* istotnie ograniczony lub brak wpływu na konfigurację sprzętową\n",
"\n",
"![Diagram przedstawia główne modele chmury obliczeniowej (IaaS, PaaS, SaaS) w raz z zaznaczeniem składowych infrastryktury (pomieszczenia, zasilanie i sieć, sprzęt, wirtualizacja, guest OS, środowisko uruchomieniowe, aplikacja, dane użytkownika) i podmiotem za nią odpowiedzialnego. Jako punkt odniesienia na diagramie umieszczono też dwa warianty posiadania własnej infrastruktury (infrastrukura na miejscu oraz kolokacja). Przy infrastrukturze na miejscu dwórca systemu informatycznego odpowiedzialny jest za wszystko, podczas gdy przy kolokacji nie musi zarządzać pomieszczeniem oraz siecią i zasilaniem. Gdy infrastruktura znajduje się w chmurze IaaS twórca aplikacji zwolniony jest konieczności zarządzania sprzętem i wirtualizacją. W modelu PaaS twórca zarządza już tylko aplikacją i danymi użytkownika, podczas gdy w modelu SaaS, tylko danymi.](../01_Intro/obrazy/typy_chmury.png)\n",
"\n",
"Niniejszy moduł podzielony jest na cztery części. Pierwsza poświęcona jest motywacjom stojącym za infrastrukturą IaaS, jej wadom i zaletom. Druga część przedstawia najczęściej oferowane usługi chmurowe w modelu IaaS. Trzecia oraz czwarta część poświęcona jest praktycznemu wykorzystanu usług jednego z dostawców IaaS z wykorzystaniem interfejsu web oraz CLI.\n",
"\n",
"# Ewolucja w kierunku Infrastructure as a Service (IaaS)\n",
"\n",
"Usługi chmurowe w modelu IaaS powstały w odpowiedzi na konkretne potrzeby firm wytwarzających oprogramowanie. Aby lepiej je zrozumieć konieczne jest przedstawienie sposobu zarządzania infrastrukturą IT przed popularyzacją chmury obliczeniowej.\n",
"\n",
"## Infrastruktura na miejscu\n",
"\n",
"Jest to najbardziej oczywiste i historycznie pierwsze rozwiązanie problemu utrzymania infrastruktury na potrzeby projektów informatycznych. Z angielskiego często nazywane jest ***on premises*** lub skrótowo ***on-prem***. Polega na samodzielnym zakupie, konfiguracji i utrzymaniu całości (lub znacznej) części infrastruktury wymaganej przez dany projekt. Podejście to nie wykazuje cech charakterystycznych dla chmury obliczeniowej.\n",
"\n",
"### Zalety\n",
"\n",
"Główną zaletą takiego podejścia jest pełna kontrola nad wszyskimi aspektami infrastruktury. Z technicznego punktu widzenia pozwala to dobrać optymalną konfigurację sprzętową i programową dla konkretnego typu oprogramowania. Możliwe jest też korzystanie z wysoce niestandardowej infrastruktury (np. serwerów mainframe, niestandardowych procesorów, dysków, itp). Z punktu widzenia bezpieczeństwa dane przechowywane na serwerach nie opuszczają firmy, co jest bardzo istotne w niektórych branżach.\n",
"\n",
"### Wady\n",
"\n",
"Podejście takie ma jednak sporo wad, które zasadnoczo można zgrupować w następujące obszary:\n",
"\n",
"1. **Koszty**\n",
" Utrzymanie własnej infrastruktury wiąże się z dużymi kosztami zarówno podczas jej budowy jak i poźniejszego utrzymania. Koszty budowy infrastruktury muszą zostać poniesione jeszcze przed uruchomieniem pierwszej wersji systemu, a co za tym idzie przed osiągnięciem jakichkolwiek zysków z projektu. Ponadto bardzo często nie jest możliwe dokładne oszacowanie skali wymaganych zasobów, co często skutkuje ich przeszacowaniem i jeszcze większym wzrostem kosztów.\n",
"\n",
" Należy pamiętać, że do stworzenia własnej infrastruktury nie potrzeba tylko serwerów, a także odpowiednio przystosowanych pomieszczeń/budynków, redundantnego zasilania, połączeń sieciowych, wentylacji i klimatyzacji. Najczęściej koszt samych serwerów jest niższy od pozostałych wydatków.\n",
"\n",
"1. **Utrzymanie**\n",
" Raz zbudowana infrastruktura wymaga cięgłego utrzymania. Skutkuje to powstaniem w ramach organizacji odzielnych działów infrastruktury IT. To z kolei rozmywa działalność przedsiębiorstwa, które zamiast skupiać się na swojej głównej misji musi zatrudniać wielu pracowników z nią nie związanych.\n",
"\n",
"1. **Skalowalność**\n",
" Zapotrzebowanie na infrastrukturę nie jest stałe. Zmienia się w zależności od bardzo wielu czynników, często w sposób trudny do przewidzenia. Jednak nawet w przypadku prostej i przewidywalnej sezonowej zmiany obciążenia systemu (np. systemy podatkowe, platformy sprzedażowe), posiadana infrastruktura musi być dopasowana do najwyższego możliwego obciążenia. Prowadzi to do sytuacji, w której zasoby nie są wykorzystywana efektywnie przez większość czasu.\n",
"\n",
" Ponadto niezależnie od wysokości nakładów poniesionych na budowę własnej infrastruktury, zawsze istnieje granica powyżej, której nie jest możliwe dodanie większej ilości zasobów (np. w skutek braku miejsca w serwerowni). W takiej sytuacji dodanie kolejnego serwera/dysku może wiązać się z nieproporcjonalnie dużymi wydatkami co znacząco ogranicza możliwości rozwoju projektu/firmy/organizacji.\n",
"\n",
"1. **Bezpieczeństwo**\n",
" Obszar bezpieczeństwa jest jednocześnie najczęściej wskazywaną zaletą jak i wadą posiadania własnej infrastruktury. Fizyczna lokalizacja serwerów wewnątrz firmy ma swoje zalety, jednak wraz z rozwojem sieci komputerowych (głównie Internetu), coraz częściej atakujący nie potrzebuje fizycznego dostępu do sprzętu. Konieczne jest zatem zapewnienie programowego i sieciowego bezpieczeństwa infrastruktury, co wiąże się z zatrudnieniem kolejnych pracowników z dziedziny bezpieczeństwa systemów IT. Ponadto, w małych i średnich organizacjach osiągnięcie wysokiego poziomu zabezpieczeń jest zreguły zbyt kosztochłonne.\n",
"\n",
"\n",
"### Przykłady\n",
"\n",
"Obecnie w modelu tym swoją infrastrukturę utrzymują głównie bardzo duże firmy i organizacje, o szczególnych wymaganiach wobec bezpieczeństwa danych lub specjalistycznych serwerów. Coraz częściej infrastruktura na miejscu jest łączona z usługami chmurowymi tworząc tak zwaną chmurę hybrydową, gdzie kluczowe systemy i dane przechowywane są w pełni kontrolowanym środowisku, podczas gdy systemy o mniejszym znaczeniu uruchamiane są w chmurze obliczeniowej.\n",
"\n",
"Przykładem organizacji działających w tym modelu są:\n",
"\n",
"* Uniwersytet im. Adama Mickiewicza w Poznaniu\n",
"* Giełda Papierów Wartościowych w Warszawie\n",
"* większość polskich banków np. Santander\n",
"* instytucje rządowe np. Zakład Ubezpieczeń Społecznych\n",
"\n",
"## Kolokacja\n",
"\n",
"Podejście to polega na powierzeniu części odpowiedzialności za infrastrukturę zewnętrznej, specjalistycznej firmie. Nadal możemy kupić serwer, nie musimy natomiast budować serwerowni ani nią zarządzać. Pozwala to znacząco zredukować początkowe wydatki na infrastrukturę, a także późniejsze jej utrzymanie. Ponadto część firm oferujących usługę kolokacji pozwala wynająć serwer na określony czas. Oczywiście odbywa się to kosztem utraty dowolności przy doborze sprzętu. Jednak w ten sposób początkowe wydatki mogą być zredukowane niemalże do zera.\n",
"\n",
"Z punktu widzenia chmury obliczeniowej, kolokacja nie wiele się różni od serwerowni na miejscu. Biorąc pod uwagę znaczne korzyści względem poprzedniego podejścia, w pewnym sensie stanowi główną jej alternatywę.\n",
"\n",
"### Wady i zalety\n",
"\n",
"Skorzystanie z usługi kolokacji powoduje, że nasze serwery opuszczają siedzibę firmy, a wszelka komunikacja odbywa się z pośrednictwem sieci (najczęściej publicznego Internetu). Z drugiej strony znacznie redukujemy początkowy koszt, a także ograniczamy nakład pracy na zarządzanie infrastrukturą. Korzystając z kolokacji dużo łatwiej jest też skalować posiadaną infrastrukturę, choć dalej obowiązują te same ograniczenia, a skolowanie w górę jest znacznie łatwiejsze niż w dół.\n",
"\n",
"Wiele firm oferujących usługę kolokacji oferuje różne usługi dodatkowe, które zdejmują z nas odpowiedzialność za pewne zadania związane z utrzymaniem infrastruktury. Przykładowo usługodawca może za nas wymieniać dyski twarde w serwerach, czy aktualizować oprogramowaie typu firmware.\n",
"\n",
"### Przykłady\n",
"\n",
"Usługa kolokacji oferowana jest przez wyspecjalizowane firmy. Wiele z nich oferuje bardzo wysokie gwarancje dostępności sprzętu rzędu 99.9%, oraz posiada stosowne certyfikaty bezpieczeństwa. Przykładami dostawców są:\n",
"\n",
"* Poznański Park Naukowo-Technologiczny fundacji UAM\n",
"* beyond.pl\n",
"* Netia SA\n",
"* NASK - Państwowy Instytut Badawczy\n",
"\n",
"### Koszt\n",
"\n",
"Ceny usług kolokacji są często ustalane indywidualnie. Jednak w 2021 roku można przyjąć następujące szacunkowe koszty:\n",
"- pojedynczy serwer wiekości 1 unit (1U): 50-150 zł miesięcznie\n",
"- 1/3 szafy Rack 19\" (około 11U): 300-500 zł miesięcznie \n",
"- cała szafa Rack 19\" (około 42U): 1000-1500 zł miesięcznie\n",
"\n",
"Do tego należy koliczyć koszt energi elektrycznej 0.5-0.6 zł/kWh.\n",
"\n",
"Przykładowo jeśli potrzebujemy małego serwera 1U, wyposażonego w 16 rdzeniowy procesor, 128GB RAM oraz 2 dyski SSD to musimy się liczyć z następującymi kosztami początkowymi:\n",
"- zakup serwera 10-20k zł\n",
"- instalacja w serwerowni 500-1000 zł\n",
"\n",
"Ponadto miesięcznie koszt utrzymania takiej infrastruktury to:\n",
"- koszt prądu przy założonym stałym zużyciu prądu na poziomie 400W: 150 zł miesięcznie\n",
"- koszt usługi kolokacji 50-150 zł miesięcznie\n",
"\n",
"Zakładając dwuletni czas amortyzacji sprzętu otrzymujemy miesięczny koszt utrzymania infrastruktury na poziomie 600-1200 zł. Jeśli zrezygnujemy z dowolności sprzętu to serwer o takich parametrach można też wynająć za 400-500 zł miesięcznie.\n",
"\n",
"> **Ciekawostka**: Wiele firm oferuje możliwość wirtualnego zwiedzenia ich serwerowni [TOUR]."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Wirtualizacja własnego/wynajętego sprzętu\n",
"\n",
"Kolejnym krokiem w kierunku usługi chmury obliczeniowej w modelu IaaS, jest wprowadzenie wirtualizacji. Zmiana z infrastruktury na miejscu w kierunku kolokacji była motywowana głównie redukcją kosztów początkowych tworzenia infrastruktury. Wprowadzenie wirtualizacji rozwiązuje zupełnie inny problem. Zakup nowego serwera, jego instalacja w serwerowni oraz konfiguracja może trwać wiele dni, a nawet tygodni. W dynamicznie zmieniającym się środowisku i szybko rozwijających się projektach zasoby często potrzebne są natychmiastowo. Im większa organizacja, tym częściej i szybciej potrzebuje alokacji nowych zasobów. Z drugiej strony zauważono, że większość kupowanych zasobów jest przeszacowana. Ze względu na bezpieczeństwo poszczególne projekty/systemy informatyczne muszą być niezależne, co prowadzi do to marnowania dużej mocy obliczeniowej, która nie może zostać wykorzystana na potrzeby innego projektu.\n",
"\n",
"Wirtualizacja w dużej mierze rozwiązuje oba te problemy. W większości zastosowań takich jak serwery www, aplikacje sieciowe czy bazy danych nie jest wymagany bezpośredni dostęp do sprzętu. Oprogramowanie może być zatem uruchamiane w środowisku wirtualnym. Wirtualizacja zapewnia wysoką separację procesów uruchomionych w ramach poszczególnych maszyn wirtualnych. W ten sposób w ramach jednego serwera można uruchomić wiele różnych systemów bez obawy o konflikty i obniżenie bezpieczeństwa, jednocześnie znacznie zwiększając wykorzystanie zasobów.\n",
"\n",
"![Schemat przedstawia serwery obsługujące wiele maszyn wirtualnych.](obrazy/wirtualizacja.png)\n",
"\n",
"### Wady i zalety\n",
"\n",
"1. **Koszt**\n",
" W tym przypadku koszty analogiczne jak w poprzednich typach infrastruktury. Należy jednak uzględnić koszt oprogramowania do wirtualizacji oraz dodatkowe koszty utrzymania. Wdrożenie wirtualizacji pozwala jednak zaoszczędzić wiele zasobów poprzez bardziej efektywne ich wykorzystanie.\n",
"\n",
"1. **Utrzymanie**\n",
" Początkowo firmy zaczęły wdrażać wirtualizację na swoich (własnych lub wynajętych) serwerach, często tworząc rozbudowne środowiska wirtualizacji. W ten sposób powstały jednak nowe problemy. Środowiskiem wirtualizacji trzeba było zarządzać, ponownie konieczne okazywało się zatrudnianie pracowników wyłącznie do jego obsługi. Należy jednak zauważyć, że skala problemu jest znacznie mniejsza niż w przypadku infrastruktury na miejscu. Zarządzenie środowiskiem wirtualizacji obejmuje tylko warstwę oprogramowania. Zarządzanie sprzętem i lokalizacją może zostać powierzone wyspecjalizowanym firmom. Jednakże, każda złożona infstarstruktura powoduje rozmycie danej organizacji i odciąganie jej zasobów ludzkich od tego w czym się specjalizuje.\n",
"\n",
"1. **Skalowanie**\n",
" Wprowadzenie wirtualizacji znacząco ułatwia skalowanie infrastruktury. Tym razem możliwe są już oba rodzaje skalowania: wertykalne (poprzez wzrost ilości zasobów dla jednej maszyny) oraz horyzontalne (poprzez wzrost liczby maszyn). W odróżnieniu od poprzednich typów infrastruktury możliwe jest też łatwe i tanie skalowanie w dół, a odzyskane w ten sposób zasoby mogą zostać efektywnie wykorzystane w innych projektach/systemach.\n",
"\n",
"1. **Bezpieczeństwo**\n",
" Należy pamiętać, że bezpieczeństwo wirtualizacji opiera się na separacji procesów na poziomie systemu operacyjnego/hypervisora, i jako takie musi być niższe niż przy wykorzystaniu niezależnych serwerów dedykowanych. Pomimo, że oprogramowanie do wirtualizacji jest bardzo dojrzałe, nie można wykluczyć ryzyka znalezienia błędów. Należy rozważyć też istnienie błędów sprzętowych, które mogą obniżać bezpieczeństwo środowika wirtualnego (np. Meltdown, Spectre). \n",
" \n",
" Najbardziej prawdopodobnym zagrożeniem w takim przypadku jest uzyskanie przez jedną maszynę wirtualną dostępu do zasobów innej maszyny wirtualnej. Decydując się na wirtualizację należy rozważyć na ile takie ryzyko jest istotne z punktu widzenia danego systemu. Istnieją różne metody eliminowania i ograniczania ryzyk związanych ze środowiskiem wirtualnym. Należy również pamiętać, że maszyny wirtualne mogą współdzielić zasoby sprzętowe, nie jest zatem rozważne trzymanie kopi bezpieczeństwa danych na tej innej maszynie wirtualnej ale w ramach tego samego serwera fizycznego.\n",
"\n",
"\n",
"### Przykłady\n",
"\n",
"Na rynku dostępne jest bardzo wiele produktów oferujących gotowe środowiska wirtualizacji. Co ważne istnieją rozwiązania darmowe o bardzo wysokiej jakości.\n",
"\n",
"* Proxmox VE (darmowe)\n",
"* VMware ESXi \n",
"* Microsoft Hyper-V\n",
"* Xen\n",
"* QNX Hypervisor\n",
"* Oracle VM Server"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Infrastruktura jako usługa\n",
"\n",
"Kolejnym naturalnym krokiem w ewolucji jest powierzenie odpowiedzialności za zarządzanie środowiskiem wirtualizacji wyspecjalizowanej firmie. Tak samo jak przy kolokacji, usługodawca bierze pełną odpowiedzialność za budynki, prąd, sieć. Ponadto, w modelu IaaS usługodawca jest odpowiedzialny za sprzęt oraz środowisko wirtualizacji na nim zainstalowane. Użytkownik uzyskuje dostęp do gotowych i skonfigurowanych maszyn wirtualnych. Nie ma natomiast dostępu do rzeczywistych zasobów sprzętowych, a do ich wirtualnych odpowiedników. W ten sposób dostawca usługi ma pełną dowolność przy doborze i organizacji zasobów fizycznych.\n",
"\n",
"Zasoby obliczeniowe reprezentowane są przez wirtualne rdzenie (vCPU), sieć i urządzenia IO za pomocą wirtualnych odpowiedników. Dyski często sprzedawane są jako osobna, niezależna od zasobów obliczeniowych (maszyn wirtualnych) usługa. Wirtualne procesory (vCPU) mogą nie mieć pokrycia w rzeczywistych rdzeniach procesora. Jest to częsta praktyka (ang. overprovinsioning). Wielu dostawców za odpowiednią dopłatą jest w stanie zagwarantować dedykowane rdzenie. Niemalże wszystkie zasoby chmurowe mogą być w pewnym stopniu alokowane bez pokrycia. Wyjątek stanowi pamięć operacyjna, która jest głównym ogranicznikiem liczby maszyn wirtualnych per serwer.\n",
"\n",
"Całkowite wyabstrachowanie zasobów obliczeniowych od sprzętu, jest **główną cechą charakterystyczną chmury obliczeniowej**. Nasze oprogramowanie działa korzystając z wirtualnych zasobów, co do których lokalizacji (a nawet istnienia) nie jest pewne.\n",
"\n",
"Drugą kluczową cechą rozwiązań typu IaaS jest swoboda alokacji zasobów. Zasoby można alokować niemal natychmiastowo, czas oczekiwania na stworzenie maszyny wirtualnej u wielu dostawców to mniej niż minuta. Tak samo szybko zasoby mogą zostać zwolnione. Takie podejście nie miało by sensu gdyby nie odpowiedni sposób naliczania opłat. W przypadku infrastruktury na miejscu, duży koszt ponoszony był na początku. Do tego należy doliczyć miesięczne koszty utrzymania. Aby taka inwesytcja mogła się spłacić musiało minąć wiele lat. W przypadku kolokacji jest bardzo podobnie, z tą różnicą że umowy kolokacyjne zawiera się na okres od kilku miesięcy do kilku lat. **Zasoby w modelu IaaS opłaca się w modelu *pay-as-you-go*** czyli zgodnie ze zużyciem, a najpowszechniej stosowaną jednostką rozliczeniową są sekundy lub godziny korzystania z zasobów. W ten sposób możliwe stało się bardzo dokładne dopasowanie zasobów do potrzeb.\n",
"\n",
"Jednak alokacja zasobów w sekudowych odstępach wymaga automatyzacji. I to jest **druga kluczowa cecha infrastruktury chmurowej typu IaaS**. Zasoby (maszyny wirtualne, dyski) można alokować natychmiastowo, tanio i przede wszystkim automatycznie. Zdecydowana większość usługodawców IaaS, udostępnia webowe API dostępowe pozwalające automatyzować zarządzanie infrastrukturą. Często też dostępne są biblioteki programistyczne dla poszczególnych języków programowania. Niektórzy dostawcy mają też w swoim portfolio wyspecjalizowane usługi automatycznego zarządzania infrastrukturą w zależności od potrzeb.\n",
"\n",
"### Wady i zalety\n",
"\n",
"1. **Koszt**\n",
" W przypadku rozwiązań w modelu IaaS, brak jest kosztów początkowych. Większość usługodawców oferuje również darmowy dostęp do podstawowych usług w ramach okresu próbnego. Całość kosztów ponoszona jest w trakcie eksploatacji systemu. Ponadto ponoszone koszty są zależne od ilości zużytych zasobów.\n",
"\n",
" Należy jednak mieć na uwadze, że w przypadku dużego i stałego zapotrzebowania na zasoby obliczeniowe może okazać się, że korzystniej jest wynająć/kupić dedykowany serwer niż korzystać z maszyn wirtualnych w modelu IaaS. Wynajmowanie 12 maszyn wirtualnych po 2 vCPU każda, przez okres 2 lat z pewnością będzie znacznie droższe od zakupu/wynajęcia serwera o takich samych paremetrach. Problem ten jest szczególnie widoczny przy wynajmowaniu maszyn wirtualnych o większej ilości zasobów w modelu IaaS.\n",
"\n",
"1. **Utrzymanie**\n",
" Korzystając z zasobów w modelu IaaS, jesteśmy odpowiedzialni za system operacyjny i oprogramowanie zainstalowane na naszej maszynie wirtualnej. Zarządzanie sprzętem oraz oprogramowaniem *hypervisora* jest obowiązkiem dostawcy usługi.\n",
"\n",
"1. **Skalowanie**\n",
" W tym modelu infrastruktury dostępne jest zarówno pełne skalowanie horyzontalne jak i wertykalne. Ważne jest to, że z punktu widzenia użytkownika nie istnieje górny limit dostępności zasobów. Można alokować dowolnie wiele maszyn bez konieczności rozbudowy infrastruktury. W przypadku skalowania wertykalnego ograniczeni jesteśmy natomiast ofertą usługodawcy (niewielu dostawców oferuje maszyny o więcej niż 32 vCPU) i dostępnością sprzętu (często największe maszyny są nie dostępne). Należy jednak pamiętać, że wielu dostawców ustawia początkowe limity dostępnych zasobów, które można znieść przechodząc dodatkową weryfikację.\n",
"\n",
" Dzieki rozliczaniu sekundowemu/godzinowemu i łatwości skalowania zasobów, poprawnie wdrożona w modelu IaaS aplikacja powinna zawsze obejmować mechanizm automatycznego skalowania przynajmniej kluczowej infrastruktury. Poniższy diagram przedstawia możliwe zachowanie systemu wobec nagłego wzrostu obciążenia systemu: bez skalowania, przy skalowaniu horyzontalnym i wertykalnym.\n",
"\n",
" ![Diagram przedstawia proces skalowania w odniesieniu do stałej alokacji zasobów w modelu własnej infrasturktury. Z czasem obciążenie systemu rośnie, co dzięki skalowaniu znajduje odzwierciedlenie w ilości zasobów obsługujących użytkowników. W skalowaniu horyzontalnym tworzone są kolejne (małe) maszyny wirtualne obsługujące nowe żądania. W skalowaniu wertykalnym całe obciążenie obsługiwane jest przez jedną maszyną, która dysponuje coraz to większymi zasobami.](obrazy/skalowanie.png)\n",
"\n",
" Przy braku skalowania można zauważyć dwa problemy. Po pierwsze przed nagłym wzrostem obciążenia spora część zasobów nie była wykorzystywana. Szacując wymaganą infrastrukturę na poziomie średniego obciążenia, praktycznie nie da się uniknąć takiej sytuacji. Ponadto, przy szczytowym obciążeniu system nie był wstanie obsłużyć wszystkich użytkowników, bez skalowania zwiększenie ilości zasobów nie jest możliwe. Rozwiązaniem tego problemu jest **skalowanie horyzontalne**, które zamiast jednego dużego serwera, korzysta z wielu małych i łatwych w tworzeniu maszyn wirtualnych. W tym podejściu liczba maszyn obsługujących użytkowników może rosnąć nieograniczenie zgodnie z zapotrzebowaniem. Nowe maszyny tworzą się szybko, dlatego możliwe jest natychmiastowe reagowanie na zmiany obciążenia. Do głównych wad skalowania horyzontalnego należy fakt, że nie wszystkie aplikację wspierają ten sposób skalowania. Stąd ważne jest aby już na etapie projektowania systemu myśleć o skalowaniu. \n",
"\n",
" Ostatni wariant to **skalowanie wertykalne**, w którym obciążenie obsługiwane jest przez pojedynczą maszynę wirtualną, która może w razie potrzeby dynamicznie zmieniać swoje parametry. Większość rozwiązań do wirtualizacji pozwala w pewnym stopniu dynamicznie dodawać pamięć, procesory i dyski do systemu. W przypadku usług chmurowych jest to jednak naczęściej realizowane poprzez powrótne utworzenie maszyny (szczególnie gdy skalujemy system w dół). Powoduje to większe opóźnienie w czasie reakcji, przy nagłym wzroście w obciążeniu zaalokowanych zasobów jest za mało, podczas gdy przy spadkach jest ich zbyt dużo.\n",
"\n",
" > **Uwaga**: W praktyce ustawianie nieograniczonego automatycznego skalowania nie jest rozsądne. Ataki DDoS są dość powszechne, a jest wysoce prawdopodobne, że infrastruktura dostawcy da radę obsłużyć cały atak bez problemów. Choć może się to wydawać korzystne, należy pamiętać o kosztach. W przypadku ataku typu DDoS, bardziej opłacalne może być wyłączenie części serwisu na kilka minut, a nawet godzin niż przyjęcie całego ruchu sieciowego i zapłacenie za zasoby niezbędne aby to zrobić.\n",
"\n",
"1. **Bezpieczeństwo**\n",
" Poziom bezpieczeństwa infrastruktury IaaS jest porównywalny do tego oferowanego przez samodzielnie wdrożoną wirtualizację. Z jednej strony zasoby sprzętowe wspóldzielone są przez nieznanych, potencjalnie złośliwych użytkowników, co sprzyja wykorzystaniu błędów w oprogramowaniu do wirtualizacji i sprzęcie. Z drugiej infrastruktura jest zarządzana przez wyspecjalizowanych ekspertów dziedzinowych, co sprzyja wyższemu poziomowi zabezpieczeń, lepszym i częstszym aktualizacjom.\n",
"\n",
" W modelu IaaS najczęsciej nie mamy możliwości sprawdzenia czy dwie różne maszyny wirtualne znajdują się na tym samym serwerze czy nie. Identyczny problem dotyczy zasobów dyskowych. W celu zapewnienia pełnej redundancji i odporności na zdarzenia losowe zaleca się umieszczenie krytycznej infrastruktury w różnych regionach (lokacjach). Wielu usługodawców pozwala wybrać przybliżoną fizyczną lokalizację tworzonych zasobów np. na poziomie miasta/państwa/rejonu geograficznego. W ten sposób możemy mieć gwarację, że zasoby są fizycznie od siebie odseparowane.\n",
"\n",
"\n",
"### Przykłady\n",
"\n",
"Usługodawców IaaS jest bardzo wielu, do najważniejszych należy zaliczyć:\n",
"* Amazon Web Services\n",
"* Microsoft Azure\n",
"* Google Cloud\n",
"* Oracle Cloud\n",
"* IBM Cloud\n",
"* OVH\n",
"* Linode\n",
"* Hetzner\n",
"* Alibaba\n",
"* Digital Ocean\n",
"\n",
"### Koszt\n",
"\n",
"Dla porównywalności z poprzednim przykładem oszacowany zostanie koszt wynajęcia maszyny wirtualnej o następujących parametrach: 16 vCPU, 128GB RAM, 4TB SSD. Koszty są bardzo różne w zależności od dostawcy. Wielu dostawców nie oferuje też tak dużych maszyn. Miesięczny koszt zasobów obliczeniowych należy szacować na poziomie od 300 zł (Hetzner) przez 1500 zł (AWS) do nawet 2500 zł (Linode). Do tego należy obowiązkowo doliczyć opłaty za przechowywane dane w wysokości 1000-1200 zł miesięcznie za 4 TB danych.\n",
"\n",
"Powyższa kalkulacja może się okazać zaskakująca, rozwiązanie chmurowe jest aż 2-5 razy droższe niż kolokacja. Konieczne jest wyjaśnienie skąd wynika ta różnica i dlaczego mimo to rozwiązania chmurowe pozwalają redukować koszty.\n",
"\n",
"Pierwszym i chyba najważniejszym problemem jest typ porównywanej infrastruktury. Pojedynczy serwer o uniwersalnych parametrach (dużo rdzeni, pamięci RAM, dysków) dobrze się sprawdza w kolokacji, podczas gdy usługi chmurowe buduje się najczęściej z wielu małych zasobów. W przypadku wielu usług chmurowych cena maszyny wirtualnej nie rośnie proporcjonalnie do liczby rdzeni/pamięci RAM. Przykładowo dla usługi AWS EC2 i maszyn wirtualnych typu t3 ceny w USD wyglądają następująco\n",
"\n",
"| liczba rdzeni | ilość pamięci | cena za godz. | cena za rdzeń | cena za GB RAM|\n",
"| --- | --- | --- | --- | --- |\n",
"| 2 | 0.5 | 0.0052 | 0.0026 | 0.0104 |\n",
"| 2 | 1 | 0.0104 | 0.0052 | 0.0104 |\n",
"| 2 | 2 | 0.0208 | 0.0104 | 0.0104 |\n",
"| 2 | 4 | 0.0416 | 0.0208 | 0.0104 |\n",
"| 2 | 8 | 0.0832 | 0.0416 | 0.0104 |\n",
"| 4 | 16 | 0.1664 | 0.0416 | 0.0104 |\n",
"| 8 | 32 | 0.3328 | 0.0416 | 0.0104 |\n",
"\n",
"Drugi problem z przedstawionym porównaniem dotyczy dysków. Kupując serwer często wyposaża sie go w duże dyski, aby uniknąć późniejszej ingerencji w sprzęt. Użyte 4TB są z pewnością przeszacowane. W przypadku własnego serwera jest to jedyna możliwość przechowywania danych. W przypadku usług chmurowych ponownie mamy doczynienia z innych charakterem zasobów. Dyski przyłączane do maszyny wirtualnej (ang. block storage) są zasobami dość kosztownymi, a ich wysoka cena wynika z ograniczeń technicznych (taki zasób może być tylko częściowo współdzielony). Natomiast usługodawcy oferują również tańsze usługi przechowywania danych opprujące na plikach (ang. object storage). \n",
"\n",
"Jest wysoce prawdopodobne, że z oszcowanych 4TB, zaledwie 200GB musi być przechowywane na wirtualnych urządzeniach blokowych (są to głównie system operacyjny, oprogramowanie i bazy danych) podczas gdy pozostałe 3.8TB to dane, które można przechowywać obiektowo (zdjęcia, filmy, archiwa, dowolne samodzielne pliki). Przy takim założeniu koszt przechowania 4TB danych spadnie do 50-400 zł miesięcznie. Dalszą redukcję oszacowanych kosztów można osiągnąć uwzględniajać fakt, że najprawdopodobniej ilość przechowywanych w systemie danych będzie rosła w czasie.\n",
"\n",
"Ostatnim aspektem tego porównania, który należy omówić jest przeszacownanie infrastruktury. Jeśli rzeczywiście nasz system będzie przez zdecydowaną większość czasu potrzebował wszystkich zasobów (np. duże bazy danych, systemy czasu rzeczywistego o stałym obciążeniu) to z pewnością rozwiązania chmurowe nie są optymalne finansowo. Dla większości systemów nie jest to jednak prawdą, a obciążenia zasobów zmiania się w czasie. Załóżmy, że nasz serwer wykorzystuje całość swoich zasobów przez 2 miesiące w roku, przez 4 wykorzystuje połowe, a przez pozostałe 6 tylko czwartą ich część. Oszacujmy teraz koszt wymaganej infrastruktury zakładając wdrożenie wskalowania wertykalnego (skalowanie horyzontalne pozwoliło by pewnie jeszcze bardziej ograniczyć koszty). Przy takim obciążeniu koszt maszyn wirtualnych to 150-650 zł miesięcznie + koszt przechowywania danych 50-400 zł miesięcznie.\n",
"\n",
"Porównując z kolokacją koszt jest teraz nawet niższy. Należy jednak pamiętać, oba oszacownia dotyczą zupełnie innej infrastruktury, choć realizującej zapotrzebowanie tego samego (fikcyjnego) systemu informatycznego."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Rekomendowana literatura uzupełniająca\n",
"[TOUR]: Hetzner Online GmbH. [Virtual tour of Hetzner Online date center park.](https://www.hetzner.com/unternehmen/360-tour/). online 2021.\n",
"\n"
]
}
],
"metadata": {
"interpreter": {
"hash": "98b0a9b7b4eaaa670588a142fd0a9b87eaafe866f1db4228be72b4211d12040f"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

366
03_IaaS/03_02.ipynb Normal file
View File

@ -0,0 +1,366 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Anatomia zasobów w modelu IaaS\n",
"\n",
"Do tej pory w materiałach na temat modelu IaaS uwaga poświęcona była przede wszystkim maszynom wirtualnym. Oczywiście stanowią one główny zasób obliczeniowy, jednak ich możliwości były by ograniczone gdyby nie usługi dodatkowe skojarzone z nimi.\n",
"\n",
"> **Uwaga**: Nie wszyscy dostawcy IaaS oferują ten sam zakres usług towarzyszących. Do najczęsciej oferowanych należą zasoby dyskowe, kopie zapasowe oraz migawki.\n",
"\n",
"Niniejsza część materiałów zostanie poświęcona szczegółowemu omówieniu najczęściej spotykanych usług towarzyszących tj. \n",
"- zasobów dyskowych\n",
"- sieci prywatnych i *pływających* adresów IP\n",
"- mechanizu równoważenia obciążenia\n",
"- kopiom zapasowym i migawkom\n",
"- zaporom sieciowym"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Maszyny wirtualne\n",
"\n",
"Jak już wspomniano w poprzedniej części materiałów, maszyny wirtualne są kluczowym elementem IaaS. Zapewniają zasoby obliczeniowe, umożliwiając w ten sposób przetwarzanie danych użytkowniaka i tych pochodzących z systemów zewnętrznych. \n",
"\n",
"### Opis \n",
"\n",
"Pojęcie wirtualizacji jest bardzo szerokie, pokrywające wiele technik budowy maszyn wirtualnych. Pierwsze próby wykorzystania wirtualizacji miały na celu zwiększenie wykorzystania procesora. W latach 60-tych XX wieku firma IBM korzystając z tech techniki pozwoliła na uruchomienie na serwerze typu *mainframe* wielu kopii tego samego systemu operacyjnego co w efekcie pozwalało na wykorzystanie tej samej fizycznej maszyny przez wielu użytkowników jednocześnie [IBM].\n",
"\n",
"![Diagram przedstawia wizializajcę pojedynczej maszyny wirtualnej chmurze typu IaaS.](obrazy/zasoby-vm.png)\n",
"\n",
"Możemy w wyróżnić następujące typy wirtualizacji:\n",
"- **Pełna wirtualizacja**: nadzorca (oprogramowanie wirtualizacyjne, ang. hypervisor) dostarcza pełne środowisko wirtualne, w którym wirtualizowany system operacyjny (gość, ang. Guest) ma wrażenie, że działa na prawdziwym, fizycznym sprzęcie. W rzeczywistości wszystkie wywołania są przechwytywane przez oprogramowanie i emulowane z wykorzystaniem dostępnego sprzętu. Rozwiązanie te jest najmniej efektywnym typem wirtualizacji ze względu na duży narzut obliczeniowy. Jego główna zaleta to możliwość emulowania środowiska innego niż fizycznie dostępne (np. urządzenia mobilnego na komputerze PC).\n",
"\n",
"- **Wspierana sprzętowo pełna wirtualizacja**: w celu zmniejszenia narzutu obliczeniowego na wirtualizację, część kosztownych operacji dzięki wsparciu sprzętowemu wykonywana jest bezpośrednio na sprzęcie fizycznym. Przykładami takich technologii są Intel VT-x i AMD-V, które są obecnie obsługiwane przez wszystkie większe systemy do wirtualizacji. Kosztem tego rozwiążania jest nieznaczne zmniejszenie bezpieczeństwa oraz utrudniona wirtualizacja innego środowiska niż dostępne fizycznie.\n",
"\n",
"- **Parawirtualiacja**: w tym przypadku system operacyjny gościa musi zostać zaadaptowany do pracy w środowisku wirtualnym, jest zatem świadomy faktu, że pracuje w środowisku wirtualnym. Dzięki temu możliwe jest bardziej efektywne wykorzystanie zasobów i znacznie zmniejszenie narzutu obliczeniowego na wirtualizację. Do przykładów technologii wspierających parawirtualizację należy [VirtIO](https://www.linux-kvm.org/page/Virtio) umożliwiające efektywny dostęp rzeczywistych urządzeń blokowych (dyski), kart sieciowych, a nawet kart graficznych. Wszystkie współczesne systemy operacyjne oparte na jądrze Linux wspierają natwynie VirtIO.\n",
"\n",
"- **Wirtualizacja na poziomie systemu operacyjnego**: często nazywana też konteneryzacją. Pozwala na uruchomienie wielu zwritualizowanych instancji na jednym komputerze, jednak w odróżnieniu od poprzednich rozwiązań, system operacyjny (a tak włąściwie jego jądro) jest współdzielony. Do zapewnienia separacji wykorzystywane są odpowiednie mechanizmy jądra systemu operacyjnego np. `chroot`, `cgroups`, `kernel namespaces`.\n",
"\n",
"W rzeczywistych systemach wirtualizacji techniki te są często łączone. Przy zasobach typu IaaS zawsze oferowana jest pełna wirtualizacja, najczęściej wspierana sprzętowo przez procesor, oraz korzystająca z mechanizmu parawirtualziacji dla dysków i sieci. Z punktu widzenia użytkownika zasobów IaaS, nie jest bardzo istotne jak zorganizowane są udostępniane zasoby.\n",
"\n",
"> **Wskazówka**: Jak odróżnić pełną maszynę wirtualną od środowiska oferowanego w ramach wirtualizacji na poziomie systemu operacyjnego? Najpewniejszym sposobem będzie próba zmiany konfiguracji jądra systemu operacyjnego. W przypadku konteneryzacji nie powinno być to możliwe, gdyż jądro jest współdzielone pomiędzy wszystkie instancje.\n",
"\n",
"### Kluczowe cechy\n",
"\n",
"Maszyny wirtualne charakretuzyją przede wszystkim wirtualne rdzenie (vCPU), pamięć operacyjna RAM, wirtualna sieć i urządzenia IO. Ponadto dyski często sprzedawane są jako osobna, niezależna od maszyn wirtualnych usługa. Wirtualne procesory (vCPU) mogą nie mieć pokrycia w rzeczywistych rdzeniach procesora. Jest to częsta praktyka (ang. overprovinsioning). Wielu dostawców za odpowiednią dopłatą jest wstanie zagwarantować pełne pokrycie rdzeni (tzw. dedicated cores/vCPU). Niemalże wszystkie zasoby chmurowe mogą być w pewnym stopniu alokowane bez pokrycia. Wyjątek stanowi pamięć operacyjna, która jest głównym ogranicznikiem liczby maszyn wirtualnych per serwer. Obecnie jako standardową platformę usług IaaS przyjmuje się procesor typu x64, pamięc RAM z ECC oraz dyski SSD w konfiguracji RAID. Jednakże, choć nadal niszowe, zasoby obliczeniowe oparte na architekturze ARM zyskują coraz większą popularność, głównie ze względu na ich niski koszt.\n",
"\n",
"Niektórzy dostawcy mają w swojej ofercie specjalistyczne maszyny wirtualne wyposażone w karty graficzne czy specjalistyczne układy obliczeniowe. Są one najczęściej wykorzystywane w przetwarzaniu graficznym oraz w uczeniu maszynowym.\n",
"\n",
"\n",
"### Sposób wykorzystania\n",
"\n",
"Maszyny witualne są uniwersalne, gdyż można na nich instalować dowolne oprogramowanie. Do najczęstrszych zastosowań tych zasobów należy zaliczyć:\n",
"- serwery webowe (Apache, Nginx) i aplikacyjne (JBoss, Tomcat, Node.js)\n",
"- bazy danych (PostgreSQL, MySql)\n",
"- obliczenia rozproszone \n",
"- bramy sieciowe, serwery proxy, firewalle\n",
"\n",
"### Dostępne usługi i ich koszt\n",
"\n",
"Poniższa tabela przedstawia miesieczny koszt używania maszyny wirtualnej oferującej 2 vCPU oraz 2GB RAM u różnych dostawców. Jest to jeden z najczęściej alokowanych typów zasobów chmurowych. W przypadku gdy dany dostawca ma w ofercie wiele takich maszyn, przyjęto tę z najpopularniejszej lini produktowej, naliczanie *on-demand* oraz współdzielone zasoby.\n",
"\n",
"W kalkulacjach przyjęto następujące kursy walut:\n",
"- 1 EUR = 4.5 PLN\n",
"- 1 USD = 3.8 PLN\n",
"\n",
"| Dostawca | Nazwa | Koszt | Uwagi |\n",
"| --- | --- | --- | ---- |\n",
"| Alibaba | ecs.t6-c1m1.large | 45.83 | 4GB RAM + 20GB SSD|\n",
"| AWS | t3.small | 56.90 | |\n",
"| Azure | B2S | 115.20 | 4GB RAM + 8GB SSD |\n",
"| Google Cloud Engine | e2-highcpu-2 | 137.21 |\n",
"| Hetzner | CPX11 | 18.00 | +40GB SSD |\n",
"| Linode | | 76.00 | 4GB RAM + 80GB SSD |\n",
"| OVH | d2-4 | 47.53 | 4GB RAM + 50GB SSD |\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Zasoby dyskowe\n",
"\n",
"W bardzo wielu zastosowaniach niezbędne jest przechowywanie danych. W zależności od potrzeb dostępne są różne rodzaje zasobów dyskowych. \n",
"\n",
"### Opis\n",
"\n",
"Jak już zostało wspomniane zasoby dyskowe bardzo często sprzedawane są jako osobna usługa. Dzięki temu dyski mogą być tworzone i zarządzane niezależnie od maszyn wirtualnych. Przyłączenie dysku do maszyny powoduje, że jest on dostępny dla niej na wyłączność (dysk może być podłączony naraz tylko do jednej maszyny). Możliwe jest jednak odłączenie dysku i podłączenie go do innej maszyny (wielu dostawców umożliwia przełączanie dysków bez potrzeby restartu maszyny).\n",
"\n",
"![Diagram przedstawia wizializajcę pojedynczej maszyny wirtualnej chmurze typu IaaS z dołączonym zasobem dyskowym.](obrazy/zasoby-dysk.png)\n",
"\n",
"### Kluczowe cechy\n",
"\n",
"Zasoby dyskowe można scharakteryzować następującymi parametrami:\n",
"- **pojemność**: najważniejszy parametr opisujący ilość danych, które można zapisać (mierzona w GB lub TB).\n",
"- **prędkość zapisu/odczytu**: informuje o ilości danych jakie będzie można odczytać/zapisać z/na dysku w jednostce czasu (mierzona w MB/s).\n",
"- **ilość operacji na sekundę (IOPS)**: informuje o ilości niezależnych operacji zapisu/odczytu jakie można wykonać w jednostce czasu. W ten sposób można określić jaki będzie czas odpowiedzi zasobu na żadanie i ile żądań będzie można obsłużyć jednocześnie (mierzona w operacjach na sekundę, IOPS).\n",
"- **stopień redundancji**: informuje w ilu kopiach dane są przechowywane i w jaki sposób są one rozmieszczone fizycznie (ten sam serwer, czy inny, ta sama serwerownia czy nie).\n",
"\n",
"Ważne jest zrozumienie różnic pomiędzy poszczególnymi typami zasobów dyskowych:\n",
"\n",
"- **dyski lokalne w konfiguracji RAID** (ang. local storage): w ofercie znajdują się zarówno dyski HDD (coraz rzadziej) jak i SSD. Takie rozwiązania oznacza, że zasób dyskowy przyłączony do naszej maszyny wirtualnej znajduje się fizycznie w tym samym serwerze co nasza maszyna wirtualna. Takie dyski najczęściej udostępniane są za pośrednictwem parawirtualizacji (VirtIO) i oferują wysoką wydajność zarówno pod względem prędkości zapisu/odczytu (GB/s) jak i ilości operacji na sekundę (IOPS). Przydatne szczególnie dla zastosowań, w których potrzeba niskiego opóźnienia dostępu do dysku np. bazach danych.\n",
"- **dyski sieciowe** (ang. network storage): tutaj nadal popularne są dyski twarde (HDD). Dostęp do zasobu odbywa się poprzez sieć dostawcy, co znacznie ogranicza skorzystanie z benefitów szybkich dysków SSD. O ile prędkość zapisu/odczytu nie musibyć drastycznie niższa od dysków lokalnych, o tyle ilość operacji na sekunde (IOPS) może być nawet o kilka rzędów wielkości niższa (choć wcale nie musi). W zamian za to dyski sieciowe oferują znacznie większą redundancję danych, dane mogą być przechowywane w wielu kopiach nawet w różnych lokalizacjach geograficznych. Przydatne szczególnie do przechowywania danych wymagających wysokiej dostępności. Dyski takie mogą być przyłączane do maszyny wirtualej jako udziały sieciowe (np. CIFS) lub jako dyski lokalne (np. iSCSI). Rozwiązanie to obecnie dominuje na rynku.\n",
"\n",
"\n",
"> **Uwaga** Dostępne są też dyski obiektowe (ang. object storage). Nie można na nich zainstalować systemu operacyjnego ani uruchomić bazy danych. Nadają się jednak doskonale do przechowywania dużych ilości plików (obiektów), które rzadko się zmieniają (zmiana nawet części pliku wymaga nadpisania całości). Zostaną one omówione w module poświęconym modelowi SaaS chmury obliczeniowej.\n",
"\n",
"### Sposób wykorzystania\n",
"\n",
"Każda maszyna wirtualna potrzebuje przynajmniej jednego zasobu dyskowego, tego na którym zainstalowany zostanie system operacyjny i wymagane oprogramowanie. Jak zostanie to opisane w dalszej części materiałów, instalacja systemu, oprogramowanie i ich konfuguracja bardzo często jest wpełni zautomatyzowana, a co za tym idzie dysk ten nie jest kluczowym zasobem. W bardzo wielu przypadkach wystarcza pojemność rzędu 8-20GB.\n",
"\n",
"Jeśli maszyna wirtualna potrzebuje zapisywać jakieś dane, które mają być przechowywane długoterminowo rekomendowane jest dołącznie do niej osobnego zasobu dyskowego. W ten sposób będzie można łatwo przenieść dane pomiędzy maszynami. Ułatwia to też zarządzanie kopią zapasową i migawkami.\n",
"\n",
"> **Uwaga**: Należy też zaznaczyć, że niektórzy dostawcy (np. AWS) nie oferują żadnych zasobów dyskowych w standardzie. W takim przypadku warto zaalokować 2 osobne zasoby, tak aby jeden zawierał system i oprogramowanie (czyli część specyficzną dla danej maszyny, która nie będzie przełączana) oraz a drugi zawierał przechowywane dane (które można będzie łatwo przenieść pomiędzy maszynami).\n",
"\n",
"Większość dostawców pozwala, dowolnie zmieniać rozmiar zasobów dyskowych (często bez konieczności restartu maszyny wirtualnej). Mimo wszystko zmiana rozmiaru dysku nie jest łatwa i automatyczna. Trudność to wynika z konieczności zmiany rozmiaru systemu pliku. Samo zmniejszenie/zwiększenie dostępnej przestrzeni dyskowej nie wystarczy aby system operacyjny zauważył tę zmianę. Konieczne jest ręczne dopasowanie systemu plików do nowych warunków. Jest to proces podencjalnie niebezpieczny i czasochłonny, który może się wiązać z przerwą w dostępności do systemu, a nawet utratą danych (szczególnie w przypadku zmniejszaniu systemu plików).\n",
"\n",
"### Dostępne usługi i ich koszt\n",
"\n",
"Zasoby dyskowe nie są usługą, która można wykorzystać poza maszyną wirtualną u danego dostawcy. Stąd wybierając dostawcę należy jednocześnie uwzględnić oferowane zasoby dyskowe i ich parametry (w tym cenę). W poniższej tabeli zebrano informacje o zasobach dyskowych oferowanych przez dostawców. Koszt podany jest za miesiąc w przeliczeniu na 1GB.\n",
"\n",
"| Dostawca | Typ | Koszt | Uwagi |\n",
"| --- | --- | --- | --- |\n",
"| Alibaba | oba, SSD | 0.22 | każda maszyna wirtualna posiada dysk lokalny w standardzie |\n",
"| Azure | sieciowe, SSD | 0.29 | każda maszyna wirtualna posiada dysk lokalny w standardzie |\n",
"| AWS | sieciowe, SSD | 0.38 | dyski lokalne dostępne tylko dla wybranych typów maszyn wirtualnych |\n",
"| Google Cloud | sieciowe, HDD | 0.15 | |\n",
"| Google Cloud | sieciowe, SSD | 0.64 | |\n",
"| Google Cloud | lokalne, SSD | 0.30 | zasoby dostępne tylko w jednostkach po 375GB |\n",
"| Hetzner | sieciowe, SSD | 0.18 | każda maszyna wirtualna posiada dysk lokalny w standardzie |\n",
"| Linode | sieciowe, SSD | 0.38 | każda maszyna wirtualna posiada dysk lokalny w standardzie |\n",
"| OVH | sieciowe, SSD | 0.17 | każda maszyna wirtualna posiada dysk lokalny w standardzie |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Wirtualne sieci prywatne\n",
"\n",
"Budując systemy informatycze, często wyróżniamy w nich niezależne komponenty (np. główna aplikacja i baza danych). Wdrażając aplikację w modelu IaaS warto każdy z komponentów umieścić na osobnej maszynie wirtualnej. Konieczny jest zatem mechanizm komunikacji pomiędzy komponentami. Standardowo każda maszyna wirtualna dysponuje publicznym adresem IP, który oczywiście można wykorzystać do takiej komunikacji. Niestety rozwiązanie takie wymaga odpowiedniej konfiguracji i zabezpieczenia udostępnianych usług. Udostępnienie publicznego dostępu do np. bazy danych systemu, nigdy nie jest dobrym rozwiązaniem. Odpowiedzią na ten problem są wirtualne sieci prywatne.\n",
"\n",
"### Opis\n",
"\n",
"Witrualna sieć prywatna dysponuje własną pulą adresów IP, najczęściej jako podzbiór zakresu `10.0.0.0/8` (np. `10.10.10.0/24`). Maszyny wirtualne mogą zostać dodane do tej sieci, dzięki czemu otrzymają adresy prywatne z jej puli, które następnie mogą wykorzystać do komunikacji wewnętrznej. Technicznie taka sieć jest bytem w pełni wirtualnym, nie istnieje fizycznie. Dane przekazywane są tymi samymi kanałami i z wykorzystaniem tego samego sprzętu co w przypadku komunikacji publicznej pomiędzy tymi samymi maszynami wirtualnymi. Jednak dodanie warstwy logicznej (wirtualnej) separacji zasobów znacznie upraszcza jej strukturę. Ponieważ sieć prywatna nie jest dostępna na zewnątrz ani dla innych klientów dostawcy usług chmurowych, można znacznie uprościć konfigurację i zabezpieczenie komponentów zlokalizowanych w tej sieci.\n",
"\n",
"> **Wskazówka**: Zapis `10.10.10.0/24` to tak zwana notacja CIDR. Pozwala ona dokładnie zdefiniować pulę adresów dostępnych w sieci. Pierwsza część `10.10.10.0` określa bazowy adres IP. Druga część `24` określa maskę podsieci, informując o tym ile pierwszych bitów adresu IP wskazuje adres podsieci. Pozostałe `32-24=8` bity używane są do adresacji hostów w sieci (w tym przypadku dostępne jest 256 adresów IP). Zapis `10.10.10.0/24` oznacza, że adres podsieci to 10.10.10.0, a maska podsieci to 255.255.255.0 co w praktyce oznacza pulę adresów `10.10.10.0 - 10.10.10.255`.\n",
"\n",
"> **Uwaga**: Termin wirtualna sieć prywatna (ang. virtual private network, VPN) może być mylący, ze względu na wiele alternatywnych znaczeń. Termin VPN najczęściej wykorzystywany jest w kontekście tunelowania prywatnego ruchu sieciowego (np. dostępu do wewnętrznych zasobów przedsiębiorstwa) przez publiczną sieć (np. Internet). Ostatnio popularne stało się też użycie terminu VPN w kontekście anonimizacji komunikacji sieciowej.\n",
"\n",
"![Diagram przedstawia logiczny podział sieci komputerowej u dostawcy usługi IaaS. Zaznaczono pulę publicznych adresów IP, do których przyłączone są maszyny wirtualne. Ponadto zaznaczono wirtualne sieci prywatne, w ramach których obowiązuje oddzielna adresacja IP. Maszyny wirtualne mogą być przypisane do dowolnej kompinacji publicznch i prywatnych adresów IP.](obrazy/zasoby-siec.png)\n",
"\n",
"Z koncepcją prywatnej sieci wirtualnej łączy się też pojęcie *pływających adresów IP* (ang. floating IP). Tworząc nową maszynę wirtualną z dostępem do sieci publicznej (co jest najczęsciej opcją domyślną), każdorazowo przydzielany jest jej losowy adres IP z dostępnej puli. W niektórych zastosowaniach częste zmienianie adresu IP nie jest dopuszczalne. Przykładowo serwer WWW powinien mieć stały adres IP ze względu na duże opóźnienia w propagacji wpisów DNS. W takiej sytuacji można skorzystać z *pływającego adresu IP*, który może być przypisany do dowolnej maszyny wirtualnej. Takie przypisanie można też dowolnie modyfikować, z niemalże natychmiastowym efektem. Pozwala to zachować stały adres IP, nie ograniczając jednocześnie możliwości zmiany i tworzenia nowych maszyn wirtualnych.\n",
"\n",
"### Sposób wykorzystania\n",
"\n",
"Tworząc system informatyczny, który ma zostać wdrożony w modelu IaaS należy zaprojektować go tak aby kluczowe komponenty mogły znajdować się na osobnych maszynach wirtualnych. Następnie należy dokonać podziału tych komponentów/maszyn wirtualnych na takie, do których niezbędny jest dostęp z zewnątrz (dostarczają usługi dla systemów zewnętrznych i użytkowników) oraz takie, które takiego dostępu nie wymagają. Wszystkie maszyny wirtualne w ramach danego systemu umieszczamy w jednej wirtualnej sieci prywatnej, i tą sięć wykorzystujemy do komunikacji wewnętrznej. Tylko maszyny wirtualne z pierwszej grupy otrzymują publiczne adresy IP. W ten sposób można łączyć prywatną komunikację (np. z bazą danych) z publiczną komunikacją w Internecie (np. z użytkownikami). Ponadto dla każdej maszyny wirtualnej istnieje możliwość określania jakie oprogramowanie nasłuchuje na danym adresie IP, co umożliwia oferowanie publicznych i prywatnych usług w ramach pojedynczej maszyny. Ponadto, jeśli stabilność adresów IP jest istotna, wszystkie publiczne adresy IP powinny być skonfigurowane jako *pływające*.\n",
"\n",
"### Dostępne usługi i ich koszt\n",
"\n",
"U wszystkich znaczących dostawców usługa wirtualnej sieci prywatnej jest darmowa. Ponadto, całość ruchu w tej sieci traktowana jest jako wewnętrzna i nie są za nią naliczane opłaty. *Pływające adresy IP* związane są z kosztem naliczanym najczęściej za każdą godzinę rezerwacji adresu nie zależnie od tego czy taki adres jest w użyciu czy też nie. Koszt tej usługi należy szacować na poziomie 10-15 zł miesięcznie.\n",
"\n",
"Nie ma jednolitej nazwy na ten typ usług. Poniżej podane zostały nazwy usługi sieci wirtualnej i *pływających adresów IP* u różnych dostawców:\n",
"\n",
"| Dostawca | Wirtualna sieć prywatna | Pływajacy adres IP |\n",
"| --- | --- | --- |\n",
"| Alibaba | Virtual Private Cloud (VPC) | Elastic IP |\n",
"| AWS | Virtual Private Cloud (VPC) | Elastic IP |\n",
"| Azure | Azure Virtual Network (VNet) | Statyczny adres IP |\n",
"| Google Cloud | Virtual Private Cloud (VPC) | Static IP |\n",
"| Hetzner | Networks | Floating IP |\n",
"| Linode | Private VLAN | niedostępne |\n",
"| OVH | Private Network | Floating IP |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Zapory sieciowe\n",
"\n",
"Każda maszyna wirtualna może mieć zainstalowaną i skonfigurowaną własną zaporę sieciową. Takie rozwiązanie może jednak prowadzić problemów w zarządzaniu wieloma serwerami jednocześnie. Stąd większość dostawców oferuje możliwość zdefiniowania zapory sieciowej, która umożliwia filtrowanie ruchu sieciowego jeszcze zanim trafi on do maszyny wirtualnej.\n",
"\n",
"### Kluczowe funkcje\n",
"\n",
"Zapora sieciowa zasadniczo definiuje reguły określające jaki ruch sieciowy jest dozwolony, a jaki nie. Każda reguła może określać:\n",
"- typ adresu: IPv4 lub IPv6\n",
"- protokół: TCP, UDP, ICMP i inne\n",
"- źródłowy adres IP\n",
"- docelowy port (lub zakres) w przypadku protokołów TCP i UDP\n",
"\n",
"U niektórych dostawców możliwe jest filtrowanie zarówno ruchu przychodzącego jak i wychodzącego.\n",
"\n",
"### Sposób użycia\n",
"\n",
"Dostawca usługi IaaS pozwala zdefiniować zbiory reguł zapory sieciowej. Taki zbiór może być następnie przypisany do wybranych maszyn wirtualnych. Dzięki temu możliwe jest jednoczesne zarządzanie zaporą sieciową wielu maszyn jednocześnie jak i wspóldzielene ich konfiguracji. Każda maszyna wirtualna z przypisanym publicznym adresem IP powinna zostać objęta zaporą sieciową oferowaną przez dostawcę usługi, ponadto w takim przypadku nie ma już potrzeby definiowania zapory na poziomie systemu operacyjnego chyba, że wymagane jest osiągnięcie niestandardowego zachowania (np. pukanie do portów, ang. port knocking).\n",
"\n",
"Najczęściej domyślnie cały ruch wychodzący jest dozwolony, podczas gdy ruch przychodzący jest zablokowany. Aby umożliwić dostęp z zewnątrz do serwisów oferowanych na danej maszynie wirtualnej należy dodać odpowiednie reguły.\n",
"\n",
"### Dostępne usługi i ich koszt\n",
"\n",
"Usługa zapory sieciowej u większości dostawców jest darmowa. Różne jest jednak nazewnictwo. Należy też zwrócić uwagę, że często w ofercie znajdują się osobne produkty o tej nazwie, które służą jednak innym celom niż te opisane powyżej (są to zapory sieciowe na poziomie sieci a nie pojedynczych maszyn wirtualnych). Poniższa tabela przedstawia nazwy u poszczególnych dostawców:\n",
"\n",
"| Dostawca | Zapora sieciowa |\n",
"| --- | --- |\n",
"| Alibaba | Security group |\n",
"| AWS | Security group |\n",
"| Azure | Security group |\n",
"| Google Cloud | firewall rules |\n",
"| Hetzner | Firewall |\n",
"| Linode | Cloud Firewall |\n",
"| OVH | Network Firewall |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Równoważenie obciążenia\n",
"\n",
"We wcześniejszej części materiałów omówiony został mechanizm skalowania horyzontalnego, polegajacego na zwiększeniu liczby niezależnych maszyn wirtualnych obsługujących żądania. Z drugiej strony użytkownicy systemu z pewnością potrzebują pojedynczego punktu dostępowego. Taki punkt dostępowy najczęściej ma postać adresu URL, domenowego lub IP systemu. Najprostszy mechanizm skalowania horyzontalnego można zrealizować na poziomie wpisów DNS. Protokół DNS umożliwia wskazanie wielu adresów IP dla danej domeny wraz z priorytetami. Takie rozwiązanie jest jednak mało elastyczne, ze wzlgędu na powolną propagację wpisów DNS. Stąd istnieje potrzeba zapewniania bardziej dynamicznego mechanizmu skalowania.\n",
"\n",
"### Opis\n",
"\n",
"**Mechanizm równowarzenia obciążenia** (ang. load balancer) to najczęściej specjalistyczne oprogramowanie dostarczane przez usługodawcę chmury, które jest zoptymalizowane pod kątem przyjmowania dużego ruchu sieciowego i przekazywania go do innych maszyn wirtualnych (węzłów, ang. nodes). Takie rozwiązanie może działać samodzielnie, lub stanowić mechanizm drugiego poziomu razem z równoważeniem opartym na wpisach DNS.\n",
"\n",
"![Diagram przedstawia wirtualna sieć prywatną w której wszystkie maszyny wirtualne posiadają wyłącznie prywatny adres IP. Komunikacja z Internetem odbywa się za pośrednictwem mechanizmu równoważenia obciążenia. Ponadto ruch sieciowy jest filtrowany za pośrednictwem zapory sieciowej.](obrazy/zasoby-lb.png)\n",
"\n",
"### Kluczowe funkcje i cechy\n",
"\n",
"Mechanizm równoważenia obciążenia to wbrew pozorom dość złożone oprogramowanie. Kluczowe jego funkcje i cechy to:\n",
"\n",
"1. **Obsługiwane protokoły**: W rozwiązaniach praktycznych najczęściej zrównoleglanie obciążenia odbywa się na następujących warstwach modelu ISO-OSI: \n",
" - 4 (transmisji) - najbardziej ogólny, pozwala równoważyć dowolne połączenia TCP/UDP. Mechanizm równoważenia obciążenia nie wykorzystuje wiedzy na temat przesyłanych danych.\n",
" - 7 (aplikacji) - najczęściej dotyczy protokołu HTTP, pozwalając na jednokierunkowy, bezstanowy transfer danych. Mechanizm równoważenia obciążenia wykorzystuje wiedzę zawartą w przesyłanych danych, w szczególności może korzystać z nagłówków HTTP, kodów odpowiedzi itp.\n",
"\n",
" W kontekście równoważenia obciązenia kluczowe jest też rozróżnienie pomiędzy stanowymi i bezstanowymi połączeniami. Komunikacja TCP i UDP wymaga utrzymania połączenia przez cały czas trwania komunikacji, która nie jest ograniczona czasowo. W ten sposób serwer zrównoleglający przez cały czas utrzymuje aktywne połączenie co znacznie ogranicza liczbę jednoczesnych połączeń i zwiększa zużycie zasobów.\n",
"\n",
" W przypadku komunikacji HTTP, choć technicznie wykorzystuje ona również protokuł TCP, to połączenie jest zamykane gdy tylko cała odpowiedź na żądanie HTTP zostanie przesłana. Dalsza komunikacja wymaga ponownego nawiązania połączenia. W ten sposób można znacznie bardziej efektywnie utrzymywać bardzo wielu klientów jednocześnie. Pojawia się natomiast inny problem, w przypadku niektórych systemów (np. korzystających ze stanowej sesji użytkownika) konieczne może się okazać, aby kolejne żądania od tego samego klienta obsługiwane były przez ten sam węzeł.\n",
"\n",
"1. **Dostępne strategie zrównoleglania**: Mechanizm zrównoleglania obciążenia dokonuje wyboru, który węzeł obsłuży bieżące żądanie. Wyróżnić można kilka najpopularniejszych strategi:\n",
" - losowy - węzeł wybierany jest losowo\n",
" - round robin - węzły ustawione są w liste, która przechodzona element po elemencie, a w momencie dotarcia na koniec algorytm ponownie przechodzi na początek listy\n",
" - najmniejsza liczba aktywnych połączeń - szczególnie przydatny przy komunikacji TCP\n",
" - obciążenie węzła - w oparciu o wybrane parametry serwera (np. użycie CPU) wybierany jest serwer najmniej obciążony\n",
" - sesyjne - wybierany jest węzeł, który obsługiwał poprzednie żądania z tego samego źródła\n",
"\n",
"1. **Sposoby weryfikacji sprawności węzłów**: Do poprawnego działania, konieczna jest metoda określenia czy dany węzeł działa poprawnie. Wyróżnić można dwie strategie:\n",
" - prewencyjne - mechanizm zrównoleglania obciążenia w ustalonym odstępie czasu dokonuje sprawdzenia stanu węzła (np. poprzez wysłanie odpowiedniego żądania HTTP)\n",
" - reaktywne - monitorowane są odpowiedzi zwracane do klientów, w przypadku wystąpienia wielu podejrzanych odpowiedzi (np. kod HTTP 5XX), węzeł uznawany jest za nie działający\n",
"\n",
"1. **Przepustowość, redundancja i liczba jednocześnie obsługiwanych połączeń**: To jest parametr, który należy dostosować do potrzeb systemu. Niezależnie od wydajności wszystkich węzłów, system nie obsłuży więcej żądań niż jest w stanie to zrobić mechanizm zrównoleglający. Ponadto tworzy to w systemie tak zwany pojedynczy punkt awarii (ang. single point of failure). Awaria mechanizmu zrównoleglającego unimożliwia korzystanie z systemu.\n",
"\n",
"1. **TLS offloading**: Coraz częściej mechanizm zrównoleglania oferuje dodatkową funkcję jaką jest dodanie szyfrowania TLS do komunikacji. Najczęściej jest to wykorzystywane w przypadku gdy węzły wykorzystują do komunikacji protokół HTTP, natomiast klient oczekuje komunikacji zaszyfrowanej (HTTPS). Mechanimz zrównoleglania obciążenia może w takiej sytuacji tłumaczyć w locie pomiędzy HTTP i HTTPS.\n",
"\n",
"\n",
"### Sposób użycia\n",
"Korzystając z wirtualnych sieci prywatnych, nie należy przypisywać publicznych adresów do żadnych maszyn wirtualnych. Jedyne punkty dostępowe do systemu powinny być udostępnione za pośrednictwem mechanizmu równoważenia obciązenia i to adres tej usługi powinien być dostępny publicznie. W ten sposób oprócz zwiększonego bezpieczeństwa, otrzymujemy pełną dowolność w budowaniu naszej infrastruktury.\n",
"\n",
"Ponadto w przypadku dużych systemów, systemów rozproszonych geograficznie albo o wymaganej bardzo dużej dostępności, warto rozważyć połącznienie mechanizmu równoważenia obciążenia z wykorzystaniem technik opartych o wielokrotne wpisy DNS wskazująć na zasoby dostępne w odseparowanych infrastrukturach.\n",
"\n",
"### Dostępne usługi i ich koszt\n",
"Praktycznie każdy dostawca IaaS oferujący usługę sieci prywatnej oferuje też mechanizm równoważenia obciążenia. Jest to najczęściej usługa płatna o koszcie zbliżonym do 1-2 rdzeniowej współdzielonej maszyny wirtualnej. Ponadto niektóre usługi opierają swój koszt na bazie zużytych zasobów (tzw. LCU, ang. Load Balancer Capacity Units). LCU obejmuję pewną ilość zasobów przydzielonych do mechanizmu równoważenia obciążenia, najczęściej:\n",
"- pewną liczbę nowych połączeń w każdej sekundzie (np. 25)\n",
"- pewną liczbę aktywnych połączęń na minutę (np. 3000)\n",
"- pewnę ilość transferu (najczęściej 1GB)\n",
"\n",
"\n",
"| Dostawca | Nazwa | Warstwa | Koszt miesięczny |\n",
"| --- | --- | --- | --- |\n",
"| Alibaba | Classic Load Balancer | 4 | 8.21 + 16.42 za transfer do Mbit/s |\n",
"| Alibaba | Application Load Balancer | 7 | 19.15 + 19.15 za każde LCU |\n",
"| AWS | Classic Load Balancer | 4 | 68.40 + 0.03 za GB |\n",
"| AWS | Application Load Balancer | 7 | 61.56 + 21.89 za każde CLU |\n",
"| Azure | Load balancer | 4 | 68.40 + 0.02 za GB |\n",
"| Azure | Application Gateway | 7 | 69.35 + + 21.89 za każde CLU|\n",
"| Google Cloud | Cloud Load Balancing | 4 i 7 | 68.40 + 0.03 za GB |\n",
"| Hetzner | Load balancer | 4 i 7 | 26.24 |\n",
"| Linode | NodeBalancer | 4 i 7 | 38.00 |\n",
"| OVH | Network Firewall | 7 | 88.99 |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Kopie zapasowe\n",
"\n",
"Większość usług chmurowych oferuje bardzo wysoką dostępność i redundancję. Nie usprawiedliwia to jednak braku kopi zapasowej kluczowych danych. W przypadku usług chmurowych podobnie jak w przypadku klasycznych środowisk wirtualnych mamy doczynienia z dwoma głównymi technikami zabezpieczania danych z maszyny wirtualnej: klasycznej kopi zapasowej na zewnętrznym serwerze oraz migawek całej maszyny wirtualnej.\n",
"\n",
"![Diagram przedstawia maszynę wirtualną wraz z migawkami przyłączonego do niej zasobu dyskowego.](obrazy/zasoby-snapshot.png)\n",
"\n",
"### Opis\n",
"\n",
"**Klasyczna kopia zapasowa** polega na cyklicznym przesyłaniu kluczowych danych z maszyn wirtualnych na zewnętrzne serwery. Taka kopia zapasowa wymaga ręcznej konfiguracji, może natomiast obejmować bardziej specyficzne dane takie jak, wyeksportowaną kopię bazy danych w odpowiednim formacie. Dla uproszczenia można przyjąć, że taka kopia to pojedyncze spakowane archiwum. Odtwarzanie z takiej kopi również wymaga odpowiedniej konfiguracji i wykorzystania odpowiednich narzędzi. Klasyczna kopia zapasowa powinna być przechowywana w infrastrukturze możliwie bardzo odseparowanej od głównej. Warto rozważyć inną lokalizację geograficzną a nawet dostawcę usług.\n",
"\n",
"**Migawka maszyny wirtualnej** to z drugiej strony kopia wszystkich zasobów dyskowych maszyny wirtualnej czasami powiązana również z jej konfiguracją (typem instancji, dostępnymi zasobami obliczeniowymi, itp). Migawka obejmuje również pliki systemu operacyjnego oraz zainstalowane aplikacje. Bazując na migawce można bardzo łatwo odtworzyć maszynę wirtualną lub stworzyć jej identyczną kopię. Technicznie, z powodu dużego rozmiaru tego typu migawki przechowywane są najczęściej w sposób przyrostowy (każda kolejna migawka zachowuje tylko różnice względem poprzedniej migawki).\n",
"\n",
"Można odnieść wrażenie, że migawki systemu są rozwiązaniem znacznie bardziej elastycznym. Do głównych wad należy ich kosztowność w przypadku długoterminowego przechowywania danych. Rozmiar migawek ma tendencje do szybkiego wzrostu. Nawet zastosowanie migawek przyrostowych nie rozwiązuje w pełni tego problemu. Druga wada dotyczy spójności danych. Migawka systemu utrwala jego bieżący stan, który nie koniecznie musi być spójny. Dlatego zalecane jest robienie migawek gdy maszyna wirtualna jest w stanie wyłączonym. To z kolei powoduje przestoje w działaniu systemu i ogranicza zastosowanie jako efektywny sposób robienia kopi zapasowej.\n",
"\n",
"\n",
"### Sposób użycia\n",
"\n",
"Zaleca się korzystanie z obu strategii kopii zapasowej. Migawki maszyny wirtualnej należy wykorzystywać do krótkotrwałęgo zabezpiecznia danych i całego stanu systemu, głównie ze względu na to, że zapewniają szybki i prosty sposób przywracania po awarii. Klasyczne kopie zapasowe należy stosować do długoterminowego przechowywania danych oraz zapewniania bardzo wysokiej dostępności na wypadek awarii. Kluczowe jest zapewnienie separacji fizycznej kopii zapasowej od głównej infrastruktury. Ponadto należy się zabezpieczyć przed sytuacją, w której wadliwa/zaatakowana maszyna wirtualna zyskuje dostęp do serwera kopii zapasowej. Szczególnie niekorzystne są dwa scenariusze: usunięcie kopii zapasowej oraz uzyskanie dostępu do kopii zapasowej innych usług/systemów.\n",
"\n",
"\n",
"### Dostępne usługi i ich koszt\n",
"\n",
"Praktycznie wszyscy dostawcy usług chmurowych oferują oba rodzaje kopii zapasowej. Najczęściej są to usługi płatne, z naliczaniem za każdy przechowywany GB danych. Poniższa tabala porównuje miesieczny koszt różnych usług.\n",
"\n",
"| Dostawca | Nazwa migawki | Koszt za GB migawki | Nazwa klasyczna kopia | Koszt GB klasycznej kopii |\n",
"| --- | --- | --- | --- | --- |\n",
"| Alibaba | Snapshots | 0.76 | Object Storage Service Infrequent Access | 0.068 |\n",
"| AWS | Classic Load EBS Snapshots | 0.19 | S3 Infrequent Access | 0.048 |\n",
"| Azure | Snapshots | 0.19 | Blob Storage Cold | 0.076 |\n",
"| Google Cloud | Snapshot | 0.099 | Cloud Coldline Storage | 0.015 |\n",
"| Hetzner | Snapshot | 0.054 | Backups | 20% ceny maszyny wirtualnej |\n",
"| Linode | Images | 0.38 | Object Storage | 0.076 |\n",
"| OVH | Volume Snapshot | 0.072 | Object Storage | 0.072 |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Literatura\n",
"* [IBM]: R. J. Creasy. The Origin of the VM/370 Time-sharing System. IBM. 1981\n",
"* [ALI]: Alibaba. [Cennik usług Alibaba Cloud](https://www.alibabacloud.com/pricing). Dostęp 28.09.2021\n",
"* [AWS]: Amazon. [Cennik usług AWS](https://aws.amazon.com/pricing/). Dostęp 28.09.2021\n",
"* [AZ]: Microsoft. [Cennik usług Azure](https://azure.microsoft.com/pl-pl/pricing/). Dostęp 28.09.2021\n",
"* [GC]: Google. [Cennik usług Google Cloud](https://cloud.google.com/pricing). Dostęp 28.09.2021\n",
"* [HZ]: Hetzner. [Cennik usług Hetzner Cloud](https://www.hetzner.com/cloud). Dostęp 28.09.2021\n",
"* [LIN]: Linode. [Cennik usług Linode](https://www.linode.com/pricing/). Dostęp 28.09.2021\n",
"* [OVH]: OVH. [Cennik usług OVH](https://www.ovhcloud.com/pl/public-cloud/prices/). Dostęp 28.09.2021\n"
]
}
],
"metadata": {
"interpreter": {
"hash": "98b0a9b7b4eaaa670588a142fd0a9b87eaafe866f1db4228be72b4211d12040f"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

281
03_IaaS/03_03.ipynb Normal file
View File

@ -0,0 +1,281 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Zadania do realizacji w czasie zajęć\n",
"\n",
"## Założenie konta na Hetzner Cloud\n",
"\n",
"1. Wejdź na stronę <https://accounts.hetzner.com> i zarejestruj nowe konto. Możesz skorzystaj ze studenckiego adresu email, ułatwi to dodanie odpowiednich uprawnień do Twojego konta.\n",
" Proces rejestracji wymaga odebrania linku aktywacyjnego oraz podania podstawowych danych osobowych. Jako formę płatności można wybrać przelew bankowy. \n",
" \n",
"1. W ramach zajęć zostaniesz przypisany do puli zasobów, która będzie opłacana przez Wydział. Zweryfikuj dostęp do projektu o nazwie ***PZC***, którego właścicielem jest Wydział.\n",
"\n",
"## Instalacja Wordpress w środowisku Hetzner\n",
"\n",
"Celem tego zadania będzie instalacja *Wordpressa* - najpopularniejszego systemu zarządzania treścią (CMS), w infrastrukturze typu IaaS z wykorzystaniem dostępu przeglądarkowego. Proces instalacji wykonamy ręcznie krok po kroku. Na następnych zajęciach przedstawione zostanie jak zautomatyzować instalację poprzez uruchomienie skryptu.\n",
"\n",
"### Centralna baza danych\n",
"\n",
"Pierwszym krokiem przy instalacji *Wordpresa* jest zainstalowanie i skonfigurowanie bazy danych. Hetzner nie oferuje zarządzanych baz danych w modelu SaaS (patrz następne zajęcia), dlatego na tym etapie będziemy również odpowiedzialni za instalację bazy i jej późniejsze utrzymanie. Jednak aby istotnie uprościć proces i wyabstrachować zbędne szczegóły, do uruchomienia oprogramowania wykorzystamy narzędzie **Docker**. \n",
"\n",
"Docelowo dążymy do uzyskania następującej konfiguracji:\n",
"\n",
"![Diagram przedstawia pojedynczą maszynę wirtualną z uruchomionymi na niej dwoma kontenerami docker: bazą danych MySql oraz webowym interfejsem administracyjnym phpMyAdmin. Komunikacja pomiędzy kontenerami odbywa się za pośrednictwem wewnętrznej sieci zarządzanej przez dockera. PhpMyAdmin jest udostępniony na publicznym adresie IP maszyny wirtualnej na porcie 8080.](obrazy/wp-etap1.png)\n",
"\n",
"\n",
"1. Rozpoczynając pracę w interfejsem webowym [chmury obliczeniowej Hetzner](https://cloud.hetzner.com) nie dysponujemy żadnymi zasobami. W ramach zasobów dostępnych w ramach zajęć powinieneś być przydzielony do dwóch projektów: *Default* oraz *PZC*. Pamiętaj, że maszyny wirtualne utworzone w projekcie *PZC* opłącene są przez Wydział, podczas gdy za te utwożone w projekcie *Default* rachunek zostanie wystawiony na dane podane przy rejestracji konta.\n",
" <img src=\"obrazy/hetzner-pusty.png\" width=\"75%\" alt=\"\">\n",
"\n",
"1. Wybieramy opcję utworzenia nowej maszyny wirtualnej i wybieramy następujące dane:\n",
"\n",
" <img src=\"obrazy/hetzner-vm-1.png\" width=\"75%\" alt=\"\">\n",
" <img src=\"obrazy/hetzner-vm-2.png\" width=\"75%\" alt=\"\">\n",
" - lokalizacja: Helsinki (nowesze serwery, lepszy transfer do polski, niższe ceny, wsparcie w języku angielskim)\n",
" - obraz systemu: Ubuntu 20.04 lub nowsze (Ubuntu serwer jest najlepszym wyborem dla początkujących administratorów)\n",
" - typ instancji: CX11 (1 vCPU, 2GB RAM, 20GB SSD, cena na poziomie 3 groszy za godzinę)\n",
" - dyski: brak\n",
" \n",
"1. W kroku *Sieć* tworzymy nową sięć prywatną o nazwie `network-1` i puli adresów `10.10.10.0/24`.\n",
" \n",
" <img src=\"obrazy/hetzner-network.png\" width=\"75%\" alt=\"\">\n",
"\n",
"1. Pomijamy dodanie zapory sieciowej oraz dodatkowych funkcjonalności. Podajemy natomiast klucz SSH, który będzie służył do logowania się na naszą maszynę na konto `root`.\n",
"\n",
" <img src=\"obrazy/hetzner-ssh-key.png\" width=\"75%\" alt=\"\">\n",
"\n",
" > **Uwaga**: Teoretycznie Hetzner umożliwia logowanie się hasłem do utworzonych maszyn wirtualnych, jest to jednak bardzo nie rozważne. Proponuję przeprowadzić eksperyment polegający na utworzeniu maszyny wirtualnej z hasłem `admin` i zmierzeniu czasu po jakim dostęp do niej zostanie przejęty przez boty. Na szczęście zawsze możesz usunąć maszynę w interfejsie webowym Hetzner, nawet po przejęciu nad nią kontroli przez kogoś innego.\n",
"\n",
"1. Potwierdzamy chęć utworzenia maszyny wirtualnej i czekamy na jej inicjalizację. Całość powinna trwać około minuty. Po tym czasie nasza maszyna jest gotowa do użycia. Sprawdź jej dostępność logując się przez SSH na przypisany nowoutworzonej maszynie adres IP. \n",
"\n",
" <img src=\"obrazy/hetzner-po-vm.png\" width=\"75%\" alt=\"\">"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Teraz gdy dysponujemy nową maszyną wirtualną możemy rozpocząć instalację niezbędnego oprogramowania.\n",
"\n",
"1. Na początku musimy zainstalować oprogramowanie docker. Niestety wersje oferowane w repozytoriach Ubuntu są bardzo stare i nie jest zalecane ich używanie. Poniższy skrypt instaluje zarówno `docker`a jak i `docker-compose` zgodnie z zaleceniami twórców tych narzędzi.\n",
" ```bash\n",
" apt update && apt install apt-transport-https ca-certificates curl gnupg lsb-release\n",
" \n",
" curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg\n",
" \n",
" echo \\\n",
" \"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \\\n",
" $(lsb_release -cs) stable\" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null\n",
" \n",
" apt update && apt install docker-ce docker-ce-cli containerd.io\n",
"\n",
" sudo curl -L \"https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose\n",
" \n",
" chmod +x /usr/local/bin/docker-compose\n",
" ```\n",
"\n",
"1. Następnie należy stworzyć plik o nazwie `docker-compose.yml` o następującej treści. Lokalizacja pliku nie ma znaczenia.\n",
" ```docker-compose\n",
" version: '3.9'\n",
"\n",
" services:\n",
" db:\n",
" image: mysql:5.7\n",
" restart: always\n",
" environment:\n",
" MYSQL_ROOT_PASSWORD: notSecureChangeMe\n",
" volumes:\n",
" - db_data:/var/lib/mysql\n",
"\n",
" phpmyadmin:\n",
" image: phpmyadmin\n",
" restart: always\n",
" ports:\n",
" - 8080:80\n",
" volumes:\n",
" db_data: {}\n",
" ```\n",
"\n",
" W pliku tym definiujemy dwie usługi (samą bazę danych oraz webowy interfejs dostępowy). Wskazujemy też, że dostęp do bazy przez przeglądarkę będzie możliwy z portu 8080.\n",
"\n",
"1. Bazę danych uruchamiamy komendą:\n",
" ```bash\n",
" docker-compose up\n",
" ```\n",
" Aby wyłączyć bazę danych należy wcisnąć `Ctrl-C`.\n",
"\n",
" > **Wskazówka**: Jeśli chcesz usunąć utworzone kontenery wraz z zasobami dyskowymi zastosuj komendę `docker-compose down -v`. W ten sposób możesz zaczać od zera.\n",
"\n",
" > **Wskazówka**: Polecenie `docker-compose up -d` uruchamia nasze kontenery w tle.\n",
"\n",
"1. Odwiedź w przeglądarce adres: `http://<adres IP maszyny wirtualnej db>:8080` u zaloguj się używając nazwy użytkownika `root` oraz hasła podanego w pliku `docker-compose.yml`. Jest to webowy interfejs dostępowy do naszej bazy danych, który przyda się w dalszej części zajęć.\n",
"\n",
" <img src=\"obrazy/phpMyAdmin.png\" width=\"75%\" alt=\"\">\n",
"\n",
"\n",
"Udało się nam skonfigurować instancję bazy MySql. W obecnej konfiguracji nie jest ona zbytnio zabezpieczona, jednak zajmiemy się tym przy okazji instalacji Wordpress w następnym kroku."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Instalacja Wordpress\n",
"\n",
"Teraz naszym zadaniem jest zainstalować oprogramowanie Wordpress na osobnej maszynie wirtualnej. Ponownie wykorzystamy gotowe obrazy `docker` w celu otrzymania następującej konfiguracji:\n",
"\n",
"![Diagram przedstawia dwie maszyny wirtualne. Konfiguracja maszyny db została zaktualizowa tak aby baza danych była dostępna w sieci prywatnej. Nowa maszyna wirtualna wordpress-1 udostępnia CMS na porcie 8000 i komunikuje się z bazą danych wewnątrz sieci prywatnej.](obrazy/wp-etap2.png)\n",
"\n",
"1. Na maszynie wirtualnej z bazą danych (`db`) musimy dokonać pewnych zmian w konfiguracji. Przede wszystkim konieczne jest udostępnienie bazy danych na zewnątrz. Nie chcemy jednak aby była ona dostępna publicznie, a tylko w sieci prywatnej. Stąd podajemy konkretny prywatny adres IP przy udostępnianiu portów. Dodajemy też osobne konto i bazę danych dla Wordpresa. Wynikowy plik powinien wyglądać następująco.\n",
"\n",
" > **Uwaga**: Zwróć uwagę na przydzielony maszynie `db` prywatny adres IP, z reguły będzie to `10.10.10.2`. Możesz to sprawdzić w widoku szczegółów maszyny wirtualnej w interfejsie webowy w zakładce *Sieć*.\n",
"\n",
" ```docker-compose\n",
" version: '3.9'\n",
"\n",
" services:\n",
" db:\n",
" image: mysql:5.7\n",
" restart: always\n",
" ports:\n",
" - \"10.10.10.2:3306:3306\"\n",
" environment:\n",
" MYSQL_ROOT_PASSWORD: notSecureChangeMe\n",
" MYSQL_DATABASE: wordpress\n",
" MYSQL_USER: wordpress\n",
" MYSQL_PASSWORD: wordpress\n",
" volumes:\n",
" - db_data:/var/lib/mysql\n",
"\n",
" phpmyadmin:\n",
" image: phpmyadmin\n",
" restart: always\n",
" # przekierowanie portów zostawione tylko dla przykładu, nie należy tak robić na produkcji\n",
" ports:\n",
" - \"8080:80\"\n",
" volumes:\n",
" db_data: {}\n",
" ```\n",
"\n",
"1. Tworzymy drugą maszynę wirtualną o nazwie `wordpress-1`, wybierając identyczne opcje jak poprzednio.\n",
"\n",
"1. Logujemy się przez SSH na nową maszynę wirtualną i podobnie jak poprzednio tworzymy plik `docker-compose.yml` o następującej treści.\n",
"\n",
" ```docker-compose\n",
" version: '3.9'\n",
"\n",
" services:\n",
" wordpress:\n",
" image: wordpress:latest\n",
" volumes:\n",
" - wordpress_data:/var/www/html\n",
" ports:\n",
" - \"8000:80\"\n",
" restart: always\n",
" environment:\n",
" WORDPRESS_DB_HOST: \"10.10.10.2:3306\"\n",
" WORDPRESS_DB_USER: wordpress\n",
" WORDPRESS_DB_PASSWORD: wordpress\n",
" WORDPRESS_DB_NAME: wordpress\n",
" \n",
" volumes:\n",
" wordpress_data: {}\n",
" ```\n",
"\n",
" Tym razem korzystamy z oficjalnego obrazu Wordpress. Za pomocą zmiennych środowiskowych podajemy dane dostępowe do bazy danych. Zwróć uwagę na zmienną środowiskową `WORDPRESS_DB_HOST`, która wskazuje na adres prywatny serwera `db`.\n",
"\n",
"1. W przeglądarce odwiedź adres `http://<adres IP maszyny wirtualnej wordpress-1>:8000` i dokończ instalację Wordpress.\n",
"\n",
"W ten sposób zakończyła się instalacja Wordpress. Serwer web oraz baza danych znajdują się na osobnych maszynach wirtualnych, ponadto baza danych dostępna jest tylko z poziomu wirtualnej sieci prywatnej."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Mechanizm równoważenia obciążenia i migawki systemu\n",
"\n",
"W kolejnym etapie dodamy mechanim równoważenia obciążenia oraz drugą maszynę wirtualną na której działał będzie Wordpress. W tym celu wykorzystamy mechanim migawek maszyn wirtualnych. Dążymy teraz do otrzymania następującej konfiguracji:\n",
"\n",
"![Diagram przedstawia ewolucję poprzedniej konfiguracji. Dodano mechanizm równoważenia obciążenia, który teraż nasłuchuje na porcie 80 i przekazuje ruch do dwóch niezależnych maszyn wirtualnych korzystając z sieci wewnętrznej.](obrazy/wp-etap3.png)\n",
"\n",
"1. Wyłącz maszynę wirtualną `wordpress-1`. Możesz to zrobić np. wydając komendę:\n",
" ```bash\n",
" shutdown now\n",
" ```\n",
" \n",
" Zweryfikuj, że maszyna jest wyłączona w interfejsie webowym.\n",
"\n",
"1. Utworz migawkę tej maszyny. W tym celu wejdź w widok szczegółów maszyny i wybierz opcję *Migawka*. Potwierdź chęć jej utworzenia i poczekaj aż proces dobiegnie końca.\n",
"\n",
"1. Migawka pozwala na stworzenie nowej maszyny wirtualnej na bazie obecnie istniejącej. Pozwoli nam to oszczędzić czas i zapewni jednolitość obu istancji. Przejdź do tworzenia nowej maszyny wirtualnej i tym razem w sekcji *Obraz systemu* wybierz opcję *Migawka*. Pozostałe opcje ustaw tak jak poprzednio, a maszynę nazwij `wordpress-2`. W między czasie możesz też uruchomić ponownie maszynę `wordpress-1`.\n",
"\n",
"1. Możesz teraz zweryfikować, że na obu maszynach działa ten sam wordpress. Dodaj przykładowy post na jednym z nich i sprawdź czy pojawi się na drugim.\n",
"\n",
"1. Czas na stworzenie i konfigurację równoważenia obciążenia. Przechodzimy do odpowiednij opcji w interfejsie webowym i wybieramy następującą konfigurację:\n",
" - lokalizacja: Helsinki\n",
" - typ: LB11\n",
" - sieć: network-1\n",
" - cele: wybieramy obie maszyny wirtualne z wordpresem i zaznaczamy komunikacje przez prywatny adres\n",
" - usługi: http, port źródłowy 800, port docelowy 8000, \n",
" - sprawdzanie stanu maszyn: wybieramy opcję *sticky sessions* z czasem ustawionym na 60 sekund, zmieniamy port docelowy na 8000, upewniamy się że *proxy protocol* jest wyłączony\n",
"\n",
" Potwierdzamy chęć utworzenia mechanizmu równoważenia obciążenia. Jego inicjalizacja może trochę potrwać, ale w przeglądarce już można przejść pod `http://<adres IP LB>:8000/`\n",
"\n",
" <img src=\"obrazy/hetzner-lb.png\" width=\"75%\" alt=\"\">\n",
"\n",
"1. Zwróć uwagę, że przy próbie zalogowanie zostajemy automatycznie przekierowani na adres IP pierwszej maszyny wirtualnej. Wynika to z domyślnego zachowania Wordpresa. Aby to naprawić należy, wejść w interfejs webowy bazy danych i wyedytować dwa wiersze w tabeli `wp-options`: `siteurl` oraz `home`, podając tam adres IP mechanizmu równoważenia obciążenia.\n",
"\n",
" > **Uwaga**: Wordpress nie jest przystosowany do łatwego przenoszenia/zmieniania adresu URL na którym pracyje.\n",
"\n",
" > **Uwaga**: W rzeczywistych warunkach nasza strona dostępna była by za pomocą adresu domenowego i powinna zostać od samego początku skonfigurowana jako dostępna pod tym adresem. Adres ten powinien być następnie przekierowany na początku na maszynę `wordpres-1` a następnie na mechanimz równoważenia obciążenia. Niestety opóźnienia propagacji wpisów DNS uniemożliwiają przeprowadzenie tego w ramach zajęć. \n",
"\n",
"1. Sprawdźmy czy nasza strona jest teraz rzeczywiście obsługiwana jednocześnie przez dwie maszyny wirtualne. W tym celu korzystając z adresu IP mechanizmu równoważenia obciążenia, dodaj nowy post zawierający jeden obraz (wgrany na serwer, nie przez URL czy z biblioteki).Odczekaj chwilę (60 sekund) lub otwórz stronę w innej przeglądarce/trybie incognito. Czasem trzeba to powrórzyć kilka razy. Co się dzieje ?\n",
"\n",
" > **Wskazówka**: Można też uruchomić narzędzia deweloperskie przeglądarki (Crtl-I) i ręcznie usunąć ciasteczko `HCLBSTICKY`, które powoduje utrzymanie powiązania przeglądarki z kontkretną maszyną wirtualną.\n",
"\n",
"1. Zaobserwowane zjawisko pokazuje, kluczowy problem z taką instalacją Wordpress. Konieczne jest utrzymanie synchronizacji pomiędzy dyskami obu maszyn wirtualnych (to tam przechowywane są przesłane na serwer obrazy). Przykładowo jeszcze większe problemy moglibyśmy obserwować przy aktualizacji Wordpresa, gdy tylko jedna z instancji została by zaktualizowana. Rozwiązanie tego problemu wymaga ingerencji w Wordpresa i zostanie pokazane na jednych z następnych zajęć."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Problemy otwarte\n",
"\n",
"Zastanów się nad następującymi problemami:\n",
"\n",
"1. W jaki sposób moglibyśmy zabezpieczyć się przed utratą zgormadzonych na stronie danych.\n",
"1. Jaki jest koszt takiej infrastruktury (wliczając kopie zapasowe, migawki, itp). Porównaj go z kosztem zakupu hostowanego Wordpresa w modelu SaaS na <https://www.wordpress.com>.\n",
"1. Co się stanie gdy zmienimy skórkę w tak skonfigurowanym Wordpresie.\n",
"1. Jakie jeszcze problemy mogą wyniknąć przy takiej instalacji Wordpresa."
]
}
],
"metadata": {
"interpreter": {
"hash": "98b0a9b7b4eaaa670588a142fd0a9b87eaafe866f1db4228be72b4211d12040f"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

764
03_IaaS/03_04.ipynb Normal file
View File

@ -0,0 +1,764 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Zadania do realizacji w czasie zajęć\n",
"\n",
"W trakcie tych zajęć zautomatyzujemy instalację Wordpresa. Celem jest osiągnięcie tej samej konfiguracji co poprzednio, jednak tak aby wszystko zostało zainstalowane i uruchomione przy wykonaniu jednego skryptu.\n",
"\n",
"##\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Instalacja CLI\n",
"\n",
"1. Pobierz najnowsze wydanie *hcloud* CLI: <https://github.com/hetznercloud/cli/releases/latest/download/hcloud-linux-amd64.tar.gz>. Pobrany plik rozpakuj\n",
" ```bash\n",
" tar -xvzf hcloud-linux-amd64.tar.gz\n",
" ```\n",
" Zweryfikuj działanie CLI:\n",
" ```bash\n",
" ./hcloud version\n",
" ```\n",
" \n",
" > **Wskazówka**: Pamiętaj aby plik rozpakować w miejscu, w którym możliwe jest uruchamianie plików wykonywalnych.\n",
"\n",
"1. Dla łatwiejszego wpisywania poleceń w zalecane jest skonfigurowanie odpowiedniego autouzupełniania składni:\n",
"\n",
" - bash:\n",
" ```bash\n",
" source <(./hcloud completion bash)\n",
" ```\n",
" - fish:\n",
" ```bash\n",
" ./hcloud completion fish | source\n",
" ```\n",
"1. Przed użyciem konieczne jest udzielenie uprawnień naszemu narzędziu konsolowemu do naszego konta. Jedyną dostępną opcją jest wykorzystanie *tokenu* autoryzacyjnego.\n",
"\n",
" ```bash\n",
" ./hcloud context create pzc\n",
" ```\n",
"\n",
" Polecenie to zażąda od nas podania tokenu dostępowego. W tym celu należy wygenerować go korzystając z webowego interfejsu (projekt PZC -> zabezpieczenia -> tokeny API). Należy wybrać uprawnienia do odczytu i zapisu, bez tego nie będzie można tworzyć nowych zasobów.\n",
"\n",
" > **Uwaga**: Należy pilnować bezpieczeństwa tokenu, co prawda nie daje on pełnych uprawnień do konta jak login i hasło, lecz wciaż umożliwia tworzenie dowolnych zasobów.\n",
"\n",
" > **Uwaga**: Token zostanie zapisany w pliku `~/.config/hcloud/cli.toml`. Tam też trafiają pozostałe opcje konfiguracyjne.\n",
"\n",
" ![](obrazy/hetzner-token.png)\n",
"\n",
" Utworzony kontekst zostanie automatycznie aktywowany, od tego momentu wszystkie polecenia będą wykonywane w jego obrębie.\n",
"\n",
"1. Spróbujmy utworzyć nową maszynę wirtualną z wiersza poleceń.\n",
"\n",
" ```bash\n",
" ./hcloud server create --image ubuntu-20.04 --type cx11 --name pzc-test-1 --location hel1\n",
" ```\n",
" \n",
" Listę dostępnych lokalizacji, obrazów systemu, i typów instancji możesz uzyskać dzięki następującym poleceniom:\n",
" ```bash\n",
" ./hcloud locations list\n",
" ./hcloud image lsit\n",
" ./hcloud server-type list\n",
" ```\n",
"\n",
"1. Przykładowo proces utworzenia maszyny wirtualnej może wyglądać następująco\n",
" ```bash\n",
" $ ./hcloud server create --image ubuntu-20.04 --type cx11 --name pzc-test-1 --location hel1\n",
" 4.551s [=================================] 100.00%\n",
" Waiting for server 14328689 to have started\n",
" ... done \n",
" Server 14328689 created\n",
" IPv4: 95.216.211.233\n",
" Root password: 7eN7CihrEvbuViciCmsq\n",
" ```\n",
"\n",
" Zweryfikuj w przeglądarce czy maszyna wirtualna została rzeczywiście utworzona.\n",
"\n",
"1. Dokladne informacje o istniejącej maszynie można uzyskać dzięki poleceniu:\n",
" \n",
" ```bash\n",
" ./hcloud server describe pzc-test-1\n",
" ```\n",
"\n",
"1. Gdy maszyna nie jest już potrzebna można ją usunać:\n",
" ```bash\n",
" ./hcloud server delete pzc-test-1\n",
"\n",
"> **Wskazówka**: W zadaniach domowych możesz założyć, że wszystkie te kroki zostały wykonane w katalogu `/dev/shm` oraz, ze aktywny jest odpowiedni kontekst."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Biblioteka Python\n",
"\n",
"CLI jest bardzo wygodnym klasycznym rozwiązaniem, jednak nie zawsze jest wystarczająco elastyczne. Możliwy jest dostęp do zasobów chmurowych z poziomu języka programowania, większość dostawców dostarcza biblioteki dla najpopuparniejszych jezyków programowania.\n",
"\n",
"Dla chmury Hetzner dostępna jest przykładowo biblioteka dostępowa w języku Python: <https://github.com/hetznercloud/hcloud-python)>. Analogicznie jak w przypadku CLI, konieczne jest posiadanie tokenu dostępowego (może być ten sam co poprzednio). Poniższy fragment kodu tworzy instancję interfejsu dostępowego do chmury:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from hcloud import Client\n",
"client = Client(\n",
" token=\"ftGv4HLU2FsZCD9JEfN8suRh1X4rHImwCOJHP4eKsntvxGyjHR39ADgzYVrbw7m5\"\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Analogicznie jak w CLI możemy utworzyć nową maszynę wirtualną:"
]
},
{
"cell_type": "code",
"execution_count": 114,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Utworzono serwer: pzc-test (95.217.183.63)\n"
]
}
],
"source": [
"from hcloud.images.domain import Image\n",
"from hcloud.server_types.domain import ServerType\n",
"\n",
"response = client.servers.create(\n",
" name=\"pzc-test\", server_type=ServerType(\"cx11\"), image=Image(name=\"ubuntu-20.04\")\n",
")\n",
"print(f\"Utworzono serwer: {response.server.data_model.name} ({response.server.data_model.public_net.ipv4.ip})\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Po zakończeniu pracy można usunąć wszystkie stworzone serwery korzystająć z prostego skryptu:"
]
},
{
"cell_type": "code",
"execution_count": 115,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Usuwanie 1 serwerów\n",
"Usuwanie serwera pzc-test (95.217.183.63): success\n"
]
}
],
"source": [
"servers = client.servers.get_all()\n",
"print(f\"Usuwanie {len(servers)} serwerów\")\n",
"for s in servers:\n",
" action = client.servers.delete(s)\n",
" print(f\"Usuwanie serwera {s.data_model.name} ({s.data_model.public_net.ipv4.ip}): {action.data_model.status}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Automatyzacja instalacji Wordpress\n",
"\n",
"Przejdziemy teraz do realizacji głównego zadania przewidzianego na dzisiejsze zajęcia. Analogicznie jak na poprzednich zajęciach chcemy uzyskać instalację Wordpresa wraz z konfigurowanym równoważeniem obciążenia, zgodnie z poniższym schematem:\n",
"\n",
"![](obrazy/wp-etap3.png)\n",
"\n",
"Tworzenie instalacji Wordpress rozpoczynamy od dodania klucza SSH do naszego konta."
]
},
{
"cell_type": "code",
"execution_count": 116,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Klucz pzc-ssh-key został dodany: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINXcCzwPDRJm+ICREkvIXRg6A0HEmasC5fLxdqK6P5zm bikol@spire\n"
]
}
],
"source": [
"ssh_key = client.ssh_keys.create(name=\"pzc-ssh-key\", public_key=\"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINXcCzwPDRJm+ICREkvIXRg6A0HEmasC5fLxdqK6P5zm bikol@spire\")\n",
"print(f\"Klucz {ssh_key.data_model.name} został dodany: {ssh_key.data_model.public_key}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Teraz przystępujemy do tworzenia właściwych zasobów. Zacznijmy od wirtualnej sieci:"
]
},
{
"cell_type": "code",
"execution_count": 117,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Utworzono sieć wirtualną pzc-test-vnet (10.10.10.0/24)\n"
]
}
],
"source": [
"from hcloud.networks.domain import NetworkSubnet\n",
"\n",
"vnet = client.networks.create(\n",
" name=\"pzc-test-vnet\", \n",
" ip_range=\"10.10.10.0/24\", \n",
" subnets=[\n",
" NetworkSubnet(ip_range=\"10.10.10.0/24\", network_zone=\"eu-central\", type=\"cloud\")\n",
" ]\n",
")\n",
"print(f\"Utworzono sieć wirtualną {vnet.data_model.name} ({vnet.data_model.ip_range})\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Kolejnym etapem jest utworzenie maszyn wirtualnych. Skorzystamy z narzędzia [cloud-init](https://cloud-init.io/) aby móc automatycznie nie tylko stworzyć maszynę, ale również zainstalować i uruchomić na niej porządane oprogramowanie. Konfiguracja z wykorzystaniem `cloud-init` pozwala zdefiniować jakie co ma być wykonane po utworzeniu maszyny wirtualnej. Ważne jest to, że wszystko zostanie wykonane automatycznie bez potrzeby logowania się przez SSH czy innej interakcji z serwerem. `cloud-init` pozwala na wykonanie dowolnych operacji na serwerze. Służy do tego sekcja `runcmd`, w której definiujemy polecenia jakie mają zostać wykonane w konsoli. Dla uproszczenia najczęściej wykonywane zadania mają przewidzianą osobną składnie. Przykładowo można\n",
"\n",
"- tworzyć nowych użytkowników i grupy\n",
"- dodawać i modyfikować pliki\n",
"- instalować nowe oprogramowania i dodawać nowe repozytoria\n",
"- zarządzać zaufanymi certyfikatami\n",
"- zarządzać zamontowanymi zasobami dyskowymi\n",
"- zarządzać kluczami SSH\n",
"\n",
"Na potrzeby tego zadania wykorzystamy tylko część z dostępnych możliwości. Ponadto wykorzystamy tylko jeden z wielu możliwych formatów konfiguracji `cloud-init` o nazwie `cloud config`.\n"
]
},
{
"cell_type": "code",
"execution_count": 118,
"metadata": {},
"outputs": [],
"source": [
"cloud_init_db=r'''#cloud-config\n",
"\n",
"# lista podstawowych pakietów, które należy zainstalować\n",
"packages:\n",
" - apt-transport-https\n",
" - ca-certificates\n",
" - curl\n",
" - gnupg-agent\n",
" - software-properties-common\n",
"\n",
"# tworzymy plik docker-compose.yml\n",
"write_files:\n",
" - path: /root/docker-compose.yml\n",
" content: |\n",
" version: '3.9'\n",
"\n",
" services:\n",
" db:\n",
" image: mysql:5.7\n",
" restart: always\n",
" ports:\n",
" - \"10.10.10.2:3306:3306\"\n",
" environment:\n",
" MYSQL_ROOT_PASSWORD: notSecureChangeMe\n",
" MYSQL_DATABASE: wordpress\n",
" MYSQL_USER: wordpress\n",
" MYSQL_PASSWORD: wordpress\n",
" volumes:\n",
" - db_data:/var/lib/mysql\n",
"\n",
" phpmyadmin:\n",
" image: phpmyadmin\n",
" restart: always\n",
" # przekierowanie portów zostawione tylko dla przykładu, nie należy tak robić na produkcji\n",
" ports:\n",
" - \"8080:80\"\n",
" volumes:\n",
" db_data: {}\n",
"\n",
"# instalujemy docker, docker-compose a następnie uruchamiamy naszą bazę danych\n",
"runcmd:\n",
" - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -\n",
" - add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable\"\n",
" - apt-get update -y\n",
" - apt-get install -y docker-ce docker-ce-cli containerd.io\n",
" - curl -L \"https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose\n",
" - chmod +x /usr/local/bin/docker-compose\n",
" - systemctl start docker\n",
" - systemctl enable docker\n",
" - cd /root/ && docker-compose up -d\n",
"'''"
]
},
{
"cell_type": "code",
"execution_count": 119,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Tworzenie serwera db: True\n"
]
}
],
"source": [
"from hcloud.locations.domain import Location\n",
"\n",
"db_server = client.servers.create(\n",
" name=\"db\", \n",
" server_type=ServerType(\"cx11\"), \n",
" image=Image(name=\"ubuntu-20.04\"), \n",
" ssh_keys=[ssh_key], \n",
" networks=[vnet], \n",
" location=Location(\"hel1\"), \n",
" user_data=cloud_init_db\n",
")\n",
"\n",
"db_server.action.wait_until_finished()\n",
"print(f\"Tworzenie serwera db: {db_server.action.complete}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Serwer został utworzony, możemy pobrać z systemu jego aktualne dane (w tym adres IP).\n",
"\n",
"> **Uwaga** W skrypcie `cloud-init` przyjeliśmy, że maszyna będzie miała przydzielony adres IP `10.10.10.2`, jeśli tak się nie stało to w dalszych krokach Wordpress może mieć problem z kominukacją z bazą danych."
]
},
{
"cell_type": "code",
"execution_count": 120,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Serwer: db\n",
"\tpubliczne IP: 135.181.201.125\n",
"\tprywatne IP: 10.10.10.2\n"
]
}
],
"source": [
"db_server = client.servers.get_by_name(\"db\")\n",
"print(f\"Serwer: {db_server.data_model.name}\\n\\tpubliczne IP: {db_server.data_model.public_net.ipv4.ip}\\n\\tprywatne IP: {db_server.data_model.private_net[0].ip}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Na tym etapie możesz zweryfikować, że wszystko działa jak należy. Odwiedź w przeglądarce `http://<publiczny adres IP>:8080`.\n",
"\n",
"> **Uwaga**: Utworzenie maszyny wirtualnej trwa zaledwie kilka sekund, jednak wykonanie całego skryptu `cloud-init` może potrwać nawet kilka minut. Jeśli serwer nadal nie odpowiada pod wskazanym adresem, poczekaj kilka minut.\n",
"\n",
"> **Wskazówka**: Jeśli coś się nie powiodło i chcesz sprawdzić co poszło nie tak, zawsze możesz zalogować się na maszynę wirtualną korzystając z SSH. Warto wtedy sprawdzić zawartość pliku `/var/log/cloud-init.log`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Przystępujemy do kolejnego kroku czyli utworzenia pierwszej instancji Wordpress. Skrypt `cloud-init` różni się tylko treścią pliku `docker-compose.yml`, pozostała część skryptu pozostaje bez zmian."
]
},
{
"cell_type": "code",
"execution_count": 121,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Tworzenie serwera wordpress-1: True\n"
]
}
],
"source": [
"cloud_init_wp1=r'''#cloud-config\n",
"\n",
"# lista podstawowych pakietów, które należy zainstalować\n",
"packages:\n",
" - apt-transport-https\n",
" - ca-certificates\n",
" - curl\n",
" - gnupg-agent\n",
" - software-properties-common\n",
"\n",
"# tworzymy plik docker-compose.yml\n",
"write_files:\n",
" - path: /root/docker-compose.yml\n",
" content: |\n",
" version: '3.9'\n",
"\n",
" services:\n",
" wordpress:\n",
" image: wordpress:latest\n",
" volumes:\n",
" - wordpress_data:/var/www/html\n",
" ports:\n",
" - \"8000:80\"\n",
" restart: always\n",
" environment:\n",
" WORDPRESS_DB_HOST: \"10.10.10.2:3306\"\n",
" WORDPRESS_DB_USER: wordpress\n",
" WORDPRESS_DB_PASSWORD: wordpress\n",
" WORDPRESS_DB_NAME: wordpress\n",
" \n",
" volumes:\n",
" wordpress_data: {}\n",
"\n",
"# instalujemy docker, docker-compose a następnie uruchamiamy naszą bazę danych\n",
"runcmd:\n",
" - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -\n",
" - add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable\"\n",
" - apt-get update -y\n",
" - apt-get install -y docker-ce docker-ce-cli containerd.io\n",
" - curl -L \"https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose\n",
" - chmod +x /usr/local/bin/docker-compose\n",
" - systemctl start docker\n",
" - systemctl enable docker\n",
" - cd /root/ && docker-compose up -d\n",
"'''\n",
"wp1_server = client.servers.create(\n",
" name=\"wordpress-1\", \n",
" server_type=ServerType(\"cx11\"), \n",
" image=Image(name=\"ubuntu-20.04\"), \n",
" ssh_keys=[ssh_key], \n",
" networks=[vnet], \n",
" location=Location(\"hel1\"), \n",
" user_data=cloud_init_wp1\n",
")\n",
"\n",
"wp1_server.action.wait_until_finished()\n",
"print(f\"Tworzenie serwera wordpress-1: {wp1_server.action.complete}\")"
]
},
{
"cell_type": "code",
"execution_count": 122,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Serwer: wordpress-1\n",
"\tpubliczne IP: 65.108.62.231\n",
"\tprywatne IP: 10.10.10.3\n"
]
}
],
"source": [
"wp1_server = client.servers.get_by_name(\"wordpress-1\")\n",
"print(f\"Serwer: {wp1_server.data_model.name}\\n\\tpubliczne IP: {wp1_server.data_model.public_net.ipv4.ip}\\n\\tprywatne IP: {wp1_server.data_model.private_net[0].ip}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Przejdź teraz w przeglądarce pod `http://<publiczny adres IP serwera wordpress-1>:8000` i dokończ instalację Wordpress.\n",
"\n",
"> **Uwaga**: Z pewnością możliwe jest zautoamtyzowanie tego kroku, jednak wykracza to poza zakres tych zajęć.\n",
"\n",
"Teraz musimy utworzyć migawkę tej maszyny wirtualnej a następnie użyć jej do utworzenia nowej maszyny wirtualnej."
]
},
{
"cell_type": "code",
"execution_count": 123,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Serwer wordpress-1 zatrzymany\n",
"Utworzono migawkę serwera wordpress-1: True\n",
"Serwer wordpress-1 uruchomiony\n"
]
}
],
"source": [
"response = wp1_server.power_off()\n",
"response.wait_until_finished()\n",
"print(\"Serwer wordpress-1 zatrzymany\")\n",
"\n",
"response = client.servers.create_image(\n",
" server=wp1_server\n",
")\n",
"response.action.wait_until_finished()\n",
"wp1_image = response.image\n",
"print(f\"Utworzono migawkę serwera wordpress-1: {response.action.complete}\")\n",
"\n",
"\n",
"response = wp1_server.power_on()\n",
"response.wait_until_finished()\n",
"print(\"Serwer wordpress-1 uruchomiony\")"
]
},
{
"cell_type": "code",
"execution_count": 124,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Tworzenie serwera wordpress-2: True\n"
]
}
],
"source": [
"wp2_server = client.servers.create(\n",
" name=\"wordpress-2\", \n",
" server_type=ServerType(\"cx11\"), \n",
" image=wp1_image, # tutaj wykorzystujemy utworzoną wcześniej migawkę\n",
" ssh_keys=[ssh_key], \n",
" networks=[vnet], \n",
" location=Location(\"hel1\") # tym razem nie ma potrzeby podawać skryptu cloud-init\n",
")\n",
"wp2_server.action.wait_until_finished()\n",
"print(f\"Tworzenie serwera wordpress-2: {wp2_server.action.complete}\")"
]
},
{
"cell_type": "code",
"execution_count": 125,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Serwer: wordpress-2\n",
"\tpubliczne IP: 95.217.167.221\n",
"\tprywatne IP: 10.10.10.4\n"
]
}
],
"source": [
"wp2_server = client.servers.get_by_name(\"wordpress-2\")\n",
"print(f\"Serwer: {wp2_server.data_model.name}\\n\\tpubliczne IP: {wp2_server.data_model.public_net.ipv4.ip}\\n\\tprywatne IP: {wp2_server.data_model.private_net[0].ip}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ostatnim krokiem jest konfiguracja mechanizmu równoważenia obciążenia."
]
},
{
"cell_type": "code",
"execution_count": 126,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Mechanizm równoważenia obciążenia został utworzony: True\n"
]
}
],
"source": [
"from hcloud.load_balancer_types.domain import LoadBalancerType\n",
"from hcloud.load_balancers.domain import LoadBalancerAlgorithm, LoadBalancerServiceHttp, LoadBalancerHealthCheck, LoadBalancerService, LoadBalancerHealtCheckHttp, LoadBalancerTarget\n",
"\n",
"lb = client.load_balancers.create(\n",
" name=\"lb-wp\", \n",
" load_balancer_type=LoadBalancerType(name=\"lb11\"),\n",
" location=Location(\"hel1\"),\n",
" services=[\n",
" LoadBalancerService(\n",
" protocol=\"http\", \n",
" listen_port=8000, \n",
" destination_port=8000, \n",
" proxyprotocol=False, \n",
" health_check=LoadBalancerHealthCheck(\n",
" protocol=\"http\", \n",
" port=\"8000\", \n",
" interval=15, \n",
" timeout=10, \n",
" retries=3, \n",
" http=LoadBalancerHealtCheckHttp(\n",
" path=\"/\", \n",
" status_codes=[\"2??\", \"3??\"], \n",
" tls=False\n",
" )\n",
" ),\n",
" http=LoadBalancerServiceHttp(\n",
" sticky_sessions=True,\n",
" cookie_name=\"HCLBSTICKY\",\n",
" cookie_lifetime=300,\n",
" certificates=[]\n",
" )\n",
" )\n",
" ],\n",
" targets=[\n",
" LoadBalancerTarget(\n",
" type=\"server\",\n",
" server=wp1_server,\n",
" use_private_ip=True\n",
" ), \n",
" LoadBalancerTarget(\n",
" type=\"server\",\n",
" server=wp2_server,\n",
" use_private_ip=True\n",
" )\n",
" ],\n",
" public_interface=True,\n",
" network=vnet\n",
")\n",
"lb.action.wait_until_finished()\n",
"print(f\"Mechanizm równoważenia obciążenia został utworzony: {lb.action.complete}\")\n"
]
},
{
"cell_type": "code",
"execution_count": 127,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Publiczny adres IP: 95.217.169.62\n"
]
}
],
"source": [
"lb = client.load_balancers.get_by_name(\"lb-wp\")\n",
"print(f\"Publiczny adres IP: {lb.data_model.public_net.ipv4.ip}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Zweryfikuj instalację w przeglądarce pod adresem: `http://<publiczny adres IP LB>:8000`.\n",
"\n",
"Udało się uzyskać konfigurację analogiczną jak poprzednio, tym razem jednak całość została wykonana za pomocą skryptu w języku Python. Pokazuje to jak bardzo elastyczne może być pracowanie w chmurze w modelu IaaS.\n",
"\n",
"**Po zakończeniu pracy rekomenduje usunięcie wszystkich utworzonych zasobów.**"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Usuwanie 0 mechanizmów LB\n",
"Usuwanie 0 migawek\n",
"Usuwanie 0 serwerów\n",
"Usuwanie 0 kluczy SSH\n",
"Usuwanie 0 sieci wirtualnych\n",
"Usuwanie 0 wolumenów\n",
"\tUsuwanie wolumenu pb-volume: True\n",
"\tUsuwanie wolumenu s470627: True\n",
"\tUsuwanie wolumenu s434804-volume: True\n",
"\tUsuwanie wolumenu s434704-gitea-volume: True\n"
]
}
],
"source": [
"lbs = client.load_balancers.get_all()\n",
"print(f\"Usuwanie {len(lbs)} mechanizmów LB\")\n",
"for s in lbs:\n",
" action = client.load_balancers.delete(s)\n",
" print(f\"\\tUsuwanie LB {s.data_model.name}: {action}\")\n",
"\n",
"images = client.images.get_all(type=\"snapshot\")\n",
"print(f\"Usuwanie {len(images)} migawek\")\n",
"for s in images:\n",
" action = client.images.delete(s)\n",
" print(f\"\\tUsuwanie migawki {s.data_model.name}: {action}\")\n",
"\n",
"servers = client.servers.get_all()\n",
"print(f\"Usuwanie {len(servers)} serwerów\")\n",
"for s in servers:\n",
" action = client.servers.delete(s)\n",
" print(f\"\\tUsuwanie serwera {s.data_model.name} ({s.data_model.public_net.ipv4.ip}): {action.data_model.status}\")\n",
"\n",
"ssh_keys = client.ssh_keys.get_all()\n",
"print(f\"Usuwanie {len(ssh_keys)} kluczy SSH\")\n",
"for s in ssh_keys:\n",
" action = client.ssh_keys.delete(s)\n",
" print(f\"\\tUsuwanie klucza {s.name}: {action}\")\n",
"\n",
"vnets = client.networks.get_all()\n",
"print(f\"Usuwanie {len(vnets)} sieci wirtualnych\")\n",
"for s in vnets:\n",
" action = client.networks.delete(s)\n",
" print(f\"\\tUsuwanie sieci wirtualnej {s.name}: {action}\")\n",
"\n",
"volumes = client.volumes.get_all()\n",
"print(f\"Usuwanie {len(vnets)} wolumenów\")\n",
"for v in volumes:\n",
" action = client.volumes.delete(v)\n",
" print(f\"\\tUsuwanie wolumenu {v.name}: {action}\")\n"
]
}
],
"metadata": {
"interpreter": {
"hash": "98b0a9b7b4eaaa670588a142fd0a9b87eaafe866f1db4228be72b4211d12040f"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

152
03_IaaS/03_zadania.ipynb Normal file
View File

@ -0,0 +1,152 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Zadania domowe\n",
"\n",
"W ramach tego modułu do zdobycia jest 10 punktów. Zadania można realizować z wykorzystaniem dowolnego usługodawcy IaaS (Hetzner, Linode, AWS, Azure). Zadanie 3.1 i 3.2 można wykonać wielokrotnie dla różnych dostawców, zdobywająć kolejne punkty. Wykonanie zadania 3.2 automatycznie oznacza wykonanie zadania 3.1. Pamiętaj, że dobór odpowiedniego dostawcy chmury obliczeniowej do zadania jest częścią jego realizacji.\n",
"\n",
"> **Uwaga**: Łącznie można wykonać zadania za znacznie więcej niż dostępnych 10 punktów. Uzyskany wynik zostanie jednak obcięty do wartości maksymalnej.\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Zadanie 3.1 (2 punkty)\n",
"Celem tego zadania jest przedstawienie sposobu konfiguracji podstawowej infrastruktury chmurowej obejmującej maszyny wirtualne, sieci prywatnej oraz dysków.\n",
"\n",
"Zadanie polega na uruchomieniu systemu [Gitea](https://gitea.io/) w modelu IaaS. Wymagane jest aby:\n",
"- baza danych oraz właściwy serwer Gitea uruchomione były na oddzielnych maszynach wirtualnych\n",
"- całość systemu znajdowała się w sieci prywatnej, a komunikacja pomiędzy bazą danych i serwerem odbywała się wyłącznie w ramach tej sieci\n",
"- baza danych nie była dostępna z poza sieci prywatnej\n",
"- dane z repozytoriów przechowywane były na oddzielnym zasobie dyskowym, który można relokować na inną maszynę w razie potrzeby\n",
"\n",
"> Wskazówka: Rekomendowane jest wykorzystanie narzędzia Docker i oficjalnych obrazów udostępnianych przez [twórców Gitea](https://docs.gitea.io/en-us/install-with-docker-rootless/).\n",
"\n",
"### Sposób sprawdzania zadania\n",
"Zadanie sprawdzane jest poprzez ręczną weryfikację czy system zbudowany został zgodnie ze specyfikacją. Pamiętaj aby przygotować się do prezentacji zadania.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Zadanie 3.2 (4 punkty + 2 punkty za 3.1)\n",
"Zautomatyzuj wykonanie zadania 3.1 tak aby cała infrastruktura (łącznie z zasobami chmurowymi, konfiguracją maszyn i oprogramowania) wykonywana była przez odpowiedni skrypt za pośrednictwem jednej komendy w konsoli.\n",
"\n",
"\n",
"\n",
"Sam skrypt oraz wszystkie niezbędne pliki (np. cloud-init, pliki konfiguracyjne, itp.) powinny znajdować się na repozytorium Git.\n",
"\n",
"> Uwaga: Pamiętaj aby przygotować stosowną dokumentację (w formacie Markdown w pliku README.md) opisującą konfigurację środowiska wymaganą przez ten skrypt (autoryzacja do platform chmury obliczeniowej, zmienne środowiskowe, itp.). Nie powinna ona jednak być zbyt skomplikowana i wykraczać znacznie poza autoryzację do chmury.\n",
"\n",
"> Wskazówka: Technologia w której przygotowany zostanie skrypt nie jest ograniczona, wymagane jest tylko umożliwienie uruchomienia jej na systemie Linux (np. Ubuntu/Debian) bez potrzeby nadmiernej rekonfiguracji systemu. W przypadku potrzeby skorzystania z niestandardowych narzędzi, zalecane jest skorzystanie z narzędzia Docker, zbudowanie specjalnego obrazu i wykonanie skryptu z jego poziomu.\n",
"\n",
"### Sposób sprawdzania zadania\n",
"Zadanie sprawdzane jest ręcznie poprzez sklonowanie repozytorium Git, wykonanie konfiguracji zgodnie z dokumentacją, wywołanie odpowiedniego skryptu i ręczne sprawdzenie czy system został zbudowany zgodnie ze specyfikacją. Skrypt będzie wykonywany w środowisku zapewnionym i skonfigurowanym przez prowadzącego zajęcia. Przykład sposobu wykonania skryptu przez prowadzącego:\n",
"\n",
"```bash\n",
"git clone git@git.wmi.amu.edu.pl:s<index>/<repo_name>.git\n",
"cd <repo_name>\n",
"./deploy.sh\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Zadanie 3.3 (6 punktów)\n",
"Celem tego zadania jest przygotowanie do prowadzenia obliczeń wymagających dużej ilości zasobów obliczeniowych.\n",
"\n",
"Zadanie polaga na przygotowaniu infrastruktury, która pozwoli rozwiązać pewien problem obliczeniowy w krótkim czasie poprzez wykorzystanie zasobów chmury obliczeniowej.\n",
"\n",
"Dana jest następującą funkcja:\n",
"$$\n",
"C_\\sigma(a,b) = \\sum_{i=a}^b f(i) \\mod 999999937\n",
"$$\n",
"\n",
"Zadanie polaga na policzeniu $C_\\sigma(1, 10000)$ dla zadanej odgórnie wartości $\\sigma$.\n",
"\n",
"> **Wskazówka**: Z podstawowych własności arytmetyki modularnej wiadomo, że funckja $C$ jest addytywna modulo $999999937$. Oznacza to, że jeśli $a<b<c$ to $C_\\sigma(a, c) = C_\\sigma(a, b) + C_\\sigma(b+1, c) \\mod 999999937$\n",
"\n",
"\n",
"Dany jest program w postaci binarnej (skompilowanej na architekturę `amd64`, program działa jednowątkowo i ma minimalne wymagania pamięciowe), który liczy wartość $C_\\sigma(a, b)$. Przyjmuje on 3 argumenty i wypisuje na standardowe wyjście jedną liczbę całkowitą stanowiącą wartość $C_\\sigma(a,b)$.\n",
"```bash\n",
" ./computeC <a> <b> <sigma>\n",
"```\n",
"\n",
"Niestety program ten jest dość powolny (wykonanie `./computeC 1 1 1` trwa około 1 sekundy na AWS EC2 t2.micro), a otrzymana wartość $\\sigma$ ważna jest tylko przez 5 minut. W tym czasie na pojedyńczym rdzeniu komputera można policzyć zaledwie około $300$ wartości. Do rozwiązania zdania potrzeba zatem przynajmniej 32 rdzeni liczących to zadanie równolegle i w skoordynowany sposób.\n",
"\n",
"> **Uwaga**: Czas działania programu computeC nie zależy od wartości parametrów wejściowych.\n",
"\n",
"> **Uwaga**: Poprawne rozwiązanie powinno korzystać z zasobów zdalnych. Przykładowo możesz utwożyć odpowiednie zasoby, a następnie wykonać uruchomić program poprzez SSH.\n",
"\n",
"> **Uwaga**: Limit 32 rdzeni wynika z ograniczeń usługodawców chmury obliczeniowej. W większości przypadków bez dodatkowej weryfikacji nie można wykorzystać więcej zasobów.\n",
"\n",
"> **Wskazówka**: Ze względu na koszty, zdecydowanie rekomendowane jest wykorzystanie wielu małych maszyn zamiast jednej dużej. Można też posiłkować się komputerami dostępnymi na WMI w celu zwiększenia mocy.\n",
"\n",
"> \n",
"\n",
"### Sposób sprawdzania zadania\n",
"Zadanie sprawdzane jest automatycznie. \n",
"\n",
"1. Należy wysłać do serwera sprawdzającego zapytanie HTTP w celu przydzielenia wartości $\\sigma$.\n",
" ```\n",
" curl -X GET https://bikol.vm.wmi.amu.edu.pl/pzc/Z3.3/<index>\n",
" ```\n",
"\n",
"1. Korzystając z zasobów chmurowych oraz programu `computeC` należy policzyć wartość $C_\\sigma(a, b)$.\n",
"\n",
"1. Należy przesłać wyliczoną w ten sposób wartość $C_\\sigma(a, b)$ na serwer sprawdzający\n",
" ```\n",
" curl -X POST https://bikol.vm.wmi.amu.edu.pl/pzc/Z3.3/<index>/<wyliczona_wartość>\n",
" ```\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Zadanie 3.4 (3 punkty)\n",
"Zadanie ma na celu zapoznanie z narzędziem [cloud-init](https://cloudinit.readthedocs.io/).\n",
"\n",
"Przygotuj skrypt `cloud-init`, który automatycznie skonfiguruje [przeglądarkową wersje VS Code](https://github.com/cdr/code-server) na utworzonym serwerze.\n",
"\n",
"\n",
"### Sposób sprawdzania zadania\n",
"Zadanie sprawdzane jest ręcznie poprzez utworzenie w infrastrukturze Hetzner maszyny wirtualnej CPX11, skonfigurowanie jej na bazie dostarczonego skryptu `cloud-init` oraz ręczną weryfikację poprawności działania systemu. Skrypt będzie wykonywany w środowisku zapewnionym i skonfigurowanym przez prowadzącego zajęcia."
]
}
],
"metadata": {
"interpreter": {
"hash": "98b0a9b7b4eaaa670588a142fd0a9b87eaafe866f1db4228be72b4211d12040f"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
03_IaaS/obrazy/wp-etap1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
03_IaaS/obrazy/wp-etap2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
03_IaaS/obrazy/wp-etap3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
03_IaaS/zadania/computeC Normal file

Binary file not shown.

203
04_Public_cloud/04_01.ipynb Normal file
View File

@ -0,0 +1,203 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Kompleksowa publiczna chmura obliczeniowa\n",
"\n",
"Niniejszy moduł przedstawia usługi oferowane w ramach Amazon Web Services (AWS). Przedstawione zostaną podstawowe pojęcia związane z tym dostawcą chmury obliczeniowej. Dla dobrego zrozumienia przedstawionego tu materiału niezbędne jest posiadanie podstawowe wiedzy o modelu IaaS przedstawionej w poprzednim module."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"# Amazon Web Services\n",
"\n",
"AWS jest największym na świecie dostawcą usług chmurowych. Oferuje usługi na różnym poziomie zaawansowania i automatyzacji, w modelu IaaS, PaaS oraz SaaS. Jedną z cech charakterystycznych jest silna integracja wszyskich usług oraz hierarhiczna struktura zasobów (zasoby bardziej abstrakcyjne budowne są na bazie zasobów podstawowych).\n",
"\n",
"\n",
"## Usługi i kategorie usług AWS:\n",
"\n",
"Amazon Web Services oferuje uslugi, które można zgrupować w kilka kategorii:\n",
"\n",
"1. Infrastruktura: regiony, AZ, Edge locations\n",
"1. Usługi bazowe: moc obliczeniowa (EC2, automatic scaling, load balancing), sieć (VPC), przechowywanie danych (obiektowe, blokowe, archiwalne)\n",
"1. PaaS: bazy danych (relacyjne, NoSQL, pamięć podręczna), Analityka (data warehouse), usługi dla applikacji (email, wyszukiwanie), zarządzanie wdrożeniem (DevOps, kontenery, usługi mobilne\n",
"1. SaaS: wirtualny pulpit zdalny, webowe IDE, email korporacyjny, współpraca i udostępnienia plików\n",
"\n",
"## AWS Cloud Adoption Framework (AWS CAF)\n",
"\n",
"Amazon zaleca aby przed migracją do chmury AWS, rozważyć wszystkie za i przeciw. W celu ułatwienia tego procesu dostępny jest tak zwany Cloud Adoption Framework. Obejmuje on 6 perspektyw pogrupownych w dwa obszary (capabilities):\n",
"\n",
"1. obszar biznesu:\n",
" - potrzeby biznesowe: czy obszary zastosowania chmury obliczeniowej pokrywają się z działanością organizacji\n",
" - ludzie: czy role i struktura organizacyjna odpowaiada wymaganiom chmury obliczeniowej\n",
" - zarządzanie: czy przyjęty model zarządzania organizacją jest wystarczająco elastyczny aby skorzystać z na migracji do chmury\n",
"1. obszar techniczny:\n",
" - platforma - czy zasoby dostępne w chmurze odpowiadają wymaganiom technicznym, czy architerktura istnijęcych systemów jest odpowiednia dla chmury obliczeniowej\n",
" - bezpieczeństwo - czy wymagania bezpieczeństwa i poufności danych mogą być spełnione w chmurze obliczeniowej\n",
" - działaność operacyjna - czy możliwe będzie prowadzenie codziennnej/miesięcznej/kwartalnej działalności operacyjnej\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## Cennik AWS\n",
"\n",
"Cennik usług AWS jest bardzo złożony, każda usługa ma swoje zasady naliczania opłat. Jednak pewne zasady są ogólne, można wyróżnić 3 główne obszary kosztów:\n",
"\n",
"1. Moc obliczeniowa: opłata naliczna w godzinach lub sekundach\n",
"1. Przechowywanie danych: oplata naliczana za każdy przechowywany GB danych w jednostce czasu\n",
"1. Transfer danych: ruch wychodzący jest płatny za każdy GB (ruch przychodzący jest darmowy)\n",
"\n",
"Ponadto, Amazon ustalając ceny kieruje się następującymi zasadami:\n",
"1. Usługi w modelu pay-as-you-go: pozwala to być elastycznym bez dużych wydatów początkowych i kontraktów długoterminowych\n",
"1. Płacisz mniej jak używasz więcej: w wielu usługach cena za 1 jednostkę spada wraz ze wzrostem zużycia\n",
"1. Darmowy dostęp (free tier): każdy nowy kilent otrzymuje roczny pakiet darmowych zasobów, które może dowolnie wykorzystać\n",
"1. Darmowe usługi dodatkowe: AWS oferuje wiele darmowych usług, które ułatwiają korzystanie z płatnych zasobów\n",
"\n",
"## Współdzielony model odpowiedzialności\n",
"\n",
"AWS jasno określa za co odpowiada i jakie są odpowiedzialności klienta. Zasady te sformułowane są w tak zwanym Współdzielonym modelu odpowiedzialności (ang. shared responsibility model). Zgodnie z nim:\n",
"\n",
"- klient odpowiada za bezpieczeństwo wewnątrz chmury:\n",
" - dane\n",
" - platforma\n",
" - oprogramowanie\n",
" - kontrola dostępu\n",
" - system\n",
" - firewall\n",
" - szyfrowanie danych\n",
" - szyfrownanie komunikacji sieciowej\n",
"- Amazon Web Services odpowiada za bezpieczeństwo chmury:\n",
" - oprogramowanie i sprzęt\n",
" - infrastruktura i fizyczne bezpieczeństwo, \n",
" - bezpieczeńśtwo wirtualizacji\n",
" - sieć\n",
"\n",
"## Wsparcie techniczne\n",
"- basic: darmowy, dokumentacja online\n",
"- dev (czas odpowiedzi do 12h): nielitowana liczba zgłoszeń serwisowych\n",
"- bussiness (czas odpowiedzi do 1h): pełny dostęp do Trusted Advior oraz API do Support Center\n",
"- enterprise (czas odpowiedzi do 15min): przydzielony Technical Account Manager\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Infrastruktura\n",
"Infrastruktura AWS składa się z tak zwanych regionów (ang. region). Region to lokalizacja geograficzna, np. wschodnie USA (us-east). Obecnie publicznie dostępne są 22 regiony (część z nich jest domyślnie wyłączona, ale można je aktywować). Ponadto istnieją regiony prywatne (np. dla administracji rządowej USA). \n",
"\n",
"W ramach danego regionu znajduje się kilka stref dostępności (ang. availibity zone, AZ). Wszystkich AZ jest 69. Strefy dostępności rozlokowane są w danym regionie geograficznym w taki sposób aby były możliwie od siebie niezależne (oddalone o kilkadziesiąt kilometów, niezależne zasilanie, podłącznie do Internetu). Poszczególne strefy dostępności w ramach regionu połączone są również bardzo szybką prywatną siecią światłowodową.\n",
"\n",
"W ramach danej strefy dostępności znajduje się wiele (najczęściej 3) centrów danych (ang. datacenter, DC). W jednym DC znajduje się około 50000-60000 fizycznych serwerów. Klienci nie mają możliwości wpływu na wybór konkretnego DC. \n",
"\n",
"Strefy dostępności należy wykorzystywać w celu uzyskania większej odporności na awarie. Ponadto, dane nie są autoamtycznie replikowane poza dany region, trzeba to zrobić ręcznie jeśli jest taka potrzeba.\n",
"\n",
"Czym się kierować przy wyborze regionu:\n",
"- lokalne przepisy ograniczaniajace przechowywanie danych np. poza UE\n",
"- bliskość do klientów/użytkowników systemu\n",
"- dostępność usług w regionach (nie wszystkie usługi AWS są dostępne w każdym regionie)\n",
"- koszty (nie są równe pomiędzy regionami)\n",
"\n",
"Ponadto amazon dysponuje 187 punktami Point of Presence (w tym edge locations), wykorzystywanymi np. przez CloudFront (sieć dystrybucji CND) czy Route53 (serwer DNS)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Zarządzanie uprawnieniami\n",
"\n",
"System zarządzania uprawnieniami w AWS jest bardzo rozbudowany. Zakładając konto w AWS, otrzymujemy dostęp do tak zwanego konta *Root*. AWS rekomenduje żeby wogóle nie używać tego konta do codziennej pracy. Zalecane jest aby korzystać z osobnego konta IAM, a konto *Root* wykorzystywać tylko wtedy gdy to jest absolutnie konieczne. Ponadto nie powinno się tworzyć kluczy dostępowych do tego konta, dobrze jest też aktywować MFA. Związane jest to z przypisaniem maksymalnych uprawnień do tego konta, uzyskanie dostępu do konta *Root* pozwala uzyskać nieodwracalny dostęp do wszystkich zasobów w chmurze, konta *Root* nie można usunąć ani ograniczyć mu uprawnień.\n",
"\n",
"> **Wskazówka**: AWS CloudTrail pozwala śledzić wszystkie akcje administracyjne na koncie (darmowo za 90 ostatnich dni)\n",
"\n",
"AWS Identity and Access Management (IAM) to darmowa usługa pozwalająca na zarządzanie kontami użytkownika stworzonymi wewnątrz jednego konta głównego. Każde konto może posiadać własne uprawnienia, zapewniając w ten sposób bardzo precyzyjną kontrolę do zasobów i dostępnych akcji. Uprawnienia w IAM można przypisać w ramach:\n",
"- użytkowników IAM (ang. user)\n",
"- grup (ang. group): grupa użytniwików IAM\n",
"- polityk (ang. policy): zestaw uprawnień w JSON\n",
"- ról (ang. role): pozwalających tymczasowo zbobyć uprawnienia do danego zasobu, nie mają długo terminowych sposóbów logowania, przyjmując role otrzymujesz tymczasowy dostęp, najcześciej przypisywane do innych zasobów (np. EC2 uzyskuje w ten sposób dostęp do S3)\n",
"\n",
"Logowanie do AWS na konto użytkownika IAM odbywa się analogicznie jak na konto *Root* : \n",
"- programistycznie za pomocą Secret Access Key\n",
"- w przeglądarce do Web Managment Console za pomocą loginu i hasła (+ MFA)\n",
"\n",
"Politykę dostępu definiowaną w postaci pliku JSON, można określić na dwa sposoby:\n",
"- identity based: przypisane do użytkownika, grupy lub roli\n",
"- resource based: przypisane do zasobu\n",
"\n",
"Domyślnym zachowaniem jest odmowa dostępu (ang. deny), ponadto reguły *deny* mają pierwszeństwo, jeśli gdziekolwiek jest reguła odmawiająca dostępu to nie zależnie od innych uprawnień dostęp do zasobu zostanie zablokowany.\n",
"\n",
"Usługa AWS Organizations uzupełnia IAM o obsługę hierarchi organizacyjnej dla dużych organizacji. Pozwala na zarządzanie kontami poprzez przypisanie ich do zdefiniowanych hierarchicznie jednostek organizacyjnych (OU), analogicznie jak w LDAP. W ramach organizacji możliwe jest zdefiniowanie Service Controlled Policy (SCP), które można przypisać do całej ogranizacji lub dowolnej jednostki organizacyjnej. SCP nie przyznaje uprawnień podaje natomiast maksymalny poziom uprawniń jaki może zostać przyznany przez IAM policy wszystkim użytkownikom i grupom w danej OU.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Wirtualna sieć prywatna (VPC)\n",
"\n",
"AWS oferuje usługę wirtualnej sieci prywatnej pod nazwą Virtual Private Cloud (VPC). VPC to logicznie wydzielona część chmury AWS, zlokalizowana w pojedynczym regionie. W ramach VPC należy następnie zdefiniować podsieci, które są przypisane do konkretnego AZ. W przypadku AWS to właśnie usługa VPC umożliwia przydzielanie zasobów do fizycznych lokalizacji oraz ich separację. Dany zasób jest lokowany na podstawie wirtualnej sieci prywantej oraz podsieci do której został przydzielony.\n",
"\n",
"W przypadku VPC dostępne jest od /16 do /28 adresów. Poniższe 5 adresów zawsze wyłączone z użytku: \n",
"- 10.0.0.0 (adres sieci)\n",
"- 10.0.0.1 (wewnętrzna komunikacja)\n",
"- 10.0.0.2 (DNS)\n",
"- 10.0.0.3 (future)\n",
"- 10.0.0.255 (broadcast)\n",
"\n",
"W VPC każda maszyna dostaje prywatny adres z jednej podsieci. Publiczny adres IP przydzielany jest tylko wtedy, gdy podsieć tego wymaga, lub poprzez Elastic IP. Elastic IP może być przypisany do dowolnej maszyny wirtualnej EC2.\n",
"\n",
"\n",
"Poprawna konfiguracja VPC wymaga też zdefiniowana teblic routingu, domyślnie zapewniona komunikacja wewnątrz VPC (lub podsieci). Pozostałe ustawienia (np. dostęp do Internetu) należy skonfigurować samodzielnie.\n",
"\n",
"Początkowo w każdym regionie zdefiniowane jest domyślne VPC, które standardowo przypisuje publiczne adresy IP maszyną wirtualnym. Domyślnę VPC powinno być używane tylko do eksperymentowania z nowymi usługami. Ponadto, ponieważ konfigurajca VPC jest stosunkowo trudna, szczególnie dla początkujących użytkowników, AWS udostępnia prosty kreator pozwalający zbudować nowe VPC w oparciu o jeden z czterech szablonów.\n",
"\n",
"Ruch sieciowy w ramach VPC można ograniczyć korzystając z dwóch mechanizmów:\n",
"- security groups: przypisane do konkretnej maszyny wirtualnej, określa tylko reguly incoming (domysle wszystko deny), jest to zapora sieciowa typu stateful\n",
"- ACL: przypisane na poziomie podsieci, domyslnie dopuszcza cały ruch w obie strony), jest to rozwiązanie typu stateless"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Zadanie do realizacji na zajęciach\n",
"\n",
"Instalacja Wordpress w AWS z wykorzystaniem Lightsail: https://aws.amazon.com/getting-started/hands-on/launch-load-balanced-wordpress-website/\n",
"\n"
]
}
],
"metadata": {
"interpreter": {
"hash": "98b0a9b7b4eaaa670588a142fd0a9b87eaafe866f1db4228be72b4211d12040f"
},
"kernelspec": {
"display_name": "Python 3.9.5 64-bit ('base': conda)",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.5"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

View File

@ -0,0 +1,9 @@
[Unit]
Description=web service
After=network-online.target
[Service]
ExecStart=/home/dpzc-4/04_Public_cloud/zadania/webservice
[Install]
WantedBy=multi-user.target

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# Praktycznie zastosowania chmury obliczeniowej
Repozytorium z materiałami do zajęć DPZC UI0 w roku akademickim 2021/22.

97
zasady.ipynb Normal file
View File

@ -0,0 +1,97 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Praktyczne zastosowania chmury obliczeniowej\n",
"## Zasady zaliczenia"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Harmonogram zajęć\n",
"\n",
"| Data | ID | Temat | Uwagi |\n",
"| --- | --- | ----- | --- |\n",
"| 2012-10-06 | 01_01 | Zasady zaliczenia, podstawowe informacje o chmurze obliczeniowej | |\n",
"| 2021-10-13 | 02_01 | Chmura obliczeniowa typu PaaS: Heroku | |\n",
"| 2021-10-20 | 02_01 | Chmura obliczeniowa typu PaaS: Heroku c.d. | LAB |\n",
"| 2021-10-27 | 03_01 | Chmura obliczeniowa typu IaaS: wprowadzenie | |\n",
"| 2021-11-03 | 03_02 | Chmura obliczeniowa typu IaaS: anatomia usług | |\n",
"| 2021-11-10 | 03_02 | Chmura obliczeniowa typu IaaS: anatomia usług c.d + dostęp Hetzner| |\n",
"| 2021-11-17 | 03_03 | Chmura obliczeniowa typu IaaS: Hetzner | LAB |\n",
"| 2021-11-24 | 03_04 | Chmura obliczeniowa typu IaaS: Hetzner via Python | LAB |\n",
"| 2021-12-01 | 04_01 | Publiczna chmura obliczeniowa: wprowadzenie do AWS | |\n",
"| 2021-12-08 | - | Odwołane (wyjazd USA) | - |\n",
"| 2021-12-15 | 04_02 | Publiczna chmura obliczeniowa: AWS przez web i CLI | LAB |\n",
"| 2021-12-22 | 04_03 | Publiczna chmura obliczeniowa: AWS przez web i CLI c.d. | LAB |\n",
"| 2021-01-05 | 05_01 | Chmura obliczeniowa typu SaaS | LAB |\n",
"| 2022-01-12 | 06_01 | Usługi typu FaaS / Serverless | LAB |\n",
"| 2021-01-19 | 07_01 | Projekt | LAB |\n",
"| 2021-01-26 | 07_02 | Projekt | LAB |\n",
"| 2021-02-02 | 07_03 | Projekt | LAB |\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Punktacja\n",
"\n",
"W ramach zajęć punkty można zdobyć na dwa sposoby: za aktywność na zajęciach oznaczonych **LAB** w harmonogramie, oraz za rozwiązywanie zadań domowych. Poniższa tabela podaje ile maksymalnie można zdobyć punktów w ramach danego modułu:\n",
"\n",
"| ID | Temat | Za aktywność | Za zadania |\n",
"| --- | --- | --- | --- |\n",
"| 01 | Wprowadzenie | 0 | 0 |\n",
"| 02 | PaaS | 2 | 4 |\n",
"| 03 | IaaS | 4 | 10 |\n",
"| 04 | Chmura publiczna | 4 | 8 |\n",
"| 05 | SaaS | 2 | 6 |\n",
"| 06 | Serverless | 2 | 4 |\n",
"| 07 | Projekt | 6 | 13 |\n",
"| | **Łącznie** | **20** | **45** |\n",
"\n",
"Do zaliczenia zajęć konieczne jest uzyskanie 32 punktów. Osoby, które uzyskają przynajmiej 30 punktów mogą skorzystać z możliwości ustnej dopytki (z zakresu całych zajęć) na ostatnich zajęciach. Dla osób, które nie uzyskają zaliczenia w pierwszym terminie przewidziana jest poprawka.\n",
"\n",
"| Punkty | Ocena |\n",
"| --- | --- |\n",
"| 58-65 | 5.0 |\n",
"| 52-58 | 4.5 |\n",
"| 45-52 | 4.0 |\n",
"| 39-45 | 3.5 |\n",
"| 32-39 | 3.0 |\n",
"| 30-32 | dopytka |\n",
"| 0-30 | poprawka |\n",
"\n",
"Ponadto obowiązkowe jest uczestniczenie w przynajmniej połowie zajęć (8). W przypadku niespełnienia tego kryterium student otrzymuje ocenę niedostateczną z zajęć (2.0), bez prawa do poprawki."
]
}
],
"metadata": {
"interpreter": {
"hash": "98b0a9b7b4eaaa670588a142fd0a9b87eaafe866f1db4228be72b4211d12040f"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}