Entwicklung zur Produktion mit Cloud Run in drei einfachen Schritten

1. Einführung

Warum ist es so schwierig, Anwendungen zu verwalten?

Ein wichtiger Grund dafür ist, dass Entwickler oft auch als Teilzeit-Systemadministratoren fungieren müssen. Hier ist eine (unvollständige) Liste von Aspekten, die Sie bei der Entwicklung, Bereitstellung und Verwaltung einer modernen Webanwendung in Produktionsqualität berücksichtigen sollten :

4d018476b4a73b47.png

Ich weiß ja nicht, wie es dir geht, aber das sind alles Dinge, um die ich mich nicht kümmern möchte. Ich möchte mich auf die Anwendungslogik konzentrieren:

6dfd143d20e5548b.png

Das ist im Grunde das, worum es bei Cloud Run geht: Sie können sich auf Ihre App konzentrieren und die gesamte Administration und Wartung jemand anderem überlassen, nämlich Google, die Millionen von Stunden in die Verfeinerung und Perfektionierung ihrer Fähigkeiten in diesem Bereich investiert haben.

Neben den oben genannten administrativen Herausforderungen müssen Sie sich auch mit Folgendem auseinandersetzen:

  • Abhängigkeiten: Die Umgebung, in der Ihre App ausgeführt wird, sollte möglichst genau der Umgebung entsprechen, in der sie getestet wurde. Dies kann mehrere Dimensionen umfassen, darunter Betriebssystem, Supportbibliotheken, Sprachinterpreter oder Compiler, Hardwarekonfiguration und viele andere Faktoren.
  • Verteilung: Der Wechsel von einer lokalen Version einer App zu einer Version, die im Internet weit verbreitet ist, erfordert oft eine Änderung der Laufzeitumgebung, einen Quantensprung in der Komplexität und eine steile Lernkurve.

Cloud Run kümmert sich um diese und viele andere Aspekte für Sie. Aber anstatt sich auf meine Worte zu verlassen, erstellen wir gemeinsam eine App und sehen, wie einfach es ist, in nur wenigen Schritten von einer lokalen Entwicklungsumgebung zu einer Cloud-App in Produktionsqualität zu wechseln.

Aufgaben

  • Sie erstellen eine einfache Web-App und prüfen, ob sie in Ihrer Entwicklungsumgebung wie erwartet ausgeführt wird.
  • Anschließend wechseln Sie zu einer containerisierten Version derselben App. Dabei erfahren Sie, was Containerisierung bedeutet und warum sie so nützlich ist.
  • Schließlich stellen Sie Ihre App in der Cloud bereit und sehen, wie einfach es ist, Ihren Cloud Run-Dienst über die Befehlszeile und die Google Cloud Console zu verwalten.

Lerninhalte

  • Einfache Webserver-App in Python erstellen
  • Anwendung in einem Docker-Container verpacken, der überall ausgeführt werden kann
  • So stellen Sie Ihre App in der Cloud bereit, damit jeder Ihre neue Kreation ausprobieren kann
  • So lassen sich die oben genannten Schritte mit Buildpacks noch weiter vereinfachen
  • Google Cloud-Befehlszeilentool und Cloud Console-Web-UI verwenden

Voraussetzungen

  • Webbrowser
  • Ein Google-Konto

Dieses Lab richtet sich an Entwickler aller Erfahrungsstufen, auch an Anfänger. Sie verwenden zwar Python, müssen aber nicht mit der Python-Programmierung vertraut sein, um zu verstehen, was passiert, da wir den gesamten verwendeten Code erläutern.

2. Einrichten

5110b5081a1e1c49.png

In diesem Abschnitt erfahren Sie alles, was Sie für den Einstieg in dieses Lab benötigen.

Umgebung zum selbstbestimmten Lernen einrichten

  1. Melden Sie sich in der Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes Projekt. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Notieren Sie sich die Projekt-ID, also den projektübergreifend nur einmal vorkommenden Namen eines Google Cloud-Projekts. Der oben angegebene Name ist bereits vergeben und kann leider nicht mehr verwendet werden. Sie wird später in diesem Codelab als PROJECT_ID bezeichnet.

  1. Als Nächstes müssen Sie die Abrechnung in der Cloud Console aktivieren, um Google Cloud-Ressourcen verwenden zu können.

Die Durchführung dieses Codelabs sollte keine oder nur geringe Kosten verursachen. Folgen Sie bitte der Anleitung im Abschnitt „Bereinigen“, in der Sie erfahren, wie Sie Ressourcen herunterfahren können, damit nach Abschluss dieser Anleitung keine Gebühren anfallen. Neue Nutzer von Google Cloud kommen für das Programm für kostenlose Testversionen mit einem Guthaben von 300$ infrage.

Cloud Shell starten

