Programowanie do produkcji w 3 prostych krokach dzięki Cloud Run

1. Wprowadzenie

Dlaczego zarządzanie aplikacjami jest tak trudne?

Jednym z głównych powodów jest fakt, że deweloperzy często muszą być administratorami systemu na część etatu. Zapoznaj się z tą (częściową) listą problemów podczas tworzenia i wdrażania nowoczesnej aplikacji internetowej klasy produkcyjnej oraz zarządzania nią :

4d018476b4a73b47.png

Nie wiem, jak Ty, ale nie chcę się tym przejmować. Chcę zastanowić się nad logiką mojej aplikacji:

6dfd143d20e5548b.png

Na tym właśnie polega Cloud Run – możesz skupić się na swojej aplikacji, a całą administrację i konserwację przekazać innej osobie, czyli firmie Google, która zainwestowała miliony godzin w doskonalenie i doskonalenie swoich umiejętności w tej dziedzinie.

Oprócz wspomnianych wyżej wyzwań administracyjnych musisz się też zmierzyć:

  • Zależności – środowisko, w którym działa aplikacja, powinno (o ile to możliwe) dokładnie odpowiadać środowisku, w którym została przetestowana. Mogą to być różne wymiary, m.in. system operacyjny, biblioteki pomocnicze, tłumacz lub kompilator języka, konfiguracja sprzętowa i wiele innych czynników.
  • Dystrybucja – przejście z lokalnego wcielenia aplikacji na taką, która jest powszechnie używana w internecie, często wymaga zmiany środowiska wykonawczego, kwantowego skoku złożoności i skrupulatnej nauki.

Cloud Run rozwiąże te i wiele innych problemów. Zamiast wierzyć na słowo, stwórzmy aplikację razem i zobaczmy, jak łatwo można przejść z lokalnego środowiska programistycznego na produkcyjną aplikację w chmurze w zaledwie kilku prostych krokach.

Co możesz zrobić...

  • Utworzysz prostą aplikację internetową i sprawdzisz, czy działa ona zgodnie z oczekiwaniami w Twoim środowisku programistycznym.
  • Następnie przejdziesz do skonteneryzowanej wersji tej samej aplikacji. W trakcie pracy dowiesz się, co oznacza konteneryzacja i dlaczego jest tak przydatna.
  • Na koniec wdrożysz aplikację w chmurze i przekonasz się, jak łatwo można zarządzać usługą Cloud Run za pomocą wiersza poleceń i konsoli Google Cloud.

Czego się nauczysz...

  • Jak utworzyć prostą aplikację serwera WWW w Pythonie
  • Jak spakować aplikację do kontenera Dockera działającego w dowolnym miejscu
  • Jak wdrożyć aplikację w chmurze, aby każdy mógł ją wypróbować
  • Jak jeszcze bardziej uprościć powyższe kroki za pomocą pakietów Buildpacks
  • Jak używać narzędzia wiersza poleceń Google Cloud i interfejsu internetowego konsoli Cloud

Co będzie Ci potrzebne...

  • Przeglądarka
  • konto Google,

Ten moduł jest przeznaczony dla programistów na wszystkich poziomach zaawansowania, w tym początkujących. Chociaż będziesz używać języka Python, nie musisz znać się na programowaniu w tym języku, aby zrozumieć, co się dzieje, ponieważ wyjaśnimy cały używany kod.

2. Konfiguracja

5110b5081a1e1c49.png

W tej sekcji znajdziesz informacje o wszystkim, co jest potrzebne, aby rozpocząć korzystanie z tego modułu.

Samodzielne konfigurowanie środowiska

  1. Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub wykorzystaj już istniejący. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Zapamiętaj identyfikator projektu, unikalną nazwę we wszystkich projektach Google Cloud (powyższa nazwa jest już zajęta i nie będzie Ci odpowiadać). W dalszej części tego ćwiczenia w programie będzie ona określana jako PROJECT_ID.

  1. Następnie musisz włączyć płatności w Cloud Console, aby korzystać z zasobów Google Cloud.

Ukończenie tego ćwiczenia z programowania nie powinno kosztować zbyt wiele. Postępuj zgodnie z instrukcjami podanymi w sekcji „Czyszczenie” W tym samouczku znajdziesz wskazówki, jak wyłączyć zasoby, aby uniknąć naliczania opłat. Nowi użytkownicy Google Cloud mogą skorzystać z programu bezpłatnego okresu próbnego o wartości 300 USD.

Uruchom Cloud Shell

W tym module będziesz pracować w sesji Cloud Shell, która jest tłumaczem poleceń hostowanym przez maszynę wirtualną działającą w chmurze Google. Możesz równie łatwo uruchomić tę sekcję lokalnie na swoim komputerze, ale użycie Cloud Shell zapewni wszystkim dostęp do powtarzalnego środowiska w spójnym środowisku. Po ukończeniu modułu możesz powtórzyć tę sekcję na swoim komputerze.

704a7b7491bd157.png

