1. Wprowadzenie
Ostatnia aktualizacja: 1.11.2024
Jak zmodernizować starą aplikację PHP do Google Cloud?
(📽️ obejrzyj 7-minutowy film wprowadzający do tego ćwiczenia)
Często zdarza się, że w firmie działają starsze aplikacje, które wymagają modernizacji. Oznacza to, że są one skalowalne, bezpieczne oraz można je wdrażać w różnych środowiskach.
W ramach warsztatów:
- Skonteneryzuj aplikację PHP.
- Przejdź na zarządzaną bazę danych (Cloud SQL).
- Wdróż w Cloud Run (to alternatywa dla GKE/Kubernetes, która nie wymaga żadnej operacji).
- Zabezpiecz aplikację za pomocą usługi Identity and Access Management (IAM) i Secret Manager.
- zdefiniuj potok CI/CD za pomocą Cloud Build; Usługę Cloud Build można połączyć z repozytorium Git hostowanym u popularnych dostawców Git, takich jak GitHub czy GitLab. Można je aktywować na przykład przy każdym wypychaniu do serwera głównego.
- Przechowuj zdjęcia aplikacji w Cloud Storage. Osiąga się to przez zamontowanie, a aby zmienić aplikację, nie trzeba pisać kodu.
- Przedstawienie funkcji generatywnej AI w narzędziu Gemini, sterowane za pomocą Cloud Functions (bezserwerowej).
- Zapoznaj się z SLOs i działaniem odświeżonej aplikacji.
Dzięki tym instrukcjom możesz stopniowo modernizować aplikację PHP, zwiększając jej skalowalność, bezpieczeństwo i elastyczność wdrożenia. Przejście na Google Cloud umożliwia też korzystanie z jego potężnej infrastruktury i usług, aby zapewnić płynne działanie aplikacji w środowisku natywnym dla chmury.
Wierzymy, że to, czego się nauczysz, wykonując te proste czynności, możesz zastosować w swojej aplikacji i organizacji z użyciem innego języka lub zestawu narzędzi i w innych przypadkach użycia.
Informacje o aplikacji
Aplikacja (kod na podstawie licencji MIT), którą rozgałęzisz, to podstawowa aplikacja PHP 5.7 z uwierzytelnianiem MySQL. Głównym założeniem aplikacji jest zapewnienie platformy, na której użytkownicy mogą przesyłać zdjęcia, a administratorzy mogą oznaczać nieodpowiednie obrazy. Aplikacja ma 2 tabele:
- Użytkownicy. Aplikacja jest wstępnie skompilowana dla administratorów. Mogą się rejestrować nowi użytkownicy.
- Obrazy. Zawiera kilka przykładowych obrazów. Zalogowani użytkownicy mogą przesyłać nowe zdjęcia. Dodamy tu trochę magii.
Twój cel
Chcemy zmodernizować starą aplikację, aby działała w Google Cloud. Będziemy korzystać z tych narzędzi i usług, aby zwiększyć skalowalność, poprawić bezpieczeństwo, zautomatyzować zarządzanie infrastrukturą oraz integrować zaawansowane funkcje, takie jak przetwarzanie obrazów, monitorowanie i przechowywanie danych, korzystając z usług takich jak Cloud SQL, Cloud Run, Cloud Build, Secret Manager i innych.
Co ważniejsze, chcemy, abyś poznawał te informacje krok po kroku, abyś dowiadywał się, jak przebiega proces myślowy związany z każdym krokiem. Zazwyczaj każdy krok otwiera nowe możliwości dla kolejnych (np. moduły 2 -> 3 i 6 -> 7).
Jeszcze nie przekonałeś(-aś) się? Obejrzyj ten 7-minutowy film w YouTube.
Czego potrzebujesz
- Komputer z przeglądarką i połączeniem z internetem.
- Niektóre środki w Google Cloud Platform. Poproś o coś swojego lokalnego fana Google.
- Polecenie
gcloud
działa. - Pracujesz lokalnie? Pobierz aplikację tutaj. Potrzebujesz też dobrego edytora (np. vscode lub intellij).
- Czy chcesz robić wszystko „w chmurze”? Możesz wtedy użyć Cloud Shell.
- Użytkownik GitHuba. Potrzebujesz go, aby utworzyć gałąź oryginalnego kodu 🧑🏻💻 gdgpescara/app-mod-workshop w swoim własnym repozytorium Git. Jest to konieczne, aby mieć własny potok CI/CD (automatyczne potwierdzenie -> kompilacja -> wdrożenie).
Przykładowe rozwiązania znajdziesz tutaj:
- Repozytorium autora: https://github.com/Friends-of-Ricc/app-mod-workshop
- Pierwotne repozytorium warsztatów w
.solutions/
folderach, według rozdziału.
Z tego warsztatu możesz korzystać na lokalnym komputerze lub w całości przeprowadzić w przeglądarce.
2. Konfiguracja kredytu i Fork
Odbierz środki na reklamę w GCP i skonfiguruj środowisko GCP (opcjonalnie)
Aby przeprowadzić te warsztaty, musisz mieć konto rozliczeniowe z odpowiednimi środkami. Jeśli masz już własne ustawienia płatności, możesz pominąć ten krok.
Utwórz zupełnie nowe konto Gmail Google (*), aby połączyć je z środkami na koncie Google Cloud Platform. Poproś nauczyciela o link do wykorzystania środków w GCP lub użyj środków tutaj: bit.ly/PHP-Amarcord-credits .
Zaloguj się na nowo utworzone konto i postępuj zgodnie z instrukcjami.
(
) Dlaczego potrzebuję zupełnie nowego konta Gmail?*
Zaobserwowaliśmy, że osoby, które nie radziły sobie z programem, ponieważ ich konta (w szczególności e-maile związane z pracą lub kontami uczniów) miały wcześniej kontakt z GCP, a zasady organizacji ograniczały możliwość ich wykonywania. Zalecamy utworzenie nowego konta Gmail lub użycie istniejącego konta Gmail (gmail.com), które nie było wcześniej używane do korzystania z Google Cloud Platform.
Kliknij ten przycisk, aby wykorzystać kwotę promocyjną.
Wypełnij formularz, podając swoje imię i nazwisko oraz zaakceptuj Warunki korzystania z usługi.
Może być konieczne odczekanie kilku sekund, aż konto rozliczeniowe pojawi się tutaj: https://console.cloud.google.com/billing
Gdy to zrobisz, otwórz konsolę Google Cloud i utwórz nowy projekt, klikając selektor projektu w menu u góry po lewej stronie, gdzie wyświetla się komunikat „Brak organizacji”. Szczegółowe informacje znajdziesz poniżej
Jeśli jeszcze nie masz projektu, utwórz go, jak pokazano na poniższym zrzucie ekranu. W prawym górnym rogu znajduje się opcja „NOWY PROJEKT”.
Połącz nowy projekt z kontem rozliczeniowym GCP w wersji próbnej w ten sposób:
Możesz już korzystać z Google Cloud Platform. Jeśli jesteś początkującym użytkownikiem lub chcesz wykonywać wszystkie czynności w środowisku chmury, możesz uzyskać dostęp do Cloud Shell i jego edytora za pomocą przycisku w lewym górnym rogu, jak pokazano poniżej.
Upewnij się, że w lewym górnym rogu wybrany jest nowy projekt:
Nie wybrano (nieprawidłowe):
Wybrane (dobrze):
Utwórz rozwidlenie aplikacji na GitHubie
- Otwórz aplikację demonstracyjną: https://github.com/gdgpescara/app-mod-workshop
- Kliknij ikonę 🍴.
- Jeśli nie masz konta GitHub, musisz je utworzyć.
- Edytuj je według własnych potrzeb.
- Skopiuj kod aplikacji za pomocą polecenia git clone https://github.com/<TWÓJ-UŻYTKOWNIK-GITHUB>/<NAZWA-REPOZYTORIUM>
- Otwórz folder z klonowanym projektem w ulubionym edytorze. Jeśli wybierzesz Cloud Shell, możesz to zrobić, klikając „Otwórz edytor”, jak pokazano poniżej.
W edytorze Google Cloud Shell masz wszystko, czego potrzebujesz.
3. Moduł 1. Tworzenie instancji SQL
Utwórz instancję Google Cloud SQL
Nasza aplikacja PHP będzie się łączyć z bazą danych MySQL, dlatego musimy ją skopiować do Google Cloud, aby migracja przebiegła bezproblemowo. Cloud SQL to idealne rozwiązanie, ponieważ umożliwia prowadzenie w chmurze w pełni zarządzanej bazy danych MySQL. Aby to zrobić:
- Otwórz stronę Cloud SQL: https://console.cloud.google.com/sql/instances
- Kliknij „Utwórz instancję”.
- Włącz interfejs API (w razie potrzeby). Może to chwilę potrwać.
- Wybierz MySQL.
- (staramy się zaoferować najtańszą wersję, która będzie działać dłużej):
- Wersja: Enterprise
- Ustawienie: programowanie (wypróbowaliśmy piaskownicę, ale u nas nie zadziałała)
- MySQL w wersji 5.7 (wow, to już przeszłość!)
- Identyfikator instancji: wybierz
appmod-phpapp
(jeśli go zmienisz, pamiętaj, aby odpowiednio zmienić przyszłe skrypty i rozwiązania). - Hasło: dowolne, ale zapisz je jako CLOUDSQL_INSTANCE_PASSWORD
- Region: zachowaj bez zmian dla pozostałej części aplikacji (np. Mediolan =
europe-west8
) - Dostępność w strefie: pojedyncza strefa (oszczędzamy na potrzeby wersji demonstracyjnej)
Kliknij przycisk Utwórz instancję, aby wdrożyć bazę danych Cloud SQL – ⌛ trwa to około 10 minut⌛. Tymczasem czytaj dalej dokumentację; możesz też zacząć rozwiązywać kolejny moduł („Konteneryzowanie aplikacji PHP”), ponieważ w pierwszej części nie ma on zależności od tego modułu (dopóki nie naprawisz połączenia z bazą danych).
Uwaga. Ta instancja powinna kosztować około 7 USD dziennie. Pamiętaj, aby oddzielić go po zakończeniu warsztatów.
Utwórz bazę danych image_catalog i użytkownika w Cloud SQL
Projekt aplikacji zawiera folder db/
z 2 plikami SQL:
- 01_schema.sql : zawiera kod SQL do utworzenia dwóch tabel zawierających dane o użytkownikach i obrazach.
- 02_seed.sql: zawiera kod SQL do zainicjowania danych w uprzednio utworzonych tabelach.
Te pliki zostaną użyte później po utworzeniu bazy danych image_catalog
. Aby to zrobić:
- Otwórz instancję i kliknij kartę Bazy danych:
- kliknij „Utwórz bazę danych”.
- nazwij go
image_catalog
(tak jak w konfiguracji aplikacji PHP).
Następnie tworzymy użytkownika bazy danych. Dzięki temu możemy uwierzytelniać się w bazie danych image_catalog.
- Teraz kliknij kartę Użytkownicy.
- Kliknij „Dodaj konto użytkownika”.
- Użytkownik: Utwórzmy jeden:
- Nazwa użytkownika:
appmod-phpapp-user
- Hasło: wybierz coś, co możesz zapamiętać, lub kliknij „Wygeneruj”.
- Pozostaw opcję „Zezwalaj na dowolnego hosta (%)”.
- kliknij DODAJ.
Otwórz bazę danych dla znanych adresów IP.
Pamiętaj, że wszystkie bazy danych w Cloud SQL są „odizolowane” od samego początku. Dostęp do niej wymaga jawnej konfiguracji sieci.
- Kliknij swoją instancję
- Otwórz menu „Połączenia”.
- Kliknij kartę „Sieć”.
- Kliknij w sekcji Autoryzowane sieci. Teraz dodaj podsieć.
- Na razie zrezygnuj z zabezpieczeń, aby umożliwić działanie aplikacji:
- Nazwa: „Wszyscy na świecie – NIEBEZPIECZNE” (przypominamy, że to tanie rozwiązanie również nie jest bezpieczne).
- Sieć: „0.0.0.0/0” (uwaga: to jest NIEBEZPIECZNE)
Kliknij Zapisz.
Powinien pojawić się ekran podobny do tego:
Uwaga. To rozwiązanie jest dobrym kompromisem, który pozwala zakończyć warsztaty w czasie rzędu O(hours). Zapoznaj się jednak z dokumentem SECURITY, aby dowiedzieć się, jak zabezpieczyć swoje rozwiązanie do wykorzystania w środowisku produkcyjnym.
Czas przetestować połączenie z bazą danych.
Sprawdźmy, czy utworzony wcześniej użytkownik image_catalog
działa. Dostęp do Cloud SQL Studio w ramach instancji i podanie bazy danych, użytkownika i hasła do uwierzytelnienia, jak pokazano poniżej:
Teraz możesz otworzyć edytor SQL i przejść do następnej sekcji.
Importowanie bazy danych z kodu źródłowego
Zaimportuj tabele image_catalog z ich danymi za pomocą Edytora SQL. Pobierz kod SQL z plików sql w repozytorium i wykonaj je jeden po drugim w kolejności. 01_schema.sql, a następnie 02_seed.sql.
Wtedy w tabeli image_catalog powinny pojawić się 2 tabele: users i images, jak pokazano poniżej:
Możesz to przetestować, wykonując w edytorze tę czynność: select * from images;
Zapisz też adres IP publiczny, który będzie Ci potrzebny później.
4. Moduł 2. Konteneryzowanie aplikacji PHP
Chcemy stworzyć tę aplikację na chmurę.
Oznacza to spakowanie kodu w pliku ZIP, który zawiera wszystkie informacje potrzebne do jego uruchomienia w chmurze.
Możesz to zrobić na kilka sposobów:
- Docker. Bardzo popularne, ale prawidłowe skonfigurowanie jest dość skomplikowane.
- Pakiety kompilacji. Mniej popularna, ale zwykle „automatycznie zgaduje”, co budować i co uruchamiać. Często to działa.
W ramach tego warsztatu zakładamy, że używasz Dockera.
Docker
Jeśli zależy Ci na kontroli, jest to rozwiązanie dla Ciebie. Ma to sens, gdy trzeba skonfigurować określone biblioteki i wstrzyknąć pewne nieoczywiste zachowania (np. chmod w przesyłanych plikach lub niestandardowy plik wykonywalny w aplikacji).
Chcemy ostatecznie wdrożyć naszą aplikację skonteneryzowaną w Cloud Run, dlatego zachęcamy do zapoznania się z tą dokumentacją i uzupełnienia pustych pól. Zapewniamy tylko to, co jest niezbędne, aby ułatwić i ułatwić Ci życie. Ostateczny plik Dockerfile będzie wyglądał mniej więcej tak:
# Use an official PHP image with Apache
# Pull a suitable php image
FROM __________# Define the env variable for the Apache listening port 8080
ENV __________
# Set working directory inside the container
WORKDIR __________
# Install required PHP extensions: PDO, MySQL, and other dependencies
RUN __________
# Copy all application files into the container
COPY __________
# Configure Apache to listen on port 8080. Use ‘sed' command to change the default listening port.
RUN __________
# When in doubt, always expose to port 8080
EXPOSE __________
# Start Apache in the foreground
CMD __________
Aby przetestować aplikację lokalnie, musimy zmienić plik config.php w taki sposób, aby aplikacja PHP mogła połączyć się z bazą danych MYSQL dostępną w Google CloudSQL. Na podstawie wcześniejszych ustawień wypełnij puste pola.
- Db_host to publiczny adres IP Cloud SQL. Znajdziesz go w konsoli:
- Wartość Db_name powinna pozostać bez zmian:
image_catalog
- Wartość Db_user powinna być
appmod-phpapp-user
- Db_pass to coś, co wybrałeś. Ustaw go w cudzysłowie i w razie potrzeby użyj znaku ucieczki.
<?php
// Database configuration
$db_host = '____________';
$db_name = '____________';
$db_user = '____________';
$db_pass = '____________';
try {
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Errore di connessione: " . $e->getMessage());
}
session_start();
?>
Możesz też przetłumaczyć kilka włoskich utworów na język angielski z pomocą Gemini.
Masz już plik Dockerfile i skonfigurujesz aplikację PHP tak, aby łączyła się z bazą danych. Wypróbujmy to.
Zainstaluj Dockera, jeśli jeszcze go nie masz (link). Nie musisz tego robić, jeśli używasz Cloud Shell (jak to jest fajne).
Teraz spróbuj utworzyć i uruchomić aplikację PHP w kontenerze za pomocą odpowiednich poleceń docker build i run.
- docker build -t <IMAGE_TAG_NAME> .
- docker run -it -p <CONTAINER PORT>:<LOCAL MACHINE PORT> <IMAGE_TAG_NAME>
Jeśli wszystko działa prawidłowo, po połączeniu z hostem lokalnym powinna wyświetlić się ta strona internetowa.
Jeśli korzystasz z Cloud Shell, możesz też wyeksportować port lokalny (np. 8080) do przeglądarki w ten sposób:
docker build -t my-php-app-docker app-mod-workshop/ -f Dockerfile
docker run -it -p 8080:8080 my-php-app-docker
Gdy już wiesz, że aplikacja działa na porcie 8080, kliknij ikonę „Podgląd w przeglądarce” (przeglądarka z okiem), a następnie Podejrzyj na porcie 8080 (lub „Zmień port” w przypadku dowolnego innego portu).
Testowanie wyniku w przeglądarce
Twoja aplikacja powinna teraz wyglądać mniej więcej tak:
Jeśli zalogujesz się jako Admin/admin123, powinieneś zobaczyć coś takiego.
Świetnie! Działa 🎉🎉🎉
Jeśli dockeryzacja jest prawidłowa, ale dane logowania do bazy danych są nieprawidłowe, możesz zobaczyć komunikat podobny do tego:
Spróbuj jeszcze raz. Jesteś już blisko!
Paczki kompilacji [opcjonalnie]
Dzięki pakietom kompilacji aplikacja jest kompilowana automatycznie. Niestety nie masz pełnej kontroli, więc możesz uzyskać nieoczekiwaną konfigurację.
- Zapoznaj się z BuildPacks w Google Cloud Platform: https://cloud.google.com/docs/buildpacks/build-application i tutaj.
- Zainstaluj
pack
: https://buildpacks.io/docs/for-platform-operators/how-to/integrate-ci/pack/ - pakiety kompilacji w PHP: https://cloud.google.com/docs/buildpacks/php (informacje o konfigurowaniu wersji PHP)
- Aby automatycznie utworzyć obraz kontenera, użyj polecenia podobnego do tego:
pack build --builder=gcr.io/buildpacks/builder my-app-with-buildpacks
W środowisku lokalnym powinien być nowy obraz Dockera. Możesz spróbować uruchomić kontener, ale ponieważ nie mamy pełnej kontroli nad tym, jak obraz został utworzony, aplikacja może nie działać. W każdym razie zachęcamy do eksperymentowania i podzielenia się opinią, jeśli eksperyment się powiedzie. Dziękujemy!
Zapisywanie w Artifact Registry (opcjonalnie)
Do tej pory powinnaś/powinieneś mieć działającą aplikację PHP w kontenerze gotową do wdrożenia w chmurze. Następnie potrzebujemy miejsca w chmurze, w którym będziemy mogli przechowywać obraz Dockera i udostępniać go do wdrożenia w usługach Google Cloud, takich jak Cloud Run. To rozwiązanie do przechowywania nosi nazwę Artifact Registry. Jest to usługa Google Cloud w pełni zarządzana, która służy do przechowywania artefaktów aplikacji, w tym obrazów kontenerów Dockera, pakietów Maven, modułów npm i innych.
Utwórz repozytorium w Google Cloud Artifact Registry, używając odpowiedniego przycisku.
Wybierz prawidłową nazwę, format i region odpowiedni do przechowywania artefaktów.
Wróć do tagu środowiska programistycznego lokalnego i prześlij obraz kontenera aplikacji do utworzonego przed chwilą repozytorium Artifact Registry. Aby to zrobić, wykonaj te polecenia.
- docker tag ŹRÓDŁO_OBRAZU[:TAG] DOCEL_OBRAZU[:TAG]
- docker push TARGET_IMAGE[:TAG]
Wynik powinien wyglądać jak na poniższym zrzucie ekranu.
Hura 🎉🎉🎉, możesz przejść na wyższy poziom.
Notatka. Wypróbuj też punkt końcowy /upload.php
i prześlij zdjęcie. Możesz otrzymać komunikat „Odmowa dostępu”. Jeśli tak, musisz wprowadzić poprawki w sekcji chmod/chown
.Dockerfile
5. Moduł 3. Wdrażanie aplikacji w Cloud Run
Dlaczego warto wybrać Cloud Run?
Dobre pytanie! Jeszcze kilka lat temu z pewnością wybrałbyś/wybrałabyś Google App Engine.
Mówiąc wprost, Cloud Run ma obecnie nowszą technologię, jest łatwiejszy do wdrożenia, tańszy i skaluje się do 0, gdy go nie używasz. Dzięki elastyczności, która umożliwia uruchamianie dowolnego bezstanowego kontenera i integrację z różnymi usługami Google Cloud, idealnie nadaje się do wdrażania mikroserwisów i nowoczesnych aplikacji przy minimalnym nakładzie pracy i maksymalnej wydajności.
Cloud Run to w pełni zarządzana platforma Google Cloud, która umożliwia uruchamianie bezstanowych aplikacji konteneryzowanych w środowisku bezserwerowym. Automatycznie obsługuje całą infrastrukturę, skalując ją od zera do poziomu wymaganego przez napływający ruch i zmniejszając ją, gdy jest nieaktywna. Dzięki temu jest ekonomiczna i wydajna. Cloud Run obsługuje dowolny język lub bibliotekę, o ile są one zapakowane w kontener, co zapewnia dużą elastyczność podczas tworzenia. Integruje się on z innymi usługami Google Cloud oraz nadaje się do tworzenia mikroserwisów, interfejsów API, witryn oraz aplikacji opartych na zdarzeniach bez konieczności zarządzania infrastrukturą serwerową.
Wymagania wstępne
Aby wykonać to zadanie, na komputerze lokalnym musisz zainstalować aplikację gcloud
. Jeśli nie, instrukcje znajdziesz tutaj. Jeśli korzystasz z Google Cloud Shell, nie musisz nic robić.
Przed wdrożeniem...
Jeśli pracujesz w środowisku lokalnym, uwierzytelnij się w Google Cloud, wykonując te czynności:
$ gcloud auth login –update-adc # not needed in Cloud Shell
W tym celu musisz się zalogować w przeglądarce za pomocą OAuth. Zaloguj się w Chrome tym samym użytkownikiem (np. vattelapesca@gmail.com), który jest zalogowany w Google Cloud z włączonym rozliczaniem.
Włącz Cloud Run API za pomocą tego polecenia
$ gcloud services enable run.googleapis.com
W tym momencie wszystko jest gotowe do wdrożenia w Cloud Run.
Wdrażanie aplikacji w Cloud Run za pomocą gcloud
Polecenie, które umożliwia wdrożenie aplikacji w Cloud Run, to gcloud run deploy
. Aby osiągnąć swój cel, możesz ustawić kilka opcji. Minimalny zestaw:
- Nazwa usługi Cloud Run, którą chcesz wdrożyć w aplikacji. Usługa Cloud Run zwróci adres URL, który zawiera punkt końcowy aplikacji.
- Region Google Cloud, w którym będzie działać aplikacja.
- obraz kontenera, który zawiera Twoją aplikację.
- Zmienne środowiskowe, których aplikacja musi używać podczas wykonywania.
- Flaga allow-unauthenticated, która pozwala wszystkim na dostęp do Twojej aplikacji bez dodatkowego uwierzytelniania.
Aby dowiedzieć się, jak zastosować tę opcję w swoim poleceniu, zapoznaj się z tą dokumentacją. Wdrażanie może potrwać kilka minut. Jeśli wszystko jest w porządku, w konsoli Google Cloud Console powinna pojawić się informacja podobna do tej.
Kliknij adres URL podany przez Cloud Run i przetestuj aplikację. Po uwierzytelnieniu powinno pojawić się coś takiego.
„gcloud run deploy” z opcją „bez pytań”
Zauważysz, że gcloud run deploy
zadaje Ci odpowiednie pytania i wypełnia puste miejsca. Jest niesamowicie!
W kilku modułach dodamy jednak to polecenie do reguły Cloud Build, aby uniknąć pytań. Musimy wypełnić wszystkie opcje w komendzie. Chcesz stworzyć złotą biżuterię gcloud run deploy --option1 blah --foo bar --region your-fav-region
. Jak to zrobisz?
- Powtarzaj kroki 2–3–4, aż gcloud przestanie zadawać pytania:
- [LOOP]
gcloud run deploy
z dotychczas znalezionymi opcjami - [LOOP] systems ask for option X
- [LOOP] Wyszukaj w publicznych dokumentach, jak skonfigurować X z poziomu interfejsu wiersza poleceń – dodaj opcję
--my-option [my-value]
. - Wróćmy teraz do kroku 2, chyba że gcloud zakończy bez dalszych pytań.
- To wdrożenie gcloud run BLAH BLAH BLAH jest niesamowite. Zapisz to polecenie gdzieś, ponieważ będzie Ci ono potrzebne w etapu Cloud Build.
Możliwe rozwiązanie znajdziesz tutaj.
Hura! 🎉🎉🎉 Twoja aplikacja została wdrożona w Google Cloud, co oznacza, że wykonałeś/wykonałaś pierwszy krok w modernizacji.
6. Moduł 4. Czyste hasło za pomocą usługi Secret Manager
W poprzednim kroku udało nam się wdrożyć i uruchomić aplikację w Cloud Run. Zrobiliśmy to jednak przy użyciu sprawdzonej metody zapewniania bezpieczeństwa: przekazania niektórych sekretów w formie tekstu nieszyfrowanego.
Pierwsza iteracja: zaktualizuj plik config.php w celu użycia zmiennych środowiskowych
Zauważysz, że hasło do bazy danych zostało umieszczone bezpośrednio w pliku config.php. To wystarczy do celów testowych i sprawdzenia, czy aplikacja działa. Nie możesz jednak używać takiego kodu w środowisku produkcyjnym. Hasło (i inne parametry połączenia z bazą danych) powinno być odczytywane dynamicznie i przekazywane do aplikacji w czasie działania. Zmień plik config.php, aby odczytywał parametry bazy danych z ustawień środowiskowych. Jeśli się nie uda, rozważ ustawienie wartości domyślnych. Jest to przydatne, gdy nie uda Ci się załadować pliku ENV. Wyjście strony poinformuje Cię, czy używa wartości domyślnych. Uzupełnij puste pola i zastąp kod w pliku config.php.
<?php
// Database configuration with ENV variables. Set default values as well
$db_host = getenv('DB_HOST') ?: _______;
$db_name = getenv('DB_NAME') ?: 'image_catalog';
$db_user = getenv('DB_USER') ?: 'appmod-phpapp-user';
$db_pass = getenv('DB_PASS') ?: _______;
// Note getenv() is PHP 5.3 compatible
try {
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Errore di connessione: " . $e->getMessage());
}
session_start();
?>
Aplikacja jest skonteneryzowana, więc musisz podać sposób dostarczania aplikacji zmiennych środowiskowych. Możesz to zrobić na kilka sposobów:
- W momencie kompilacji w pliku Dockerfile. Dodaj do poprzedniego pliku Dockerfile 4 parametry, używając składni ENV DB_VAR=ENV_VAR_VALUE. Spowoduje to ustawienie wartości domyślnych, które można zastąpić w czasie wykonywania. Na przykład zmienne „DB_NAME” i „DB_USER” mogą być ustawione tylko tutaj.
- W czasie wykonywania. Te zmienne możesz skonfigurować w Cloud Run, korzystając z interfejsu wiersza poleceń lub interfejsu użytkownika. To jest odpowiednie miejsce na umieszczenie wszystkich 4 zmiennych (chyba że chcesz zachować domyślne wartości ustawione w pliku Dockerfile).
W localhost możesz umieścić zmienne środowiskowe w pliku .env
(sprawdź folder solutions).
Upewnij się też, że plik .env został dodany do .gitignore
: nie chcesz przecież przesłać swoich tajemnic na Githuba.
echo .env >> .gitignore
Potem możesz przetestować instancję lokalnie:
docker run -it -p 8080:8080 --env-file .env my-php-app-docker
Udało Ci się już:
- Aplikacja będzie dynamicznie odczytywać zmienną z ENV
- Zwiększyłeś/zwiększyłaś bezpieczeństwo, usuwając z kodu hasło do bazy danych.
Możesz teraz wdrożyć nową wersję w Cloud Run. Przejdźmy do interfejsu użytkownika i ręcznie ustaw zmienne środowiskowe:
- Wejdź na https://console.cloud.google.com/run.
- Kliknij aplikację
- Kliknij „Edytuj i wdróż nową wersję”
- Na pierwszej karcie „Kontenery” kliknij dolną kartę „Zmienne i obiekty tajne”.
- Kliknij „+ Dodaj zmienną” i dodaj wszystkie potrzebne zmienne. Powinieneś uzyskać coś takiego:
Czy te dane są idealne? Nie. Twój identyfikator PASS jest nadal widoczny dla większości operatorów. Można temu zapobiec, korzystając z usługi Google Cloud Secret Manager.
Druga iteracja: Secret Manager
Twoje hasła zniknęły z Twojego własnego kodu – zwycięstwo! Ale czy na pewno jesteśmy już bezpieczni?
Twoje hasła są nadal widoczne dla każdego, kto ma dostęp do konsoli Google Cloud. Jeśli otworzysz plik wdrożenia YAML Cloud Run, możesz go pobrać. Jeśli spróbujesz edytować lub wdrożyć nową wersję Cloud Run, hasło będzie widoczne w sekcji Zmienne i sekrety, jak pokazano na poniższych zrzutach ekranu.
Secret Manager w Google Cloud to bezpieczna, scentralizowana usługa do zarządzania informacjami poufnymi, takimi jak klucze interfejsu API, hasła, certyfikaty i inne obiekty tajne.
Umożliwia przechowywanie obiektów tajnych, zarządzanie nimi i uzyskiwanie do nich dostępu za pomocą szczegółowych uprawnień i solidnego szyfrowania. Usługa Secret Manager jest zintegrowana z Identity and Access Management (IAM) w Google Cloud i umożliwia kontrolowanie, kto ma dostęp do poszczególnych obiektów tajnych, co zapewnia bezpieczeństwo danych i zgodność z przepisami.
Umożliwia też automatyczną rotację i wersjonowanie kluczy, upraszcza zarządzanie cyklem życia kluczy oraz zwiększa bezpieczeństwo aplikacji w usługach Google Cloud.
Aby uzyskać dostęp do usługi Secret Manager, w menu Hamburger otwórz usługi Security (Zabezpieczenia) i znajdź tę usługę w sekcji Ochrona danych, jak pokazano na zrzucie ekranu poniżej.
Gdy tam dotrzesz, włącz interfejs Secret Manager API, jak pokazano na poniższym obrazie.
- Teraz kliknij „Utwórz obiekt tajny”: nazwij go na przykład „racjonalnie”:
- Nazwa:
php-amarcord-db-pass
- Wartość obiektu tajnego: Twoje hasło do bazy danych (zignoruj część dotyczącą przesyłania pliku).
- Dodaj adnotację do tego linku do obiektu tajnego, który powinien wyglądać tak:
projects/123456789012/secrets/php-amarcord-db-pass
. To jest unikalny wskaźnik do Twojego obiektu tajnego (w przypadku Terraform, Cloud Run i innych). Numer jest Twoim unikalnym numerem projektu.
Wskazówka: staraj się stosować spójne konwencje nazewnictwa dla swoich sekretów, na przykład: cloud-devrel-phpamarcord-dbpass
- Organizacja (z firmą)
- Zespół (w organizacji)
- Aplikacja (w zespole)
- Nazwa zmiennej (w aplikacji)
Pozwoli Ci to korzystać z łatwych wyrażeń regularnych do znajdowania wszystkich obiektów tajnych w pojedynczej aplikacji.
Tworzenie nowej wersji Cloud Run
Teraz, gdy mamy już nowy tajny klucz, musimy usunąć zmienną środowiskową DB_PASS i zastąpić ją nowym tajnym kluczem. Przykłady:
- Dostęp do Cloud Run przy użyciu konsoli Google Cloud
- Wybierz aplikację.
- Kliknij „Edytuj i wdróż nową wersję”.
- odszukaj kartę „Zmienne i obiekty tajne”.
- Aby zresetować zmienną środowiskową DB_PASS, użyj przycisku „+ Odwołaj się do tajnego klucza”.
- Użyj tej samej wartości „DB_PASS” dla przywołanych obiektów tajnych i użyj najnowszej wersji.
Po zakończeniu powinien pojawić się ten błąd
Spróbuj znaleźć sposób jego rozwiązania. Aby rozwiązać ten problem, musisz otworzyć sekcję Administracja i zmienić uprawnienia. Powodzenia w debugowaniu
Gdy już to wiesz, wróć do Cloud Run i ponownie wdróż nową wersję. Wynik powinien wyglądać tak:
Wskazówka: konsola programisty (UI) doskonale wskazuje problemy z uprawnieniami. Przejdź do wszystkich linków do Twoich elementów w Cloud.
7. Moduł 5. Konfigurowanie CI/CD za pomocą Cloud Build
Dlaczego warto korzystać z potoku CI/CD?
Do tej pory pewnie kilka razy wpisałaś/eś gcloud run deploy
, odpowiadając na to samo pytanie.
Masz dość ręcznego wdrażania aplikacji przy użyciu gcloud run deploy? Czy nie byłoby świetnie, gdyby Twoja aplikacja była wdrażana automatycznie za każdym razem, gdy przenosisz nowe zmiany do repozytorium Git?
Aby korzystać z potoku CI/CD, musisz mieć:
- Osobisty repozytorium Git: w kroku 2. powinieneś(-aś) już utworzyć rozwidlenie repozytorium warsztatów na swoim koncie GitHub. Jeśli nie, wróć i wykonaj ten krok. Twoje rozwidlone repozytorium powinno wyglądać tak:
https://github.com/<YOUR_GITHUB_USER>/app-mod-workshop
- Cloud Build. Ta niesamowita i tania usługa umożliwia konfigurowanie automatyzacji kompilacji praktycznie wszystkiego: Terraform, aplikacji w kontenerach itp.
W tej sekcji skupimy się na konfigurowaniu Cloud Build.
Zacznij korzystać z Cloud Build
W tym celu użyjemy Cloud Build:
- skompilować źródło (za pomocą pliku Dockerfile). Wyobraź sobie, że jest to „duży plik ZIP”, który zawiera wszystko, czego potrzebujesz do jego skompilowania i uruchomienia (tzw. „element kompilacji”).
- przenieść ten artefakt do Artifact Registry (AR).
- Następnie zleć wdrożenie z AR do Cloud Run dla aplikacji „php-amarcord”.
- Spowoduje to utworzenie nowej wersji („zmiana”) istniejącej aplikacji (na przykład warstwy z nowym kodem) i skonfigurowanie jej tak, by w razie powodzenia przekierowywał ruch do nowej wersji.
Oto przykłady niektórych wersji aplikacji php-amarcord
:
Jak to wszystko robimy?
- Utwórz jeden idealny plik YAML:
cloudbuild.yaml
- Przez utworzenie aktywatora Cloud Build.
- Łącząc się z naszym repozytorium GitHub przez interfejs Cloud Build.
Tworzenie reguły (i łączenie repozytorium)
- Otwórz stronę https://console.cloud.google.com/cloud-build/triggers.
- Kliknij „Utwórz aktywator”.
- Kompilacja:
- Nazwa: coś znaczącego, np.
on-git-commit-build-php-app
- Zdarzenie: wypchnięcie do gałęzi
- Źródło: „Połącz nowe repozytorium”
- Po prawej stronie otworzy się okno „Połącz repozytorium”.
- Dostawca źródłowy: „Github” (pierwszy)
- „Dalej”
- Po kliknięciu opcji uwierzytelnienia otworzy się okno w GitHub, w którym będzie można przeprowadzić uwierzytelnienie. Postępuj zgodnie z instrukcjami i zachowaj cierpliwość. Jeśli masz wiele repozytoriów, może to trochę potrwać.
- „Select repo” (Wybierz repozytorium) Wybierz swoje konto lub repozytorium i zaznacz pole „I understand…” (Rozumiem).
- Jeśli otrzymasz błąd: „Aplikacja na GitHubie nie jest zainstalowana w żadnym Twoim repozytorium”, kliknij „Zainstaluj Google Cloud Build” i postępuj zgodnie z instrukcjami.
- Kliknij Połącz
- Bingo! Twoje repozytorium jest teraz połączone.
- Wróć do reguły...
- Konfiguracja: wykrywanie automatyczne (*)
- Zaawansowane: wybierz konto usługi „[NUMER_PROJEKTU]-compute@developer.gserviceaccount.com”
- xxxxx to identyfikator Twojego projektu
- Domyślne konto usługi Compute jest odpowiednie w przypadku metody laboratoryjnej – nie używaj go w środowisku produkcyjnym. ( więcej informacji).
- Pozostaw wszystko inne bez zmian.
- Kliknij przycisk „Utwórz”.
(*) Jest to najprostsza metoda, ponieważ sprawdza plik Dockerfile lub cloudbuild.yaml. Jednak cloudbuild.yaml
daje Ci realną możliwość decydowania, co należy zrobić na danym etapie.
Mam moc!
Aktywator nie będzie działać, dopóki nie przyznasz uprawnień do konta usługi Cloud Build (co to jest konto usługi? Adres e-mail „robota”, który działa w Twoim imieniu w ramach zadania (w tym przypadku tworzenia elementów w chmurze).
Jeśli nie dasz mu uprawnień, nie będzie mógł tworzyć ani wdrażać. Na szczęście to proste.
- otwórz „Budowa w chmurze” > Ustawienia.
- Konto usługi „[PROJECT_NUMBER]- compute@developer.gserviceaccount.com”
- Zaznacz te pola:
- Cloud Run
- Secret Manager
- Konta usługi
- Cloud Build
- Zaznacz też pole „Ustaw jako preferowane konto usługi”.
Gdzie jest plik YAML Cloud Buld?
Zdecydowanie zalecamy, aby poświęcić trochę czasu na utworzenie własnego pliku YAML kompilacji Cloud Build.
Jeśli jednak nie masz czasu lub nie chcesz poświęcić go na tworzenie rozwiązań, możesz znaleźć inspirację w tym folderze rozwiązań: .solutions
Możesz teraz przesłać zmiany do GitHub i obserwować Cloud Build.
Konfigurowanie Cloud Build może być trudne. Spodziewaj się pewnego terminu do:
- Sprawdzanie logów na stronie https://console.cloud.google.com/cloud-build/builds;region=global
- Znajdowanie błędu.
- Naprawić kod i ponownie wydać polecenie git commit / git push.
- Czasami błąd nie jest związany z kodem, ale z jakiś ustawieniami. W takim przypadku możesz uruchomić nową kompilację z poziomu interfejsu użytkownika (Cloud Build > „Aktywatory” > Uruchom).
Jeśli korzystasz z tego rozwiązania, musisz wykonać jeszcze trochę pracy. Na przykład musisz ustawić zmienne ENV dla nowo utworzonych punktów końcowych środowiska programistycznego/produkcyjnego:
Można to zrobić na dwa sposoby:
- Za pomocą interfejsu – przez ponowne ustawienie zmiennych ENV
- Za pomocą CLI, tworząc dla Ciebie „idealny” skrypt. Przykładowy plik znajdziesz tutaj: gcloud-run-deploy.sh. Musisz zmienić kilka rzeczy, np. punkt końcowy i numer projektu. Numer projektu znajdziesz w sekcji Przegląd Cloud.
Jak zatwierdzić kod na GitHubie?
W ramach tego warsztatu nie będziemy uczyć, jak najlepiej publikować git push
na GitHubie. Jeśli jednak masz problemy z Cloud Shell, możesz rozwiązać je na 2 sposoby:
- CLI. Dodaj klucz SSH lokalnie i dodaj zdalne repozytorium za pomocą git@github.com:TWÓJ_UŻYTKOWNIK/app-mod-workshop.git (zamiast http).
- VSCode. Jeśli używasz edytora Cloud Shell, możesz użyć karty Zarządzanie źródłem (Ctrl+Shift+G), kliknąć „Synchronizuj zmiany” i postępować zgodnie z instrukcjami. Powinieneś mieć możliwość uwierzytelnienia swojego konta GitHub w VSCode, dzięki czemu przeciąganie/wrzucanie stanie się dziecinnie proste.
Pamiętaj, aby między innymi wykonać polecenie git add clodubuild.yaml
. W przeciwnym razie działanie nie będzie działać.
Porównanie głębokiego i płytkiego „równego traktowania wersji deweloperskiej i produkcyjnej” [opcjonalnie]
Jeśli skopiujesz wersję modelu tutaj, będziesz mieć 2 identyczne wersje: DEV i PROD. To świetne rozwiązanie, zgodne z regułą 10 aplikacji 12-czynnikowej.
Używamy jednak 2 różnych punktów końcowych w internecie, aby aplikacja wskazywała tę samą bazę danych. Wystarczy to na warsztaty, ale w rzeczywistych warunkach warto poświęcić trochę czasu na stworzenie odpowiedniego środowiska produkcyjnego. Oznacza to posiadanie 2 baz danych (jednej na potrzeby testów, a drugiej na potrzeby produkcji) oraz wybór miejsca, w którym mają się one znajdować na potrzeby odtwarzania awaryjnego lub wysokiej dostępności. To wykracza poza zakres tego warsztatu, ale warto się nad tym zastanowić.
Jeśli masz czas na „głęboką” wersję produkcji, pamiętaj o wszystkich zasobach, które musisz powielić, takich jak:
- Bazy danych Cloud SQL (i prawdopodobnie instancji SQL).
- Zasobnik GCS
- Funkcja w Cloud Functions.
- Możesz używać modelu Gemini 1.5 Flash jako modelu w wersji deweloperskiej (tańszy, szybszy) i modelu Gemini 1.5 Pro (bardziej wydajny).
Za każdym razem, gdy coś zmieniasz w aplikacji, zastanów się, czy w wersji produkcyjnej powinna być ta sama wartość. Jeśli nie, powtórz te czynności. Jest to oczywiście znacznie łatwiejsze dzięki Terraform, który umożliwia wstrzykiwanie środowiska (-dev, -prod) jako sufiksu do zasobów.
8. Moduł 6. Przenoszenie do Google Cloud Storage
Miejsce na dane
Obecnie aplikacja przechowuje stan w kontenerze Dockera. Jeśli maszyna się zepsuje, aplikacja się zawiesi lub po prostu prześlesz nową wersję, zostanie zaplanowane nowe uaktualnienie z wyzerowaniem (=>pustą) pamięci. 🙈
Jak to naprawić? Istnieje kilka sposobów.
- przechowywać obrazy w DB. Tak zrobiłem w przypadku poprzedniej aplikacji PHP. To najprostsze rozwiązanie, ponieważ nie skomplikuje ono aplikacji. Na pewno zwiększa to jednak czas oczekiwania i obciążenie bazy danych.
- Przeprowadź migrację aplikacji Cloud Run do rozwiązania, które ułatwia przechowywanie danych: GCE + dysk stały? Może GKE + miejsce na dane?
- Przejdź do GCS. Google Cloud Storage to najlepsza usługa przechowywania danych w Google Cloud i najbardziej typowe rozwiązanie w chmurze. Wymaga to jednak korzystania z bibliotek PHP. Czy mamy biblioteki PHP 5.7 dla GCS? Czy
PHP 5.7
obsługujeComposer
(wygląda na to, że PHP 5.3.2 to najstarsza wersja obsługiwana przez Composer)? - Możesz użyć dodatku do Dockera.
- Możesz też użyć punktów montowania woluminu Cloud Run w GCS. Brzmi świetnie.
🤔 Przenieś miejsce na dane (otwarte)
[Open Ended] W tym ćwiczeniu chcemy, abyś znalazł(a) sposób na przenoszenie obrazów w sposób, który w jakimś stopniu je utrwala.
Test weryfikacyjny
Nie chcę Ci mówić, jak rozwiązać ten problem, ale chcę, żeby to się stało:
- Przesyłanie
newpic.jpg
. Zobaczysz je w aplikacji. - Uaktualniasz aplikację do nowej wersji.
newpic.jpg
jest nadal widoczny.
💡 Możliwe rozwiązanie (montowanie woluminów Cloud Run w GCS)
Jest to bardzo eleganckie rozwiązanie, które umożliwia przesyłanie plików ze stanem, bez konieczności dotykania kodu (poza wyświetlaniem opisu obrazu, ale to jest trywialne i tylko dla oka).
Dzięki temu możesz zamontować folder z Cloud Run w GCS:
- Wszystkie dane przesłane do GCS będą widoczne w Twojej aplikacji.
- Wszystkie przesłane do aplikacji pliki zostaną faktycznie przesłane do GCS.
- Z obiektami przesłanymi do GCS dzieją się cuda (rozdział 7).
Uwaga. Zapoznaj się z drobnym drukiem dotyczącym FUSE. Nie jest to dopuszczalne, jeśli wydajność jest problemem.
Tworzenie zasobnika GCS
GCS to wszechobecna usługa przechowywania danych w Google Cloud. Jest przetestowana i używana w każdej usłudze GCP wymagającej miejsca na dane.
Pamiętaj, że Cloud Shell eksportuje identyfikator projektu PROJECT_ID jako GOOGLE_CLOUD_PROJECT:
$ export PROJECT_ID=$GOOGLE_CLOUD_PROJECT
#!/bin/bash
set -euo pipefail
# Your Cloud Run Service Name, eg php-amarcord-dev
SERVICE_NAME='php-amarcord-dev'
BUCKET="${PROJECT_ID}-public-images"
GS_BUCKET="gs://${BUCKET}"
# Create bucket
gsutil mb -l "$GCP_REGION" -p "$PROJECT_ID" "$GS_BUCKET/"
# Copy original pictures there - better if you add an image of YOURS before.
gsutil cp ./uploads/*.png "$GS_BUCKET/"
Konfigurowanie Cloud Run do zamontowania zasobnika w folderze /uploads/
Teraz przejdźmy do eleganckiej części. Tworzymy wolumin php_uploads
i dajemy Cloud Run instrukcje, aby zamontował go w kontekście MOUNT_PATH
(coś w stylu /var/www/html/uploads/
):
#!/bin/bash
set -euo pipefail
# .. keep variables from previous script..
# Uploads folder within your docker container.
# Tweak it for your app code.
MOUNT_PATH='/var/www/html/uploads/'
# Inject a volume mount to your GCS bucket in the right folder.
gcloud --project "$PROJECT_ID" beta run services update "$SERVICE_NAME" \
--region $GCP_REGION \
--execution-environment gen2 \
--add-volume=name=php_uploads,type=cloud-storage,bucket="$BUCKET" \
--add-volume-mount=volume=php_uploads,mount-path="$MOUNT_PATH"
Powtórz ten krok w przypadku wszystkich punktów końcowych, które chcesz skonfigurować w usłudze Cloud Storage.
To samo możesz zrobić w interfejsie
- Na karcie „Woluminy” utwórz punkty montowania woluminu wskazujące Twój zasobnik typu „zasobnik Cloud Storage”, na przykład o nazwie „php_uploads”.
- W sekcji Kontenery > Punkty montowania woluminu zamontuj wolumin, który został utworzony na żądanym przez aplikację punkcie woluminu. Zależnie od pliku dockerfile może to wyglądać tak:
var/www/html/uploads/
.
W każdym razie, jeśli wszystko działa, po edytowaniu nowej wersji Cloud Run powinno pojawić się coś takiego:
Teraz przetestuj nową aplikację, przesyłając 1 nowy obraz do punktu końcowego /upload.php
.
Obrazy powinny płynnie przepływać w GCS bez konieczności pisania ani jednej linii kodu PHP:
Co się właśnie stało?
Stało się coś bardzo magicznego.
Stara aplikacja ze starym kodem nadal działa. Nowy, zmodernizowany pakiet komponentów pozwala nam wygodnie przechowywać wszystkie obrazy w naszej aplikacji w zasobach Cloud Bucket. Teraz granicą jest niebo:
- Chcesz wysyłać e-maila za każdym razem, gdy pojawi się obraz z treścią „niebezpieczne” lub „nagość”? Możesz to zrobić bez dotykania kodu PHP.
- Czy chcesz, aby model multimodaly Gemini opisywał każdy obraz, który otrzymasz, i przesyłał opis do bazy danych? Możesz to zrobić bez dotykania kodu PHP. Nie wierzysz? Czytaj dalej w rozdziale 7.
Właśnie otworzyliśmy przed Tobą nowe możliwości.
9. Moduł 7. Wzmocnij swoją aplikację dzięki Google Gemini
Teraz masz świetną zmodernizowaną, nową aplikację PHP (np. 2024 Fiat 126
) z magazynem w chmurze.
Do czego służy
Wymagania wstępne
W poprzednim rozdziale za pomocą modelu rozwiązania mogliśmy podłączyć obrazy /uploads/
do GCS, defacto oddzielając logikę aplikacji od pamięci obrazów.
W tym ćwiczeniu musisz:
- Ukończone ćwiczenie z rozdziału 6 (magazynowanie).
- Utwórz zasobnik GCS z przesyłanymi obrazami, do którego użytkownicy będą przesyłać zdjęcia w Twojej aplikacji.
Konfigurowanie funkcji w Cloud Functions (w języku Python)
Zastanawiasz się, jak wdrożyć aplikację opartą na zdarzeniach? Na przykład:
- gdy <event> wystąpi => wyślij e-maila
- gdy <event> wystąpi => jeśli <condition> ma wartość Prawda, zaktualizuj bazę danych.
Może to być cokolwiek: nowy rekord dostępny w BigQuery, nowy obiekt zmieniony w folderze w GCS lub nowa wiadomość oczekująca w kolejce w Pub/Sub.
Aby to osiągnąć, Google Cloud obsługuje wiele paradygmatów. Najważniejsze:
- EventArc. Dowiedz się, jak otrzymywać zdarzenia GCS. Umożliwia tworzenie DAG-ów i sterowanie działaniami na podstawie instrukcji „jeśli-to-wówczas-wtedy” w chmurze.
- Cloud Scheduler Jest to świetne rozwiązanie np. w przypadku nocnego zadania cron w chmurze.
- Cloud Workflows. Podobnie jak Event Arc, umożliwia:
- Funkcje Cloud Run (znane jako
lambdas
). - Cloud Composer. Jest to w podstawie wersja Apache Airflow od Google, która świetnie sprawdza się też w przypadku DAG-ów.
W tym ćwiczeniu zagłębimy się w funkcję w Cloud Functions, by osiągnąć dość spektakularny wynik. Przekażemy Ci też opcjonalne ćwiczenia.
Pamiętaj, że przykładowy kod jest dostępny w sekcji .solutions/
.
Konfigurowanie funkcji w Cloud Functions (🐍 Python)
Staramy się stworzyć bardzo ambitny GCF.
- Gdy w GCS zostanie utworzony nowy obraz... (prawdopodobnie tak, jak ktoś przesłał to w aplikacji – ale nie tylko).
- .. call Gemini to describe it and get a textual description of the image .. (would be nice to check the MIME and ensure its an image and not a PDF, MP3, or Text)
- .. i zaktualizować bazę danych o ten opis. (może to wymagać wprowadzenia poprawek w bazie danych w celu dodania kolumny
description
do tabeliimages
).
Zmodyfikuj bazę danych, aby dodać description
do obrazów.
- Otwórz Cloud SQL Studio:
- Wpisz użytkownika i hasło do bazy danych Images
- Wstrzyknij ten kod SQL, który dodaje kolumnę opisu obrazu:
ALTER TABLE images ADD COLUMN description TEXT;
I bingo! Aby sprawdzić, czy to zadziałało, wykonaj te czynności:
SELECT * FROM images;
Powinna pojawić się nowa kolumna opisu:
Wpisz w Gemini f(x)
Uwaga. Ta funkcja została utworzona przy użyciu Gemini Code Assist.
Uwaga. Podczas tworzenia tej funkcji mogą wystąpić błędy uprawnień IAM. Niektóre z nich zostały opisane poniżej w sekcji „Możliwe błędy”.
- Włącz interfejsy API
- Otwórz stronę https://console.cloud.google.com/functions/list.
- Kliknij „Utwórz funkcję”.
- Włącz interfejsy API za pomocą kreatora API:
Możesz utworzyć GCF w interfejsie lub w wierszu poleceń. Tutaj użyjemy wiersza poleceń.
Możliwy kod można znaleźć w sekcji .solutions/
- Utwórz folder na kod, np. „gcf/”. Otwórz folder.
- Utwórz plik
requirements.txt
:
google-cloud-storage
google-cloud-aiplatform
pymysql
- Utwórz funkcję w Pythonie. Przykładowy kod znajdziesz tutaj: gcf/main.py.
#!/usr/bin/env python
"""Complete this"""
from google.cloud import storage
from google.cloud import aiplatform
import vertexai
from vertexai.generative_models import GenerativeModel, Part
import os
import pymysql
import pymysql.cursors
# Replace with your project ID
PROJECT_ID = "your-project-id"
GEMINI_MODEL = "gemini-1.5-pro-002"
DEFAULT_PROMPT = "Generate a caption for this image: "
def gemini_describe_image_from_gcs(gcs_url, image_prompt=DEFAULT_PROMPT):
pass
def update_db_with_description(image_filename, caption, db_user, db_pass, db_host, db_name):
pass
def generate_caption(event, context):
"""
Cloud Function triggered by a GCS event.
Args:
event (dict): The dictionary with data specific to this type of event.
context (google.cloud.functions.Context): The context parameter contains
event metadata such as event ID
and timestamp.
"""
pass
- Prześlij funkcję. Możesz skorzystać ze skryptu podobnego do tego: gcf/push-to-gcf.sh.
Uwaga 1. Upewnij się, że źródła środowiskowe mają prawidłowe wartości, lub po prostu dodaj je na górze (GS_BUCKET=blah
, ..):
Uwaga 2. Spowoduje to przesłanie całego kodu lokalnego (.
), więc pamiętaj, aby otoczyć kod określonym folderem i użyć .gcloudignore
jak profesjonalista, aby uniknąć przesyłania ogromnych bibliotek. (na przykład).
#!/bin/bash
set -euo pipefail
# add your logic here, for instance:
source .env || exit 2
echo "Pushing ☁️ f(x)☁ to 🪣 $GS_BUCKET, along with DB config.. (DB_PASS=$DB_PASS)"
gcloud --project "$PROJECT_ID" functions deploy php_amarcord_generate_caption \
--runtime python310 \
--region "$GCP_REGION" \
--trigger-event google.cloud.storage.object.v1.finalized \
--trigger-resource "$BUCKET" \
--set-env-vars "DB_HOST=$DB_HOST,DB_NAME=$DB_NAME,DB_PASS=$DB_PASS,DB_USER=$DB_USER" \
--source . \
--entry-point generate_caption \
--gen2
Uwaga: w tym przykładzie wywoływana będzie metoda generate_caption
, a funkcja usługi w chmurze przekaże do niej zdarzenie GCS wraz ze wszystkimi odpowiednimi informacjami (nazwa zasobnika, nazwa obiektu itp.). Poświęć trochę czasu na debugowanie tego słownika Pythona.
Testowanie funkcji
Testy jednostek
Funkcja ta składa się z wielu ruchomych części. Możesz przetestować wszystkie dostępne opcje.
Przykładem jest plik gcf/test.py.
Interfejs Cloud Functions
Poświęć też trochę czasu na zapoznanie się z funkcją w interfejsie. Warto zapoznać się z każdą kartą, zwłaszcza Source
(moja ulubiona), Variables
, Trigger
i Logs
. Na karcie Logs
spędzisz dużo czasu, rozwiązując błędy (patrz też możliwe błędy na dole tej strony). Sprawdź też kartę Permissions
.
Test E2E
Czas ręcznie przetestować funkcję.
- Otwórz aplikację i zaloguj się.
- Prześlij zdjęcie (nie za duże, mieliśmy problemy z dużymi obrazami)
- sprawdź w interfejsie, czy zdjęcie zostało przesłane.
- Sprawdź w Cloud SQL Studio, czy opis został zaktualizowany. Zaloguj się i uruchom to zapytanie:
SELECT * FROM images
.
I to działa. Możemy też chcieć zaktualizować interfejs, aby wyświetlał ten opis.
Aktualizowanie PHP w celu wyświetlenia [opcjonalnie]
Udowodniliśmy, że aplikacja działa. Byłoby jednak miło, gdyby użytkownicy mogli też zobaczyć ten opis.
Aby dodać opis do index.php
, nie musisz być ekspertem w języku PHP. Ten kod powinien działać (tak, Gemini napisał go też dla mnie):
<?php if (!empty($image['description'])): ?>
<p class="font-bold">Gemini Caption:</p>
<p class="italic"><?php echo $image['description']; ?></p>
<?php endif; ?>
Umieść ten kod wewnątrz foreach
według własnego uznania.
W następnych krokach widzimy ładniejszą wersję UI dzięki Gemini Code Assist. Ładna wersja może wyglądać tak:
Wnioski
W przypadku nowych obiektów w GCS została uruchomiona funkcja Cloud Functions, która może dodawać adnotacje do obrazu tak jak człowiek i automatycznie aktualizować bazę danych. Niesamowite!
Co dalej? Kierując się tym samym rozumowaniem, możesz osiągnąć 2 świetne funkcje.
[Opcjonalnie] Dodawanie kolejnych funkcji Cloud Functions [nieograniczone]
Mam na myśli kilka dodatkowych funkcji.
📩 Aktywator e-maila
Reguła wysyłania e-maili, która wysyła do Ciebie e-maila za każdym razem, gdy ktoś wyśle Ci zdjęcie.
- Zbyt często? Dodaj kolejny warunek: duża grafika lub grafika, której treść zawiera słowa „nagość” lub „przemoc”.
- Sprawdź to na stronie
EventArc
.
🚫 Automatyczna moderacja nieodpowiednich zdjęć
Obecnie administrator zgłasza obrazy jako „nieodpowiednie”. A może Gemini wykona za Ciebie całą robotę i zmoderuje pokój? Dodaj test, aby oznaczać flagą nieodpowiednie treści w aktywatorze, i zaktualizuj bazę danych zgodnie z informacjami z poprzedniej funkcji. Oznacza to, że trzeba wziąć poprzednią funkcję, zmienić prompt i zaktualizować bazę danych na podstawie odpowiedzi.
Zastrzeżenie. Generatywna AI daje nieprzewidywalne dane wyjściowe. Upewnij się, że „dane wyjściowe kreacji” z Gemini są ustawione „na szynach”. Możesz poprosić o deterministyczną odpowiedź, np. o wynik wiarygodności od 0 do 1 lub dane w formacie JSON. Możesz to zrobić na wiele sposobów, np.: * Używając bibliotek Pythona pydantic
, langchain
, .. * Używając uporządkowanych danych Gemini.
Wskazówka: Możesz mieć WIELE funkcji lub pojedynczy prompt, który wymusza odpowiedź w formacie JSON (działa to świetnie z „Gemini Structured Output”, jak zaznaczono powyżej), np.:
Jaki prompt został użyty do wygenerowania tego obrazu?
{
"description": "This is the picture of an arrosticino",
"suitable": TRUE
}
Do promptu możesz dodać dodatkowe pola, aby uzyskać takie statystyki jak: czy jest w nim coś przyjemnego? Nie podoba Ci się to? Czy rozpoznajesz to miejsce? Czy jest jakiś tekst (OCR nigdy nie było prostsze):
goods
: „Wygląda jak pyszne jedzenie”bads
: „Wygląda jak niezdrowe jedzenie”OCR
: "Da consumare preferibilmente prima del 10 Novembre 2024"location
: „Pescara, Lungomare”
Zwykle lepiej jest mieć funkcję N dla N wyników, ale warto też mieć funkcję, która wykonuje 10 działań. Aby dowiedzieć się, jak to zrobić, przeczytaj ten artykuł autorstwa Riccardo.
Możliwe błędy (głównie dotyczące uprawnień)
Gdy po raz pierwszy opracowałam to rozwiązanie, napotkałam na problemy z uprawnieniami IAM. Dodam je tutaj, aby pokazać Ci, z czym masz do czynienia, i podać kilka pomysłów na rozwiązanie problemu.
Błąd: niewystarczające uprawnienia konta usługi
- Pamiętaj, że aby wdrożyć funkcję GCF, która nasłuchuje zasobnika GCS, musisz skonfigurować odpowiednie uprawnienia do konta usługi używanego do wykonania zadania, jak na ilustracji:
Może też być konieczne włączenie interfejsów EventArc API na kilka minut przed tym, jak staną się w pełni dostępne.
Błąd: brakujący wywołujący Cloud Run
- Kolejny komentarz z interfejsu dotyczący uprawnień GCF: (rola wywołującego w Cloud Run):
Ten błąd można naprawić, wykonując polecenie na obrazie, które jest podobne do fix-permissions.sh.
Ten problem jest opisany tutaj: https://cloud.google.com/functions/docs/securing/authenticating
Błąd: przekroczono limit pamięci
Po pierwszym uruchomieniu dziennik mógł zawierać komunikat: „Limit pamięci 244 MiB został przekroczony przy wykorzystaniu 270 MiB. Rozważ zwiększenie limitu pamięci (patrz https://cloud.google.com/functions/docs/configuring/memory). Ponownie dodaj pamięć RAM do GCF. Można to łatwo zrobić w interfejsie. Oto możliwe rozwiązanie:
Możesz też poprawić skrypt wdrażania Cloud Run, aby zwiększyć MEM/CPU. Może to trochę potrwać.
Błąd: PubSub opublikowany
Podczas tworzenia aktywatora za pomocą GCF w wersji 1 wystąpił ten błąd:
Ten problem można łatwo rozwiązać – wystarczy otworzyć Uprawnienia i przypisać do konta usługi rolę „Publikujący w Pub/Sub”.
Błąd: nie użyto Vertex AI
Jeśli pojawi się ten błąd:
Odmowa dostępu: 403 Interfejs Vertex AI API nie był wcześniej używany w projekcie YOUR_PROJECT lub jest wyłączony. Aby go włączyć, wejdź na https://console.developers.google.com/apis/api/aiplatform.googleapis.com/overview?project=YOR_PROJECT.
Wystarczy, że włączysz interfejsy Vertex AI API. Najłatwiejszym sposobem włączenia WSZYSTKICH potrzebnych interfejsów API jest to:
- https://console.cloud.google.com/vertex-ai
- Kliknij „Włącz wszystkie zalecane interfejsy API”.
Błąd: nie znaleziono aktywatora EventArc.
Jeśli otrzymasz takie powiadomienie, ponownie wdróż funkcję.
Błąd: 400 usługa jest przygotowywana
Udostępniam agenty usługi 400 ( https://cloud.google.com/vertex-ai/docs/general/access-control#service-agents). Agenty usługi są wymagane, aby odczytywać udostępniony plik z Cloud Storage. Spróbuj ponownie za kilka minut.
Jeśli tak się stanie, odczekaj chwilę lub poproś o pomoc Googlera.
10. Moduł 8. Tworzenie SLA dostępności
W tym rozdziale staramy się osiągnąć te cele:
- Tworzenie SLI
- Tworzenie SLA na podstawie SLI
- Tworzenie alertów na podstawie docelowych poziomów usług
Jest to bardzo ważny temat dla autora, ponieważ Riccardo pracuje w Google Cloud w obszarze SRE/DevOps.
(otwarte) Utwórz SLI i docelowe poziomy usług dla tej aplikacji
Jak dobra jest aplikacja, jeśli nie można sprawdzić, kiedy jest niedostępna?
Co to jest poziom usług?
O rany! Google wymyśliło docelowe poziomy usług. Aby dowiedzieć się więcej na ten temat, polecam:
- Książka SRE – rozdział 2 – Wdrażanie docelowych poziomów usług (👉 więcej informacji o SREbooks)
- Art of SLO ( świetny film). To świetne szkolenie, które pozwoli Ci dowiedzieć się, jak stworzyć idealne SLO dla swojej usługi.
- SRE course w serwisie Coursera. Ja też dołożyłem swoją cegiełkę.
Krok 1. Utwórz SLI/SLO dostępności
Zacznijmy od dostępności, ponieważ jest to najprostszy i najważniejszy parametr do pomiaru.
Na szczęście Cloud Run jest wyposażony w wstępnie skonfigurowaną obsługę SLO dzięki Istio.
Gdy aplikacja jest uruchomiona w Cloud Run, jest to bardzo proste. Zajmuje to 30 sekund.
- Otwórz stronę Cloud Run.
- Kliknij lub wybierz aplikację.
- Wybierz kartę
SLOs
. - Kliknij „+ Utwórz SLA”.
- Dostępność, na podstawie żądania
- Dalej
- Miesiąc kalendarzowy / 99%.
- kliknij „Utwórz SLA”.
Krok 2. Skonfiguruj alerty dla tego poziomu usług
Proponuję utworzyć 2 alerty:
- Jeden z niskim współczynnikiem spalania („Slowburn”), aby wysyłać powiadomienia e-mailem (symuluje zgłoszenie o niskim priorytecie).
- Jeden z wysokim współczynnikiem spalania („Fastburn”), aby wysyłać powiadomienia SMS-em (symuluje wysoki priorytet / pagera).
Wróć do wcześniejszego SLO tab
.
Zrób to 2 razy:
- Kliknij „Utwórz alert docelowego poziomu usług” (przycisk 🔔 z plusem po prawej stronie).
- Okres wyszukiwania wstecz, próg tempa wykorzystania:
- [FAST]. Pierwszy:
60
min /10
x - [SLOW]. Druga:
720
min /2
x - Kanał powiadomień: kliknij Zarządzaj kanałami powiadomień.
- Najpierw kliknij „E-mail” > Dodaj nowy >.
- Następnie: „SMS” -> Dodaj nowy -> Zweryfikuj przez telefon.
- Wskazówka: lubię używać emotikonów w nazwach. To świetna opcja na potrzeby prezentacji.
- Gdy skończysz, kliknij duży przycisk X w prawym górnym rogu.
- Najpierw wybierz telefon (szybko), a potem e-maila (wolno).
- Dodaj przykładową dokumentację, np.:
[PHP Amarcord] Riccardo told me to type sudo reboot or to check documentation in http://example.com/playbooks/1.php but I guess he was joking
.
Bingo!
Wynik końcowy
Możemy uznać to ćwiczenie za zakończone, gdy będziesz mieć 1 działający docelowy poziom usług i 2 razy więcej alertów dotyczących Twojej dostępności. Otrzymasz też powiadomienie na swój adres e-mail i telefon.
Jeśli chcesz, możesz dodać opóźnienie (bardzo to polecam) lub nawet bardziej złożone opóźnienie. Jeśli czas oczekiwania jest możliwy, określ go, jeśli uważasz, że jest on uzasadniony. W razie wątpliwości wybierz 200 ms.
11. Dalsze kroki
Ukończyłeś WSZYSTKO. Czego brakuje?
Pomysły do przemyślenia:
Graj z Gemini
Gemini może być używane na 2 sposoby:
- Vertex AI. „Metoda dla firm”, która łączy się z GCP, o której mówiliśmy w rozdziale 7 (GCF+Gemini). Cała magia uwierzytelniania działa, a usługi są ze sobą pięknie połączone.
- AI od Google „Sposób konsumenta”. Pobierasz klucz interfejsu Gemini API tutaj i zaczynasz tworzyć małe skrypty, które można powiązać z dowolnym zbiorem zadań, który już masz (prace zastrzeżone, inne chmury, localhost itp.). Wystarczy, że zastąpisz klucz interfejsu API, a kod zacznie działać.
Zachęcamy do wypróbowania (2) własnych projektów z udziałem zwierząt.
Podnoszenie interfejsu użytkownika
Nie znam się z interfejsów. Ale Gemini – tak. Możesz pobrać jedną stronę PHP i powiedzieć coś takiego:
I have a VERY old PHP application. I want to touch it as little as possible. Can you help me:
1. add some nice CSS to it, a single static include for tailwind or similar, whatever you prefer
2. Transform the image print with description into cards, which fit 4 per line in the canvas?
Here's the code:
-----------------------------------
[Paste your PHP page, for instance index.php - mind the token limit!]
Możesz to zrobić w mniej niż 5 minut za pomocą jednej kompilacji w chmurze. :)
Odpowiedź Gemini była idealna (nie musiałam niczego zmieniać):
A oto nowy układ w osobistej aplikacji autora:
Uwaga: kod jest wklejany jako obraz, ponieważ nie chcemy zachęcać Cię do jego pobierania, ale byśmy mogli pozwolić Gemini na jego napisanie za Ciebie z zastosowaniem Twoich własnych ograniczeń interfejsu kreacji/frontendu kreacji. Proszę mi zaufać, po tym czasie zostaną wprowadzone bardzo niewielkie zmiany.
Bezpieczeństwo
Podczas tych 4-godzinnych warsztatów nie zajmujemy się zabezpieczeniem aplikacji.
Więcej pomysłów znajdziesz w SECURITY
doc
.
12. Gratulacje!
Gratulacje! 🎉🎉🎉 udało Ci się zmodernizować Twoją starszą aplikację PHP w Google Cloud.
Podsumowując, w tym ćwiczeniu dowiesz się:
- Jak wdrożyć bazę danych MySQL w Google Cloud SQL i jak przenieść do niej istniejącą bazę danych.
- Jak skonteneryzować aplikację PHP za pomocą Dockera i Buildpacków oraz przechowywać jej obraz w Google Cloud Artifact Registry
- Wdrażanie aplikacji skonteneryzowanej w Cloud Run i uruchamianie jej z Cloud SQL
- Jak w tajemnicy przechowywać i używać poufnych parametrów konfiguracji (np. hasła do bazy danych) za pomocą usługi Google Secret Manager
- Jak skonfigurować potok CI/CD za pomocą Google Cloud Build, aby automatycznie kompilować i wdrażać aplikację PHP po każdym przesłaniu kodu do repozytorium GitHub.
- Jak korzystać z Cloud Storage, aby „przenosić” zasoby aplikacji do chmury
- Jak korzystać z technologii bezserwerowych, aby tworzyć w Google Cloud niesamowite przepływy pracy bez konieczności modyfikowania kodu aplikacji.
- Używaj multimodalnych możliwości Gemini w odpowiednich przypadkach użycia.
To świetny początek modernizacji aplikacji z Google Cloud.
🔁 Opinia
Jeśli chcesz podzielić się z nami opinią na temat warsztatów, wypełnij ten formularz.
Czekamy na Twoją opinię oraz PR za fragmenty kodu, z których jesteś szczególnie dumny/a.
🙏 Pozdrawiamy
Autor dziękuje Mirko Gilioli i Maurizio Ipsale z Datatonic za pomoc w sporządzeniu dokumentacji i przetestowaniu rozwiązania.