In diesem Lab arbeiten Sie in einer Cloud Shell-Sitzung. Das ist ein Befehlsinterpreter, der auf einer virtuellen Maschine in der Google-Cloud gehostet wird. Sie könnten diesen Abschnitt genauso gut lokal auf Ihrem eigenen Computer ausführen, aber mit Cloud Shell hat jeder Zugriff auf eine reproduzierbare Umgebung. Nach dem Lab können Sie diesen Abschnitt gern auf Ihrem eigenen Computer wiederholen.

704a7b7491bd157.png

Cloud Shell aktivieren

  1. Klicken Sie in der Cloud Console auf Cloud Shell aktivieren 4292cbf4971c9786.png.

bce75f34b2c53987.png

Wenn Sie die Cloud Shell zuvor noch nicht gestartet haben, wird ein Fenster mit einer Beschreibung eingeblendet. Klicken Sie in diesem Fall einfach auf Weiter. So sieht dieses Fenster aus:

70f315d7b402b476.png

Das Herstellen der Verbindung mit der Cloud Shell sollte nur wenige Augenblicke dauern.

fbe3a0674c982259.png

Auf dieser virtuellen Maschine sind alle Entwicklungstools installiert, die Sie benötigen. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft in Google Cloud, was die Netzwerkleistung und Authentifizierung erheblich verbessert. Die meisten, wenn nicht sogar alle Aufgaben in diesem Codelab können mit einem Browser oder Ihrem Chromebook erledigt werden.

Sobald die Verbindung mit der Cloud Shell hergestellt ist, sehen Sie, dass Sie bereits authentifiziert sind und für das Projekt schon Ihre Projekt-ID eingestellt ist.

  1. Führen Sie in der Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list

Befehlsausgabe

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Führen Sie den folgenden Befehl in Cloud Shell aus, um zu bestätigen, dass der gcloud-Befehl Ihr Projekt kennt:
gcloud config list project

Befehlsausgabe

[core]
project = <PROJECT_ID>

Ist dies nicht der Fall, können Sie die Einstellung mit diesem Befehl vornehmen:

gcloud config set project <PROJECT_ID>

Befehlsausgabe

Updated property [core/project].

Legen Sie in Ihrem Terminal einige Umgebungsvariablen fest, die die nachfolgenden Schritte erleichtern:

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

APIs aktivieren

In späteren Schritten erfahren Sie, wo diese Dienste benötigt werden und warum. Führen Sie jetzt diesen Befehl aus, um Ihrem Projekt Zugriff auf die Dienste Cloud Build, Container Registry und Cloud Run zu gewähren:

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

Wenn die Aktivierung erfolgreich war, erhalten Sie eine Meldung, die ungefähr so aussieht:

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

3. Einfache Webanwendung erstellen

eef530b56b8e93a3.png

Klicken Sie zuerst oben im Cloud Shell-Bereich auf die Schaltfläche Open Editor. Sie sieht so aus:

9b81c8a37a6bcdd8.png

Sie befinden sich dann in einer IDE-Umgebung, die Visual Studio Code ähnelt. Dort können Sie Projekte erstellen, Quellcode bearbeiten und Programme ausführen. Wenn Ihr Bildschirm zu klein ist, können Sie die Trennlinie zwischen der Konsole und dem Bearbeitungs-/Terminalfenster vergrößern oder verkleinern, indem Sie die horizontale Leiste zwischen diesen beiden Bereichen ziehen (siehe Abbildung):

8dea35450851af53.png

Sie können zwischen dem Editor und dem Terminal wechseln, indem Sie auf die Schaltflächen Open Editor bzw. Open Terminal klicken. Wechseln Sie jetzt zwischen diesen beiden Umgebungen hin und her.

Erstellen Sie als Nächstes einen Ordner, in dem Sie Ihre Arbeit für dieses Lab speichern. Wählen Sie dazu „Datei“ –> „Neuer Ordner“ aus, geben Sie hello ein und klicken Sie auf OK. Alle Dateien, die Sie in diesem Lab erstellen, und alle Aufgaben, die Sie in Cloud Shell ausführen, werden in diesem Ordner gespeichert.

Erstellen Sie nun eine requirements.txt-Datei. Dadurch wird Python mitgeteilt, von welchen Bibliotheken Ihre App abhängig ist. Für diese einfache Web-App verwenden Sie ein beliebtes Python-Modul zum Erstellen von Webservern namens Flask und ein Webserver-Framework namens gunicorn. Klicken Sie im Cloud Editor-Fenster auf das Menü „Datei“ > „Neue Datei“, um eine neue Datei zu erstellen. Wenn Sie nach dem Namen der neuen Datei gefragt werden, geben Sie requirements.txt ein und drücken Sie die OK-Taste. Achten Sie darauf, dass die neue Datei im Projektordner hello landet.

Geben Sie die folgenden Zeilen in die neue Datei ein, um anzugeben, dass Ihre App vom Python-Paket Flask und vom Webserver gunicorn abhängt.

Flask
gunicorn

Sie müssen diese Datei nicht explizit speichern, da Änderungen im Cloud Editor automatisch gespeichert werden.