Aktywowanie Cloud Shell

  1. W konsoli Cloud kliknij Aktywuj Cloud Shell 4292cbf4971c9786.png.

bce75f34b2c53987.png

Jeśli dopiero zaczynasz korzystać z Cloud Shell, wyświetli się ekran pośredni (w części strony widocznej po przewinięciu) z opisem tej funkcji. W takim przypadku kliknij Dalej (nie zobaczysz go więcej). Tak wygląda ten jednorazowy ekran:

70f315d7b402b476.png

Uzyskanie dostępu do Cloud Shell i połączenie się z nim powinno zająć tylko kilka chwil.

fbe3a0674c982259.png

Ta maszyna wirtualna ma wszystkie potrzebne narzędzia dla programistów. Zawiera stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i uwierzytelnianie. Większość czynności z tego ćwiczenia z programowania można wykonać w przeglądarce lub na Chromebooku.

Po nawiązaniu połączenia z Cloud Shell powinno pojawić się potwierdzenie, że użytkownik jest już uwierzytelniony i że projekt jest już ustawiony na identyfikator Twojego projektu.

  1. Uruchom to polecenie w Cloud Shell, aby potwierdzić, że jesteś uwierzytelniony:
gcloud auth list

Dane wyjściowe polecenia

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Uruchom to polecenie w Cloud Shell, aby sprawdzić, czy polecenie gcloud zna Twój projekt:
gcloud config list project

Dane wyjściowe polecenia

[core]
project = <PROJECT_ID>

Jeśli tak nie jest, możesz go ustawić za pomocą tego polecenia:

gcloud config set project <PROJECT_ID>

Dane wyjściowe polecenia

Updated property [core/project].

Ustaw w terminalu zmienne środowiskowe, które ułatwią Ci wykonywanie kolejnych czynności:

export PROJ=$GOOGLE_CLOUD_PROJECT 
export APP=hello 
export PORT=8080
export REGION="us-central1"
export TAG="gcr.io/$PROJ/$APP"

Włączanie interfejsów API

W późniejszych krokach zobaczysz, gdzie te usługi są potrzebne (i dlaczego). Na razie uruchom to polecenie, aby przyznać projektowi dostęp do usług Cloud Build, Container Registry i Cloud Run:

gcloud services enable cloudbuild.googleapis.com         \
                       containerregistry.googleapis.com  \
                       run.googleapis.com          

Powinien wyświetlić się komunikat o powodzeniu podobny do tego:

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

3. Utwórz prostą aplikację internetową

eef530b56b8e93a3.png

Zacznij od kliknięcia przycisku Open Editor u góry panelu Cloud Shell. Wygląda on następująco:

9b81c8a37a6bcdd8.png

Znajdziesz się w środowisku IDE podobnym do Visual Studio Code, w którym możesz tworzyć projekty, edytować kod źródłowy, uruchamiać programy itp. Jeśli ekran jest zbyt mały, możesz rozwinąć lub zmniejszyć linię oddzielającą konsolę od okna edycji/terminalu, przeciągając poziomy pasek między tymi 2 regionami, wyróżniony tutaj:

8dea35450851af53.png

Między Edytorem a terminalem możesz przełączać się między przyciskami Open Editor i Open Terminal. Spróbuj teraz przełączać się między tymi dwoma środowiskami.

Następnie utwórz folder, w którym będą zapisywane Twoje postępy w tym module. W tym celu wybierz Plik > Nowy folder, wpisz hello i kliknij OK. W tym folderze będą przechowywane wszystkie pliki, które utworzysz w tym module, oraz wszystkie czynności, które wykonujesz w Cloud Shell.

Teraz utwórz plik requirements.txt. Dzięki temu Python będzie wiedzieć, od których bibliotek jest wykorzystywana Twoja aplikacja. W tej prostej aplikacji internetowej wykorzystasz popularny moduł Pythona do tworzenia serwerów WWW o nazwie Flask i platformę serwera WWW o nazwie gunicorn. W oknie Edytora Google Cloud kliknij menu Plik > Nowy plik, aby utworzyć nowy plik. Gdy pojawi się prośba o podanie nazwy nowego pliku, wpisz requirements.txt i naciśnij przycisk OK. Nowy plik powinien trafić do folderu projektu hello.

Wpisz następujące wiersze w nowym pliku, aby określić, że aplikacja jest zależna od pakietu Pythona Flask i serwera WWW gunicorn.

Flask
gunicorn

Nie musisz zapisywać tego pliku bezpośrednio, ponieważ edytor Google Cloud zapisze zmiany automatycznie.

Wersja 1. Witaj świecie!

W ten sam sposób utwórz kolejny plik o nazwie main.py. Będzie to główny (i jedyny) plik źródłowy w Pythonie aplikacji. Upewnij się, że nowy plik kończy się w folderze projektu hello.

Wstaw do tego pliku ten kod:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
@app.route("/", methods=["GET"])
def say_hello():
    html = "<h1>Hello world!</h1>"
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Wróć do terminala i przejdź do folderu projektu za pomocą tego polecenia:

cd hello

Uruchom to polecenie, aby zainstalować zależności w projekcie:

pip3 install -r requirements.txt

Teraz uruchom aplikację, uruchamiając w terminalu to polecenie:

python3 main.py

W tym momencie aplikacja działa na maszynie wirtualnej dedykowanej dla sesji Cloud Shell. Cloud Shell zawiera mechanizm serwera proxy, który umożliwia dostęp do serwerów WWW (takich jak właśnie uruchomione) działających w Twojej maszynie wirtualnej z dowolnego miejsca w globalnym internecie.

Kliknij przycisk web preview, a następnie element menu Preview on Port 8080 podobny do tego:

fe45e0192080efd6.png

Otworzy się karta przeglądarki z uruchomioną aplikacją, która powinna wyglądać mniej więcej tak:

b1f06501509aefb9.png

Wersja 2: powtarzanie ścieżki adresu URL

Wróć do edytora Cloud (przez przycisk Open Editor) i dodaj obsługę odczytywania opcjonalnego sufiksu adresu URL, aktualizując plik main.py w ten sposób:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])     # ← NEW
def say_hello(name="world"):               # ← MODIFIED
    html = f"<h1>Hello {name}!</h1>"       # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Przełącz się z powrotem do Terminalu (za pomocą przycisku Open Terminal) i naciśnij control-C (przytrzymaj klawisz Ctrl i naciśnij „C”), aby zatrzymać uruchomioną aplikację, a następnie uruchom ją ponownie, wpisując:

python3 main.py

Ponownie kliknij kolejno przycisk web preview i Preview on Port 8080, aby otworzyć kartę przeglądarki z uruchomioną aplikacją. Powinien znowu pojawić się komunikat „Hello world”. , ale teraz zastąp tekst adresu URL po ukośniku wybranym przez siebie ciągiem (np. /your-name) i sprawdź, czy wyświetlany jest następujący ciąg:

93b87996f88fa370.png

Wersja 3. Kolory losowe

Teraz możesz dodać obsługę losowych kolorów tła. W tym celu wróć do Cloud Editor (za pomocą przycisku Open Editor) i zaktualizuj plik main.py w ten sposób:

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# This function decides whether foreground text should be
# displayed in black or white, to maximize fg/bg contrast.
def set_text_color(rgb):                      # ← NEW
    sum = round(                              # ← NEW
        (int(rgb[0]) * 0.299)                 # ← NEW
        + (int(rgb[1]) * 0.587)               # ← NEW
        + (int(rgb[2]) * 0.114)               # ← NEW
    )                                         # ← NEW
    return "black" if sum > 186 else "white"  # ← NEW


# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
# To verify each new invocation of these requests, the HTML document
# includes CSS styling to produce a randomly colored background.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])
def say_hello(name="world"):
    bg = random.sample(range(1, 255), 3)                       # ← NEW
    hex = (int(bg[0]) * 256) + (int(bg[1]) * 16) + int(bg[2])  # ← NEW
    fg_color = set_text_color(bg)                              # ← NEW
    bg_color = f"#{hex:06x}"                                   # ← NEW
    style = f"color:{fg_color}; background-color:{bg_color}"   # ← NEW
    html = f'<h1 style="{style}">Hello {name}!</h1>'           # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

Przełącz się z powrotem do Terminalu (za pomocą przycisku Open Terminal) i naciśnij control-C (przytrzymaj klawisz Ctrl i naciśnij „C”), aby zatrzymać uruchomioną aplikację, a następnie uruchom ją ponownie, wpisując:

python3 main.py

Ponownie kliknij kolejno przycisk web preview i Preview on Port 8080, aby otworzyć kartę przeglądarki z uruchomioną aplikacją. Powinien wyświetlić się wygenerowany tekst z dowolnym sufiksem lub domyślnym fragmentem „Hello world”. wyświetlany na losowo kolorowym tle, taki jak:

baf8d028f15ea7f4.png

Odśwież stronę kilka razy, aby zobaczyć, że losowy kolor tła zmienia się przy każdym uruchomieniu aplikacji.

I to wszystko na koniec – gratulacje! W następnym kroku dowiesz się, jak spakować aplikację w kontener i dlaczego jest to przydatne.

4. Konteneryzowanie aplikacji

17cc234ec3325a8a.png

Co to jest kontener?

Kontenery, a w szczególności Docker, dają nam możliwość utworzenia modułu, w którym uruchamiamy aplikację ze wszystkimi jej zależnościami. Wynik określamy jako obraz kontenera. W tej sekcji utworzysz obraz kontenera, którego użyjesz do hermetyzacji aplikacji i wszystkich jej zależności.

A jeśli już mowa o zależnościach, w poprzednim kroku, gdy aplikacja działała w środowisku programistycznym, trzeba było uruchomić pip3 install -r requirements.txt i upewnić się, że plik requirements.txt zawiera wszystkie biblioteki zależne i odpowiadające im wersje. W przypadku kontenerów musisz zainstalować te wymagania podczas generowania obrazu kontenera, więc klient nie musi się martwić o instalowanie kontenera.