Version 1: Hello world!

Erstellen Sie auf dieselbe Weise eine weitere neue Datei mit dem Namen main.py. Dies ist die Haupt- (und einzige) Python-Quelldatei Ihrer App. Achten Sie noch einmal darauf, dass die neue Datei im Projektordner hello landet.

Fügen Sie den folgenden Code in diese Datei ein:

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)

Wechseln Sie zurück zum Terminal und mit diesem Befehl in den Projektordner:

cd hello

Führen Sie den folgenden Befehl aus, um die Projektabhängigkeiten zu installieren:

pip3 install -r requirements.txt

Starten Sie die App nun mit dem folgenden Befehl im Terminal:

python3 main.py

Ihre Anwendung wird jetzt auf der VM ausgeführt, die Ihrer Cloud Shell-Sitzung zugewiesen ist. Cloud Shell enthält einen Proxymechanismus, mit dem Sie von überall im Internet auf Webserver (wie den, den Sie gerade gestartet haben) zugreifen können, die auf Ihrer VM ausgeführt werden.

Klicken Sie auf die Schaltfläche web preview und dann auf den Menüpunkt Preview on Port 8080:

fe45e0192080efd6.png

Dadurch wird ein Webbrowser-Tab für Ihre laufende App geöffnet, der in etwa so aussehen sollte:

b1f06501509aefb9.png

Version 2: URL-Pfad ausgeben

Kehren Sie zum Cloud Editor zurück (über die Schaltfläche Open Editor) und fügen Sie Unterstützung für das Ausgeben eines optionalen URL-Suffixes hinzu, indem Sie die Datei main.py so aktualisieren:

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)

Wechseln Sie zurück zum Terminal (über die Schaltfläche Open Terminal) und geben Sie control-C ein (halten Sie die Strg-Taste gedrückt, während Sie „C“ drücken), um die laufende App zu beenden. Starten Sie sie dann neu, indem Sie Folgendes eingeben:

python3 main.py

Klicken Sie noch einmal auf die Schaltfläche web preview und dann auf das Menüelement Preview on Port 8080, um einen Webbrowser-Tab für Ihre laufende App zu öffnen. Sie sollten wieder die Meldung „Hello world!“ sehen. Ersetzen Sie nun den URL-Text nach dem Schrägstrich durch einen beliebigen String (z. B. /your-name) und prüfen Sie, ob etwas Ähnliches wie das Folgende angezeigt wird:

93b87996f88fa370.png

Version 3: Zufällige Farben

Fügen Sie nun Unterstützung für zufällige Hintergrundfarben hinzu, indem Sie zum Cloud Editor zurückkehren (über die Schaltfläche Open Editor) und Ihre Datei main.py so aktualisieren:

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)

Wechseln Sie zurück zum Terminal (über die Schaltfläche Open Terminal) und geben Sie control-C ein (halten Sie die Strg-Taste gedrückt, während Sie „C“ drücken), um die laufende App zu beenden. Starten Sie sie dann neu, indem Sie Folgendes eingeben:

python3 main.py

Klicken Sie noch einmal auf die Schaltfläche web preview und dann auf den Menüpunkt Preview on Port 8080, um einen Webbrowser-Tab für Ihre laufende App zu öffnen. Der generierte Text sollte vor einem zufällig farbigen Hintergrund angezeigt werden, z. B. so:

baf8d028f15ea7f4.png

Laden Sie die Seite mehrmals neu, um zu sehen, dass sich die zufällige Hintergrundfarbe bei jedem Besuch der App ändert.

Damit ist Ihre App fertig – herzlichen Glückwunsch! Im nächsten Schritt erfahren Sie, wie Sie Ihre App in einem Container verpacken und warum das sinnvoll ist.

4. Anwendung containerisieren

17cc234ec3325a8a.png

Was ist ein Container?

Container im Allgemeinen und Docker im Besonderen ermöglichen es uns, eine modulare Box zu erstellen, in der eine Anwendung mit allen ihren Abhängigkeiten gebündelt ausgeführt werden kann. Das Ergebnis nennen wir Container-Image. In diesem Abschnitt erstellen Sie ein Container-Image, mit dem Sie Ihre Anwendung und alle zugehörigen Abhängigkeiten kapseln.

Apropos Abhängigkeiten: In einem vorherigen Schritt mussten Sie beim Ausführen Ihrer App in einer Entwicklungsumgebung pip3 install -r requirements.txt ausführen und darauf achten, dass die Datei „requirements.txt“ alle abhängigen Bibliotheken und entsprechenden Versionen enthält. Bei Containern installieren Sie diese Anforderungen, wenn Sie das Container-Image generieren. Der Nutzer des Containers muss sich also nicht um die Installation kümmern.

Dieses Container-Image bildet den grundlegenden Baustein für die Bereitstellung Ihrer Anwendung in Cloud Run. Da Container auf nahezu jedem virtuellen oder physischen Server verwendet werden können, können wir Ihre Anwendung überall bereitstellen und von einem Dienstanbieter zu einem anderen oder von lokal in die Cloud verschieben.

Container helfen Ihnen, Ihre Anwendungen

  • reproduzierbar – Container sind in sich geschlossen und vollständig
  • Portierbar: Container sind branchenübergreifende Bausteine, die die Portierbarkeit von Anwendungen über Cloud-Anbieter und Umgebungen hinweg ermöglichen.

Kurz gesagt: Container bieten endlich die Möglichkeit, Anwendungen „einmal zu schreiben und überall auszuführen“. Eine Ausnahme von dieser Regel besteht darin, dass der generierte Container auf den Prozessortyp beschränkt ist, auf dem Sie ihn erstellt haben. Es gibt jedoch Möglichkeiten, Containerversionen auch für andere Hardwarekonfigurationen zu generieren.

Genug geredet – erstellen wir einen Container! Sie verwenden eine bestimmte Technologie zum Erstellen eines Containers namens Docker.

Erstellen Sie im Cloud Editor eine neue Datei mit dem Namen Dockerfile. Diese Datei ist ein Bauplan für die Erstellung Ihres Bildes. Sie enthält Informationen zu Ihrer Betriebsumgebung und Ihrem Quellcode, zur Installation Ihrer Abhängigkeiten, zum Erstellen Ihrer App und zum Ausführen Ihres Codes.

# 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

Erstellen Sie das Container-Image mit Cloud Build. Führen Sie dazu folgenden Befehl im Cloud-Terminal aus:

gcloud builds submit --tag $TAG

Bei erfolgreicher Übertragung in die Registry wird eine SUCCESS-Meldung mit dem Image-Namen ausgegeben, die in etwa so aussehen sollte: gcr.io/<project-id>/hello. Das Image wird jetzt in Google Container Registry gespeichert und kann jederzeit und überall wiederverwendet werden.

Lassen Sie sich mit folgendem Befehl alle Container-Images Ihres aktuellen Projekts anzeigen:

gcloud container images list

Führen Sie die Anwendung jetzt lokal in Cloud Shell aus und testen Sie sie mit den folgenden docker-Befehlen:

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

Mit der Option -p $PORT:$PORT wird Docker angewiesen, den externen Port $PORT (oben auf 8080 festgelegt) in der Hostumgebung dem Port mit derselben Nummer im laufenden Container zuzuordnen. Das macht die Entwicklung einfacher, da der von Ihnen geschriebene Servercode und die externe Portnummer, mit der Sie beim Testen Ihrer App eine Verbindung herstellen, identisch sind (8080). Sie können aber auch die Option „-p“ verwenden, um einen beliebigen externen Port auf dem Host einem beliebigen internen Port im Container zuzuordnen.

Mit der Option -e PORT=$PORT wird Docker angewiesen, die Umgebungsvariable $PORT (oben auf 8080 festgelegt) für Ihre Anwendung verfügbar zu machen, die im Container ausgeführt wird.

Sie können Ihre App jetzt testen, indem Sie einen Webbrowser auf den Python-Code verweisen, der im Container ausgeführt wird. Klicken Sie im Cloud Shell-Fenster auf das Symbol „Webvorschau“ und wählen Sie „Vorschau auf Port 8080“ aus, wie Sie es im vorherigen Schritt getan haben.

Das Ergebnis sollte Ihnen bekannt vorkommen: Sie sehen den generierten Text vor einem zufällig farbigen Hintergrund, genau wie beim direkten Ausführen der App in Ihrem Cloud Shell-Terminal. Laden Sie die Seite mehrmals neu, um zu sehen, dass sich die zufällige Hintergrundfarbe bei jedem Besuch der App ändert.

Glückwunsch! Sie haben jetzt eine containerisierte Version Ihrer App ausgeführt. Im nächsten Abschnitt wandeln Sie Ihr Container-Image in eine Web-App in Produktionsqualität um, ohne eine einzige Zeile Code zu ändern.

5. In die Cloud…

1b0665d94750ded6.gif

Nachdem Sie Ihre App containerisiert haben, möchten Sie sie sicher mit dem Rest der Welt teilen. Es ist also an der Zeit, sie in der Cloud bereitzustellen. Aber du möchtest mehr tun, als es nur zu teilen. Sie möchten sichergehen, dass:

  • zuverlässig ausgeführt wird – Sie erhalten automatische Fehlertoleranz, falls ein Computer, auf dem Ihre App ausgeführt wird, abstürzt
  • Automatische Skalierung: Ihre App kann auch bei sehr hohem Traffic mithalten und reduziert automatisch ihren Ressourcenverbrauch, wenn sie nicht verwendet wird.
  • Sie zahlen nur für Ressourcen, die während der Reaktion auf Traffic verbraucht werden.
  • ist über einen benutzerdefinierten Domainnamen zugänglich – Sie haben Zugriff auf eine Ein-Klick-Lösung, um Ihrem Dienst einen benutzerdefinierten Domainnamen zuzuweisen.
  • bietet eine hervorragende Reaktionszeit. Kaltstarts sind relativ reaktionsschnell, aber Sie können das durch Angabe einer Mindestanzahl von Instanzen optimieren.
  • Unterstützt End-to-End-Verschlüsselung mit standardmäßiger SSL/TLS-Websicherheit: Wenn Sie einen Dienst bereitstellen, erhalten Sie kostenlos und automatisch eine standardmäßige Webverschlüsselung und die entsprechenden erforderlichen Zertifikate.