Ten obraz kontenera będzie podstawowym elementem składowym wdrażania aplikacji w Cloud Run. Kontenery mogą być używane na niemal każdym serwerze wirtualnym lub rzeczywistym, co umożliwia nam wdrażanie aplikacji w dowolnym miejscu i przenoszenie jej z jednego dostawcy usług do drugiego lub z lokalnego i lokalnego serwera do chmury.

Dzięki kontenerom Twoje aplikacje:

  • odtwarzalne – kontenery są autonomiczne i kompletne
  • przenośny – kontenery to międzybranżowe elementy składowe, które umożliwiają przenoszenie aplikacji między różnymi dostawcami i środowiskami chmurowymi

Krótko mówiąc, kontenery umożliwiają „pisanie raz i uruchamianie w dowolnym miejscu”. Wyjątkiem od tej reguły jest to, że wygenerowany kontener będzie działać tylko na typie procesora, na którym został utworzony. Istnieją też sposoby generowania wersji kontenerów dla innych konfiguracji sprzętowych.

Dość gadania – zróbmy kontener! Do utworzenia kontenera o nazwie Docker użyjesz określonej technologii.

W edytorze Cloud utwórz nowy plik o nazwie Dockerfile. Ten plik jest planem tworzenia obrazu. Informuje Dockera o Twoim środowisku operacyjnym i kodzie źródłowym, a także o tym, jak zainstalować zależności, skompilować aplikację i uruchomić kod.

# Use an official lightweight Python image.
FROM python:3.9-slim

# Copy local code to the container image.
WORKDIR /app
COPY main.py .
COPY requirements.txt .

# Install dependencies into this container so there's no need to 
# install anything at container run time.
RUN pip install -r requirements.txt

# Service must listen to $PORT environment variable.
# This default value facilitates local development.
ENV PORT 8080

# Run the web service on container startup. Here you use the gunicorn
# server, with one worker process and 8 threads. For environments 
# with multiple CPU cores, increase the number of workers to match 
# the number of cores available.
CMD exec gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 main:app

W Cloud Terminal utwórz obraz kontenera za pomocą Cloud Build, uruchamiając to polecenie:

gcloud builds submit --tag $TAG

Po przekazaniu kontenera do rejestru zobaczysz komunikat SUCCESS zawierający nazwę obrazu, która powinna wyglądać mniej więcej tak: gcr.io/<project-id>/hello. Obraz zostanie zapisany w Google Container Registry i możesz go użyć w dowolnym momencie i w dowolnym miejscu.

Aby wyświetlić wszystkie obrazy kontenerów powiązane z bieżącym projektem, użyj tego polecenia:

gcloud container images list

Teraz uruchom i przetestuj aplikację lokalnie w Cloud Shell, używając tego polecenia docker:

docker run -p $PORT:$PORT -e PORT=$PORT $TAG

Opcja -p $PORT:$PORT informuje Dockera o mapowaniu zewnętrznego portu $PORT (ustawionego powyżej na 8080) w środowisku hosta na ten sam numer portu w uruchomionym kontenerze. Ułatwia to pracę, ponieważ napisany przez Ciebie kod serwera i numer portu zewnętrznego, z którym się łączysz podczas testowania aplikacji, pozostają takie same (8080). Jednak równie łatwo jest użyć opcji -p, aby zmapować dowolny port zewnętrzny hosta na dowolny wewnętrzny port wewnątrz kontenera.

Opcja -e PORT=$PORT informuje Dockera o udostępnieniu zmiennej środowiskowej $PORT (ustawionej powyżej na wartość 8080) Twojej aplikacji uruchomionej w kontenerze.

Teraz możesz przetestować swoją aplikację. W tym celu wskaż w przeglądarce kod Pythona działający w kontenerze. W oknie Cloud Shell kliknij „Podgląd w przeglądarce”. i wybierz „Podejrzyj na porcie 8080”, tak jak w poprzednim kroku.

Wynik powinien wyglądać znajomo – wygenerowany tekst powinien pojawić się na losowo kolorowym tle, tak jak w przypadku uruchomienia aplikacji bezpośrednio w terminalu Cloud Shell. Odśwież stronę kilka razy, aby zobaczyć, że losowy kolor tła zmienia się przy każdym uruchomieniu aplikacji.

Gratulacje! To jest teraz skonteneryzowana wersja aplikacji. W następnej sekcji bez dotykania wiersza kodu zmienisz obraz kontenera w aplikację internetową o wysokiej jakości produkcyjnej.

5. Do chmury...

1b0665d94750ded6.gif