Wenn Sie Ihre App in Google Cloud Run bereitstellen, erhalten Sie all das und noch mehr.

Anwendung in Cloud Run bereitstellen

Ändern wir zuerst Ihre App, damit Sie die neue Version von der alten unterscheiden können. Ändern Sie dazu die Datei main.py so, dass die Standardnachricht von „Hello world!“ in „Hello from Cloud Run!“ geändert wird. Ändern Sie diese Zeile in main.py also von:

def say_hello(name="world"):

zu

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

Cloud Run ist regional. Die Infrastruktur, in der die Cloud Run-Dienste ausgeführt werden, befindet sich demnach in einer bestimmten Region. Aufgrund der Verwaltung durch Google sind die Anwendungen in allen Zonen innerhalb dieser Region redundant verfügbar. Im Abschnitt „Einrichtung“ oben haben Sie eine Standardregion über die Umgebungsvariable REGION definiert.

Erstellen Sie das Container-Image neu und stellen Sie die containerisierte Anwendung mit dem folgenden Befehl in Cloud Run bereit:

gcloud builds submit --tag $TAG
gcloud run deploy "$APP"   \
  --image "$TAG"           \
  --platform "managed"     \
  --region "$REGION"       \
  --allow-unauthenticated
  • Sie können auch eine Standardregion mit gcloud config set run/region $REGION definieren.
  • Mit der Option --allow-unauthenticated wird der Dienst öffentlich verfügbar. Verwenden Sie stattdessen --no-allow-unauthenticated, um nicht authentifizierte Anfragen zu vermeiden.

Das hier angegebene Image ist das Docker-Image, das Sie im letzten Schritt erstellt haben. Dank des Cloud Build-Dienstes, der das resultierende Image in der Google Container Registry gespeichert hat, kann der Cloud Run-Dienst es finden und für Sie bereitstellen.

Warten Sie dann einige Sekunden, bis die Bereitstellung abgeschlossen ist. Wenn die Bereitstellung erfolgreich war, wird in der Befehlszeile die Dienst-URL angezeigt:

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

Sie können die Dienst-URL auch mit diesem Befehl abrufen:

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

Es sollte etwa Folgendes angezeigt werden:

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

Dieser Link ist eine dedizierte URL mit TLS-Sicherheit für Ihren Cloud Run-Dienst. Dieser Link ist dauerhaft (solange Sie Ihren Dienst nicht deaktivieren) und überall im Internet nutzbar. Dabei wird nicht der zuvor erwähnte Cloud Shell-Proxymechanismus verwendet, der von einer temporären virtuellen Maschine abhängig war.

Klicken Sie auf das hervorgehobene Service URL, um einen Webbrowser-Tab mit Ihrer ausgeführten App zu öffnen. Das Ergebnis sollte die Meldung „Hello from Cloud Run!“ vor einem zufällig farbigen Hintergrund anzeigen.

Glückwunsch! Ihre App wird jetzt in der Google Cloud ausgeführt. Ihre App ist öffentlich verfügbar, mit TLS-Verschlüsselung (HTTPS) und automatischer Skalierung für unglaubliche Traffic-Mengen.

Aber ich denke, dieser Prozess könnte noch einfacher sein…

6. Container automatisch erstellen

Das ist alles ziemlich cool, aber was ist, wenn ich mich nicht mit Dockerfiles und Containern beschäftigen möchte? Was ist, wenn ich mich wie die meisten Entwickler nur auf das Schreiben meines Anwendungscodes konzentrieren und jemand anderes sich um die Containerisierung kümmern soll? Glücklicherweise unterstützt Cloud Run einen Open-Source-Standard namens Buildpacks, der genau aus diesem Grund existiert: um den Prozess der Erstellung eines Containers aus einer Sammlung von Quelldateien zu automatisieren.

Es gibt jedoch einige Fälle, in denen ein Entwickler möglicherweise lieber ein explizites Dockerfile verwendet, z. B. wenn er den Build-Prozess des Containers stark anpassen möchte. Für gängige Fälle wie diese Übung funktionieren Buildpacks jedoch gut und es ist nicht erforderlich, eine Dockerfile manuell zu erstellen. Wir ändern Ihren Code, damit Buildpacks verwendet werden.

Ändern wir zuerst Ihre App, damit Sie die neue Version von der alten unterscheiden können. Ändern Sie dazu die Datei main.py so, dass die Standardnachricht von „Hello from Cloud Run!“ in „Hello from Cloud Run with Buildpacks!“ geändert wird. Ändern Sie diese Zeile in main.py also von:

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

zu

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

Jetzt nutzen wir Buildpacks, indem wir eine neue Datei mit dem Namen Procfile erstellen. Erstellen Sie diese Datei in Cloud Editor und fügen Sie diese eine Textzeile ein:

web: python3 main.py

Dadurch wird dem Buildpack-System mitgeteilt, wie Ihre App im automatisch generierten Container ausgeführt werden soll. Mit dieser Anweisung benötigen Sie nicht einmal mehr eine Dockerfile. Löschen Sie dazu Ihr Dockerfile und führen Sie den folgenden Befehl im Cloud Shell-Terminal aus:

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

Dieser Befehl ähnelt dem Befehl, den Sie im letzten Schritt zum Bereitstellen Ihrer App ausgeführt haben. Diesmal haben Sie jedoch die Option --image durch die Option --source . ersetzt. Damit wird dem Befehl gcloud mitgeteilt, dass Sie Buildpacks verwenden möchten, um Ihr Container-Image auf Grundlage der Quelldateien im aktuellen Verzeichnis zu erstellen. Das dot in --source . ist eine Kurzform für das aktuelle Verzeichnis. Da der Dienst sich implizit um das Container-Image kümmert, müssen Sie in diesem gcloud-Befehl kein Image angeben.

Prüfen Sie noch einmal, ob die Bereitstellung funktioniert hat. Klicken Sie dazu auf das markierte Service URL, um einen Browsertab mit Ihrer ausgeführten App zu öffnen. Ihr Dienst sollte „Hello from Cloud Run with Buildpacks!“ vor einem zufällig farbigen Hintergrund anzeigen.

Wenn Sie Buildpacks zum Erstellen Ihrer Dockerfile verwenden, reduzieren Sie die drei einfachen Schritte auf zwei:

  1. Erstellen Sie eine App in Ihrer Entwicklungsumgebung.
  2. Stellen Sie genau denselben Code mit einem einzigen Befehl in der Cloud bereit.

7. Muss ich die Befehlszeile verwenden?

Nein! Wie bei fast jedem Google Cloud-Dienst gibt es drei Möglichkeiten, mit Cloud Run zu interagieren:

  • Das gcloud-Befehlszeilentool, das Sie gerade gesehen haben.
  • Eine umfangreiche Web-Benutzeroberfläche über die Cloud Console, die eine intuitive Point-and-Click-Interaktion unterstützt.
  • Programmgesteuert mit Google-Clientbibliotheken, die für viele gängige Sprachen wie Java, C#, Python, Go, Javascript, Ruby und C/C++ verfügbar sind.

Wir stellen eine zusätzliche Instanz Ihrer Cloud Run-App über die Console-Benutzeroberfläche bereit. Rufen Sie die Cloud Run-Dienst-Landingpage über das Menü oben links auf:

e2b4983b38c81796.png

Sie sollten dann eine Zusammenfassung Ihrer Cloud Run-Dienste sehen, etwa so:

b335e7bf0a3af845.png

Klicken Sie auf den Link „Dienst erstellen“, um den Bereitstellungsprozess zu starten:

51f61a8ddc7a4c0b.png

Geben Sie „hello-again“ als Dienstnamen ein, übernehmen Sie die Standardbereitstellungsplattform und ‑region und klicken Sie auf „Weiter“.

8a17baa45336c4c9.png

Geben Sie diese URL für das Container-Image ein: gcr.io/cloudrun/hello. Das ist ein von Google erstellter Container für Testzwecke. Klicken Sie auf das Drop-down-Menü „Erweiterte Einstellungen“, um einige der vielen Konfigurationseinstellungen zu sehen, die Ihnen zur Verfügung stehen. Hier nur einige Beispiele:

  • Portnummer und Containereinstiegspunkt (der den beim Erstellen des Containers angegebenen Einstiegspunkt überschreibt)
  • Hardware: Arbeitsspeicher und Anzahl der CPUs
  • Skalierung: Mindest- und Höchstzahl von Instanzen
  • Umgebungsvariablen
  • Andere: Einstellung für das Zeitlimit für Anfragen, maximale Anzahl von Anfragen pro Container, HTTP/2

Klicken Sie auf die Schaltfläche „Weiter“, um das Dialogfeld zu öffnen. Im nächsten Dialogfeld können Sie angeben, wie Ihr Dienst ausgelöst wird. Wählen Sie für „Eingehender Traffic“ die Option „Gesamten Traffic zulassen“ und für „Authentifizierung“ die Option „Nicht authentifizierten Traffic zulassen“ aus.

e78281d1cff3418.png