Teraz gdy aplikacja znajduje się w kontenerze, możesz podzielić się jej z resztą świata, więc nadszedł czas, aby wdrożyć ją w chmurze. Chcesz jednak zrobić coś więcej, niż tylko się dzielić. Upewnij się, że:

  • działa niezawodnie – automatyczne odporność na awarie w przypadku awarii komputera, na którym działa aplikacja;
  • skaluje się automatycznie – aplikacja dotrzymuje kroku dużym natężeniem ruchu i automatycznie zmniejsza swój ślad, gdy nie jest używany
  • minimalizuje koszty, nie obciążając Cię za zasoby, z których nie korzystasz; płacisz tylko za zasoby zużyte podczas reagowania na ruch
  • jest dostępna za pomocą niestandardowej nazwy domeny – masz dostęp do rozwiązania, które pozwala jednym kliknięciem przypisać do Twojej usługi niestandardową nazwę domeny
  • zapewnia doskonały czas reakcji – uruchomienia „na zimno” reagują na działania użytkownika, ale można go dostosować, określając minimalną konfigurację instancji.
  • obsługuje pełne szyfrowanie z wykorzystaniem standardowych zabezpieczeń internetowych SSL/TLS – po wdrożeniu usługi uzyskujesz standardowe szyfrowanie sieciowe i odpowiadające im certyfikaty – bezpłatnie i automatycznie.

Wdrażając aplikację w Google Cloud Run, uzyskasz wszystkie powyższe możliwości.

Wdrażanie aplikacji w Cloud Run

Najpierw zmodyfikujmy Twoją aplikację, aby móc odróżnić nową wersję od starej. Zmodyfikuj plik main.py tak, aby komunikat domyślny zmieniał się z „Hello world!” na „Hello from Cloud Run!”. Inaczej mówiąc, w main.py zmień ten wiersz:

def say_hello(name="world"):

na:

def say_hello(name="from Cloud Run"):

Cloud Run działa regionalnie, co oznacza, że infrastruktura, w której działają usługi Cloud Run, znajduje się w określonym regionie i jest zarządzana przez Google, aby zapewnić nadmiarową dostępność we wszystkich strefach w tym regionie. W sekcji „Przygotowania” powyżej zdefiniujesz region domyślny za pomocą zmiennej środowiskowej REGION.

Ponownie skompiluj obraz kontenera i wdróż skonteneryzowaną aplikację w Cloud Run za pomocą tego polecenia:

gcloud builds submit --tag $TAG
gcloud run deploy "$APP"   \
  --image "$TAG"           \
  --platform "managed"     \
  --region "$REGION"       \
  --allow-unauthenticated
  • Możesz również określić region domyślny za pomocą atrybutu gcloud config set run/region $REGION.
  • Opcja --allow-unauthenticated powoduje udostępnienie usługi publicznie. Aby uniknąć nieuwierzytelnionych żądań, używaj zamiast tego --no-allow-unauthenticated.

Podany tu obraz to obraz Dockera utworzony w ostatnim kroku. Dzięki usłudze Cloud Build, która zapisała utworzony obraz w Google Container Registry, usługa Cloud Run może go znaleźć i wdrożyć za Ciebie.

Poczekaj chwilę na zakończenie wdrażania. Kiedy operacja zostanie wykonana, w wierszu poleceń wyświetli się URL usługi:

Deploying container to Cloud Run service [hello] in project [PROJECT_ID...
✓ Deploying new service... Done.                                   
  ✓ Creating Revision... Revision deployment finished. Waiting for health check...
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [hello] revision [hello-...] has been deployed and is serving 100 percent of traffic.
Service URL: https://hello-....a.run.app

Adres URL usługi możesz też pobrać za pomocą tego polecenia:

gcloud run services describe hello  \
  --platform managed                \
  --region $REGION                  \
  --format "value(status.url)"

Powinno wyświetlić się coś takiego:

https://hello-....a.run.app

Ten link to specjalny adres URL z zabezpieczeniami TLS, dla Twojej usługi Cloud Run. Link jest trwały (o ile nie wyłączysz usługi) i można go używać w dowolnym miejscu w internecie. Nie wykorzystuje wspomnianego wcześniej mechanizmu serwera proxy Cloud Shell, który bazował na przejściowej maszynie wirtualnej.

Kliknij podświetlony Service URL, aby otworzyć kartę przeglądarki z uruchomioną aplikacją. W wyniku powinien wyświetlić się komunikat „Hello from Cloud Run!”. na losowo kolorowym tle.

Gratulacje! Twoja aplikacja działa teraz w Google Cloud. Twoja aplikacja jest dostępna publicznie, z szyfrowaniem TLS (HTTPS) i automatycznym skalowaniem do poziomu natężenia ruchu, o którym nawet nie musisz pamiętać.

Ale myślę, że ten proces może być jeszcze prostszy...

6. Automagiczne tworzenie kontenera

To całkiem fajne, ale co w przypadku, gdy w ogóle nie chcę myśleć o plikach Dockerfile i kontenerach? A jeśli tak, jak większość programistów, chcę tylko skupić się na pisaniu kodu aplikacji i pozwolić, aby ktoś inny zajął się jego konteneryzacją. Na szczęście Cloud Run obsługuje standard typu open source o nazwie Buildpacks, który istnieje właśnie z tego powodu: do automatyzacji procesu tworzenia kontenera na podstawie zbioru plików źródłowych.

W niektórych przypadkach deweloper może preferować użycie jawnie zdefiniowanego pliku Dockerfile, na przykład jeśli chce w dużym stopniu dostosować sposób tworzenia kontenera. W typowych przypadkach, takich jak to ćwiczenie, kompilacje działają dobrze i nie trzeba ręcznie tworzyć Dockerfile. Zmodyfikujmy Twój kod, aby używał pakietów kompilacji.

Najpierw zmodyfikujmy Twoją aplikację, aby móc odróżnić nową wersję od starej. Zmodyfikuj plik main.py tak, aby komunikat domyślny zmienił się z „Hello from Cloud Run!”. do „Hello from Cloud Run with Buildpacks!” (Witaj z poziomu Cloud Run with Buildpacks). Inaczej mówiąc, w main.py zmień ten wiersz:

def say_hello(name="from Cloud Run"):

na:

def say_hello(name="from Cloud Run with Buildpacks"):

Aby wykorzystać możliwości pakietów kompilacji, utwórz nowy plik o nazwie Procfile. Utwórz plik w edytorze Cloud i wstaw ten 1 wiersz tekstu:

web: python3 main.py

Informuje on system kompilacji, jak uruchomić aplikację w kontenerze wygenerowanym automatycznie. Dzięki takiej instrukcji nie jest już potrzebny plik Dockerfile. Aby to sprawdzić, usuń plik Dockerfile i uruchom w terminalu Cloud Shell to polecenie:

gcloud beta run deploy "$APP"  \
    --source .                 \
    --platform "managed"       \
    --region "$REGION"         \
    --allow-unauthenticated

Jest to podobne do polecenia uruchomionego w ostatnim kroku w celu wdrożenia aplikacji, ale tym razem opcję --image zastąpiliśmy opcją --source .. Informuje to polecenie gcloud, że ma ono używać pakietów kompilacji do utworzenia obrazu kontenera na podstawie plików źródłowych, które znajdzie w bieżącym katalogu (dot w pliku --source . to skrócony skrót dla bieżącego katalogu). Usługa domyślnie zajmuje się obrazem kontenera, więc nie musisz określać obrazu w tym poleceniu gcloud.

Ponownie sprawdź, czy wdrożenie zadziałało – kliknij zaznaczony przycisk Service URL, aby otworzyć kartę przeglądarki z działającą aplikacją, i sprawdź, czy usługa wyświetla komunikat „Hello from Cloud Run with Buildpacks!” (Witaj z Cloud Run with Buildpacks). na losowo kolorowym tle.

Zwróć uwagę, że dzięki pakietom kompilacji do utworzenia Dockerfile udało Ci się skrócić te trzy proste kroki do dwóch:

  1. Tworzenie aplikacji w środowisku programistycznym
  2. Wdróż w chmurze dokładnie ten sam kod za pomocą jednego polecenia.

7. Czy muszę używać wiersza poleceń?

Nie! Podobnie jak w przypadku niemal każdej usługi Google Cloud, z Cloud Run można korzystać na 3 sposoby:

  • Przyznane przed chwilą narzędzie wiersza poleceń gcloud.
  • Zaawansowany internetowy interfejs użytkownika w konsoli Cloud, który obsługuje intuicyjny styl interakcji typu „wskaż i kliknij”.
  • W sposób zautomatyzowany korzystanie z bibliotek klienta Google dostępnych w wielu popularnych językach, takich jak Java, C#, Python, Go, JavaScript, Ruby czy C/C++.

Wdróżmy dodatkową instancję Twojej aplikacji Cloud Run za pomocą interfejsu konsoli. Przejdź do strony docelowej usługi Cloud Run, korzystając z menu w lewym górnym rogu:

e2b4983b38c81796.png

Zobaczysz podsumowanie swoich usług Cloud Run, na przykład:

b335e7bf0a3af845.png

Kliknij „Utwórz usługę”. link do rozpoczynania procesu wdrażania:

51f61a8ddc7a4c0b.png

Wpisz „Witaj ponownie” jako nazwę usługi, wybierz domyślną platformę wdrożenia i region, a następnie kliknij „Dalej”.

8a17baa45336c4c9.png

Wpisz adres URL obrazu kontenera: gcr.io/cloudrun/hello, czyli kontenera stworzonego przez Google do celów testowych, i kliknij „Ustawienia zaawansowane” aby wyświetlić niektóre z dostępnych ustawień. Niektóre z nich możesz dostosować:

  • numer portu i punkt wejścia kontenera (zastępujący punkt wejścia określony podczas tworzenia kontenera)
  • sprzęt: pamięć i liczba procesorów.
  • skalowanie: minimalna i maksymalna liczba instancji
  • zmienne środowiskowe
  • inne: ustawienie limitu czasu żądania, maksymalna liczba żądań na kontener, HTTP/2

Kliknij przycisk „Dalej”. aby przejść dalej w tym oknie. W następnym oknie możesz określić sposób wywoływania usługi. W sekcji „Ruch przychodzący” wybierz „Zezwalaj na cały ruch”, a w sekcji „Uwierzytelnianie” wybierz „Zezwalaj na nieuwierzytelniony ruch”.

e78281d1cff3418.png

Są to najbardziej liberalne ustawienia, ponieważ umożliwiają każdemu dostęp do Twojej aplikacji Cloud Run z dowolnego miejsca w publicznym internecie bez konieczności podawania danych uwierzytelniających. Możesz potrzebować bardziej restrykcyjnych ustawień, ale w tym ćwiczeniu skupimy się na prostych rozwiązaniach.

Teraz kliknij przycisk Create, aby utworzyć usługę Cloud Run. Po kilku sekundach nowa usługa powinna pojawić się na liście podsumowania usług Cloud Run. Wiersz podsumowania zawiera najnowsze wdrożenie (datę/godzinę i autora) wraz z kluczowymi ustawieniami konfiguracji. Kliknij link z nazwą usługi, aby wyświetlić szczegółowe informacje na temat nowej usługi.

Aby zweryfikować usługę, kliknij adres URL u góry strony podsumowania, jak pokazano w poniższym przykładzie:

6c35cf0636dddc51.png

Powinien pojawić się ekran podobny do tego:

3ba6ab4fe0da1f84.png

Po wdrożeniu nowej usługi Cloud Run kliknij kartę REVISIONS, aby poznać sposoby zarządzania wieloma wdrożeniami.

2351ee7ec4a356f0.png

Aby wdrożyć nowe wersje bezpośrednio z poziomu konsoli, możesz kliknąć przycisk EDIT & DEPLOY NEW REVISION, jak pokazano na przykładowym zrzucie ekranu poniżej:

a599fa88d00d6776.png

Kliknij ten przycisk teraz, aby utworzyć nową wersję. Obok adresu URL kontenera kliknij przycisk SELECT, jak pokazano poniżej:

5fd1b1f8e1f11d40.png

W wyświetlonym oknie znajdź prostą aplikację internetową wdrożoną wcześniej z Cloud Build przy użyciu pakietów Buildpacks i kliknij „Wybierz”. Pamiętaj, aby wybrać obraz kontenera

gcr.io/<project>/cloud-run-source-deploy

folder w ten sposób:

8a756c6157face3a.png

Następnie przewiń w dół i kliknij przycisk DEPLOY. Wdrożyłeś(-aś) nową wersję aplikacji. Aby to sprawdzić, wejdź jeszcze raz na adres URL swojej usługi i sprawdź, czy wyświetla się kolorowy komunikat „Hello from Cloud Run with Buildpacks!” (Witaj z Cloud Run with Buildpacks). aplikacji internetowej.

Jak widać, na karcie Wersje znajdziesz podsumowanie każdej wdrożonej wersji. Powinny być teraz widoczne 2 wersje tej usługi. Możesz wybrać daną wersję, klikając przycisk po lewej stronie nazwy wersji. Po prawej stronie ekranu zostanie wyświetlone podsumowanie szczegółów wersji. Po kliknięciu tych przycisków widać, że dwie wersje pochodzą z dwóch różnych obrazów kontenerów.

Przycisk MANAGE TRAFFIC umożliwia zmianę rozkładu żądań przychodzących wysyłanych do danej wersji. Możliwość dostosowania ilości ruchu wysyłanego do danej wersji umożliwia kilka cennych zastosowań:

  • testy do wczesnych testów nowej wersji aplikacji z niewielką częścią ruchu przychodzącego.
  • przywrócenie ruchu z problematycznej wersji do poprzedniej wersji
  • Testy A/B

Przycisk MANAGE TRAFFIC znajdziesz tutaj:

519d3c22ae028287.png

Skonfiguruj podział ruchu 50/50 między 2 wersje, określając podział ruchu 50/50 w ten sposób:

8c37d4f115d9ded4.png

Teraz kliknij przycisk ZAPISZ i sprawdź podział 50/50, odwiedzając wielokrotnie adres URL swojej usługi. Następnie sprawdź, czy średnio połowa żądań jest obsługiwana przez bieżącą wersję („Hello from Cloud Run with Buildpacks!”), a połowa jest obsługiwana przez poprzednią wersję („To działa”).

Inne karty na stronie Szczegóły usługi umożliwiają monitorowanie wydajności, ruchu i logów, co zapewnia cenny wgląd w intensywność i jakość działania usługi. Za pomocą sekcji „Uprawnienia” możesz też dostosować dostęp do usługi. . Poświęć chwilę na zapoznanie się z kartami na tej stronie i poznaj funkcje dostępne na tej stronie.

Interfejs automatyzacji

Jak wspomnieliśmy wcześniej, możesz też automatycznie tworzyć i wdrażać usługi Cloud Run oraz nimi zarządzać. W przypadku zadań ręcznych ta opcja jest bardziej zaawansowana niż użycie wiersza poleceń i konsoli sieciowej, ale z pewnością nadaje się do automatyzacji usług Cloud Run. Biblioteki klienta Google możesz używać w kilku popularnych językach programowania.

8. Testowanie aplikacji

198ada162d1f0bf1.png

W tym ostatnim kroku przeprowadzisz sztuczny test obciążenia, aby przetestować aplikację w warunkach skrajnych i sprawdzić, jak skaluje się w zależności od przychodzącego popytu. Użyjesz narzędzia hey, które jest już zainstalowane w Cloud Shell i pozwala nam przeprowadzać testy obciążenia i przedstawiać wyniki.

Przeprowadź test

Aby uruchomić test obciążenia, w terminalu Cloud Shell uruchom to polecenie:

hey -q 1000 -c 200 -z 30s https://hello-...run.app

Argumenty polecenia są interpretowane w ten sposób:

  • -q 1000 – spróbuj zwiększyć obciążenie z szybkością około 1000 żądań na sekundę
  • -c 200 – przydziel 200 równoległych instancji roboczych
  • -z 30s – uruchom test obciążenia na 30 sekund
  • pamiętaj, aby użyć adresu URL usługi jako ostatniego argumentu w tym wierszu poleceń

Wyniki testu powinny wyglądać mniej więcej tak:

 Summary:
 Total:        30.2767 secs
 Slowest:      3.3633 secs
 Fastest:      0.1071 secs
 Average:      0.1828 secs
 Requests/sec: 1087.2387
 Total data:   3028456 bytes
 Size/request: 92 bytes

Response time histogram:
 0.107 [1]     |
 0.433 [31346] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 0.758 [1472]  |■■
 1.084 [82]    |
 1.410 [4]     |
...

Latency distribution:
...
 50% in 0.1528 secs
 75% in 0.1949 secs
 90% in 0.2442 secs
 95% in 0.4052 secs
 99% in 0.7062 secs

Details (average, fastest, slowest):
...
 req write:    0.0000 secs, 0.0000 secs, 0.0232 secs
 resp wait:    0.1824 secs, 0.1070 secs, 3.2953 secs
 resp read:    0.0000 secs, 0.0000 secs, 0.0010 secs
Status code distribution:
 [200] 32918 responses

To podsumowanie zawiera kilka interesujących Cię kwestii:

  • Wysłano 32 918 żądań z szybkością około 1 tys. na sekundę przez 30 sekund.
  • Nie wykryto błędów (tylko 200 odpowiedzi HTTP).
  • Średni czas oczekiwania wyniósł 180 ms.
  • Minimalny czas oczekiwania to 107 ms, a w najgorszym przypadku 3,3 s
  • 90 centyl czasu oczekiwania wynosi 244 ms.

Na karcie METRICS w konsoli Cloud Run znajdziesz historię o wydajności od strony serwera:

e635c6831c468dd3.png

9. Czyszczenie

Cloud Run nie nalicza opłat, gdy usługa nie jest używana, ale może zostać pobrana należność za przechowywanie utworzonego obrazu kontenera.

Możesz usunąć projekt GCP, co spowoduje zaprzestanie naliczania opłat za wszystkie zasoby wykorzystywane w ramach tego projektu, lub po prostu usunąć obraz kontenera za pomocą tego polecenia:

gcloud container images delete $TAG

Aby usunąć usługi Cloud Run, użyj tych poleceń:

gcloud run services delete hello --platform managed --region $REGION --quiet
gcloud run services delete hello-again --platform managed --region $REGION --quiet

10. Udało się!

9a31f4fdbbf1ddcb.png

Gratulujemy – udało Ci się skompilować i wdrożyć produkcyjną aplikację w Cloud Run. Dowiedzieliśmy się też, jak utworzyć własny kontener. Wiesz już również, jak łatwo jest wdrożyć aplikację za pomocą Cloud Run, używając zarówno narzędzia wiersza poleceń gcloud, jak i konsoli Cloud. Teraz już wiesz, jak podzielić się swoim wspaniałym dziełem z całym światem.

Mam dla Ciebie jedno ważne pytanie:

Ile wierszy kodu trzeba było zmodyfikować, aby wdrożyć aplikację w chmurze po wdrożeniu aplikacji w środowisku programistycznym, z uwzględnieniem wszystkich atrybutów klasy produkcyjnej oferowanej przez Cloud Run?

Odpowiedź brzmi oczywiście 0.

Ćwiczenia z programowania do obejrzenia...

Inne ciekawe funkcje...

Dokumentacja...

11. Wezwanie do działania

Logo Google Cloud

Jeśli podoba Ci się to szkolenie z programowania, ale zapewne chcesz poświęcić więcej czasu na praktyczne doświadczenie w Google Cloud, dołącz do Google Cloud Innovators już dziś.

Logo ogólnego członka programu Innovators

Pakiet Google Cloud Innovators jest dostępny bezpłatnie i obejmuje:

  • Sesje dyskusji na żywo, kontrowersje i plany rozwoju na żywo, aby wyciągać wnioski bezpośrednio od pracowników Google
  • najnowsze wiadomości dotyczące Google Cloud bezpośrednio w skrzynce odbiorczej
  • Cyfrowa plakietka i tło rozmowy wideo
  • 500 punktów w modułach i nauce na platformie Skills Boost

Kliknij tutaj, aby się zarejestrować.