Dies sind die liberalsten Einstellungen, da sie jedem den Zugriff auf Ihre Cloud Run-App von überall im öffentlichen Internet ermöglichen, ohne dass Authentifizierungsanmeldedaten angegeben werden müssen. Möglicherweise möchten Sie restriktivere Einstellungen für Ihre App festlegen, aber für diese Übung halten wir es einfach.

Klicken Sie nun auf die Schaltfläche Create, um den Cloud Run-Dienst zu erstellen. Nach einigen Sekunden sollte Ihr neuer Dienst in der Zusammenfassungsliste der Cloud Run-Dienste angezeigt werden. In der Zusammenfassungszeile finden Sie die letzte Bereitstellung (Datum/Uhrzeit und von wem) sowie einige wichtige Konfigurationseinstellungen. Klicken Sie auf den Link zum Dienstnamen, um Details zu Ihrem neuen Dienst aufzurufen.

Klicken Sie zum Bestätigen Ihres Dienstes auf die URL, die oben auf der Übersichtsseite angezeigt wird, wie im folgenden Beispiel hervorgehoben:

6c35cf0636dddc51.png

Auf dem Bildschirm sollte Folgendes zu sehen sein:

3ba6ab4fe0da1f84.png

Nachdem Sie einen neuen Cloud Run-Dienst bereitgestellt haben, können Sie auf dem Tab REVISIONS sehen, wie Sie mehrere Bereitstellungen verwalten können.

2351ee7ec4a356f0.png

Wenn Sie neue Überarbeitungen direkt über die Konsole bereitstellen möchten, können Sie auf die Schaltfläche EDIT & DEPLOY NEW REVISION klicken, wie im Beispiel-Screenshot unten dargestellt:

a599fa88d00d6776.png

Klicken Sie jetzt auf diese Schaltfläche, um eine neue Überarbeitung zu erstellen. Klicken Sie neben der Container-URL auf die Schaltfläche SELECT (siehe unten):

5fd1b1f8e1f11d40.png

Suchen Sie im eingeblendeten Dialogfeld nach der einfachen Webanwendung, die Sie zuvor mit Buildpacks über Cloud Build bereitgestellt haben, und klicken Sie auf „Auswählen“. Achten Sie darauf, dass Sie das Container-Image unter

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

Ordner , wie hier:

8a756c6157face3a.png

Scrollen Sie nach der Auswahl nach unten und klicken Sie auf die Schaltfläche DEPLOY. Sie haben jetzt eine neue Überarbeitung Ihrer App bereitgestellt. Rufen Sie zur Bestätigung noch einmal die Dienst-URL auf und prüfen Sie, ob Sie jetzt Ihre farbenfrohe Web-App „Hello from Cloud Run with Buildpacks!“ sehen.

Wie Sie sehen, bietet der Tab „Überarbeitungen“ eine Zusammenfassung aller bereitgestellten Überarbeitungen. Für diesen Dienst sollten jetzt zwei Überarbeitungen angezeigt werden. Sie können eine bestimmte Überarbeitung auswählen, indem Sie auf das Optionsfeld links neben dem Namen der Überarbeitung klicken. Rechts auf dem Bildschirm wird dann eine Zusammenfassung der Überarbeitungsdetails angezeigt. Wenn Sie diese Schaltflächen auswählen, sehen Sie, dass Ihre beiden Überarbeitungen aus zwei verschiedenen Container-Images abgeleitet wurden.

Mit der Schaltfläche MANAGE TRAFFIC können Sie die Verteilung eingehender Anfragen ändern, die an eine bestimmte Überarbeitung gesendet werden. Die Möglichkeit, die Menge des Traffics, der an eine bestimmte Revision gesendet wird, genau zu steuern, ermöglicht mehrere wertvolle Anwendungsfälle:

  • Canary-Tests einer neuen Version Ihrer App mit einem kleinen Teil des eingehenden Traffics
  • Traffic von einem problematischen Release zu einer vorherigen Überarbeitung zurücksetzen
  • A/B-Test

So finden Sie die Schaltfläche MANAGE TRAFFIC:

519d3c22ae028287.png

Konfigurieren Sie eine 50/50-Trafficaufteilung zwischen den beiden Überarbeitungen, indem Sie eine 50/50-Trafficaufteilung so angeben:

8c37d4f115d9ded4.png

Klicken Sie jetzt auf die Schaltfläche „SAVE“ (SPEICHERN) und prüfen Sie die 50/50-Aufteilung, indem Sie die URL Ihres Dienstes wiederholt aufrufen. Prüfen Sie, ob im Durchschnitt die Hälfte Ihrer Anfragen von der aktuellen Revision („Hello from Cloud Run with Buildpacks!“) und die Hälfte von der vorherigen Revision („It's running!“) verarbeitet werden.

Auf anderen Tabs auf der Seite „Dienstdetails“ können Sie Leistung, Traffic und Logs überwachen. So erhalten Sie wertvolle Informationen dazu, wie stark und wie gut Ihr Dienst genutzt wird. Über den Tab „Berechtigungen“ können Sie den Zugriff auf Ihren Dienst auch genauer anpassen. Nehmen Sie sich einen Moment Zeit, um sich die Tabs auf dieser Seite anzusehen und sich einen Überblick über die verfügbaren Funktionen zu verschaffen.

Programmatische Schnittstelle

Wie bereits erwähnt, haben Sie auch die Möglichkeit, Ihre Cloud Run-Dienste programmatisch zu erstellen, bereitzustellen und zu verwalten. Für manuelle Aufgaben ist diese Option komplexer als die Befehlszeile oder Webkonsole, aber für die Automatisierung von Cloud Run-Diensten ist sie die beste Wahl. Sie haben die Möglichkeit, Google-Clientbibliotheken in verschiedenen gängigen Programmiersprachen zu verwenden.

8. App testen

198ada162d1f0bf1.png

In diesem letzten Schritt führen Sie einen künstlichen Lasttest durch, um Ihre App zu belasten und zu sehen, wie sie mit der eingehenden Nachfrage skaliert. Sie verwenden das Tool hey, das in Cloud Shell vorinstalliert ist und mit dem wir Lasttests ausführen und die Ergebnisse präsentieren können.

Testen

Führen Sie im Cloud Shell-Terminal diesen Befehl aus, um einen Lasttest auszuführen:

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

Die Befehlsargumente werden so interpretiert:

  • -q 1000: Versuchen Sie,die Last auf etwa 1.000 Anfragen pro Sekunde zu erhöhen.
  • -c 200 – 200 parallele Worker zuweisen
  • -z 30s – Führen Sie den Lasttest 30 Sekunden lang aus.
  • Verwenden Sie die Dienst-URL als letztes Argument in dieser Befehlszeile.

Die Ergebnisse Ihres Tests sollten in etwa so aussehen:

 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

Diese Zusammenfassung enthält mehrere interessante Informationen:

  • 32.918 Anfragen wurden über 30 Sekunden hinweg mit etwa 1.000 Anfragen pro Sekunde gesendet.
  • Es sind keine Fehler aufgetreten (nur 200 HTTP-Antworten).
  • Die durchschnittliche Latenz betrug 180 ms.
  • Die minimale Latenz betrug 107 ms, der Worst Case 3,3 s.
  • Die Latenz beim 90. Perzentil betrug 244 ms.

Wenn Sie in der Cloud Run Console den Tab METRICS aufrufen, sehen Sie die Serverseite der Leistungsgeschichte:

e635c6831c468dd3.png

9. Bereinigen

Während für Cloud Run keine Kosten anfallen, wenn der Dienst nicht verwendet wird, wird Ihnen dennoch das Speichern des erstellten Container-Images möglicherweise in Rechnung gestellt.

Um Gebühren zu vermeiden, können Sie entweder Ihr GCP-Projekt löschen und so die Abrechnung für alle in diesem Projekt verwendeten Ressourcen beenden oder einfach mit dem folgenden Befehl Ihr Container-Image löschen:

gcloud container images delete $TAG

Verwenden Sie die folgenden Befehle, um Ihre Cloud Run-Dienste zu löschen:

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

10. Du hast es geschafft!

9a31f4fdbbf1ddcb.png

Herzlichen Glückwunsch! Sie haben erfolgreich eine Cloud Run-Produktions-App erstellt und bereitgestellt. Dabei haben Sie etwas über Container und das Erstellen eigener Container gelernt. Sie haben gesehen, wie einfach es ist, Ihre App mit Cloud Run bereitzustellen, sowohl mit dem gcloud-Befehlszeilentool als auch mit der Cloud Console. Jetzt wissen Sie, wie Sie Ihre brillanten Kreationen mit der ganzen Welt teilen können.

Zum Schluss möchte ich Ihnen noch eine wichtige Frage stellen:

Nachdem Ihre App in Ihrer Entwicklungsumgebung funktioniert hat, wie viele Codezeilen mussten Sie ändern, um sie in der Cloud bereitzustellen, mit allen Produktionsattributen, die von Cloud Run angeboten werden?

Die Antwort lautet natürlich null. :)

Codelabs, die Sie sich ansehen können…

Weitere interessante Funktionen

Referenzdokumente

11. Call-to-Action

Logo: Google Cloud

Wenn Ihnen dieses Codelab gefallen hat und Sie wahrscheinlich mehr Zeit mit Google Cloud verbringen werden, sollten Sie noch heute Google Cloud Innovators beitreten.

Logo: Allgemeines Mitgliederabzeichen für Innovatoren

Google Cloud Innovators ist kostenlos und umfasst:

  • Live-Diskussionen, Fragerunden und Roadmap-Sessions mit den neuesten Informationen von Google-Mitarbeitern
  • die neuesten Google Cloud-Nachrichten direkt in Ihrem Posteingang
  • Digitales Kennzeichen und Videokonferenzhintergrund
  • 500 Guthabenpunkte für Labs und Skills Boost

Hier registrieren