In dieser Anleitung erfahren Sie, wie Sie Nachrichten von mobilen oder clientseitigen Anwendungen in Pub/Sub veröffentlichen, indem Sie anstelle von clientseitigen Anmeldedaten einen Proxy für die Authentifizierungs- und Autorisierungslogik verwenden.
Mit der Identitäts- und Zugriffsverwaltung (Identity and Access Management, IAM) können Sie zwar Nachrichten vom Client zu Pub/Sub authentifizieren, solche langlebigen Anmeldedaten laufen aber nicht ab. In clientseitigen Anwendungen können diese Anmeldedaten durch Techniken wie App-Dekompilierung und Reverse Engineering ermittelt werden.
Stattdessen können Sie die Authentifizierungs- und Autorisierungslogik auf einen Proxy übertragen, der die folgenden Aufgaben ausführt:
- Eingehende Anfragen authentifizieren, um Nutzer zu validieren
- Anfragen zusammen mit den entsprechenden IAM-Berechtigungen an Pub/Sub weiterleiten
In dieser Anleitung erfahren Sie, wie Sie einen Pub/Sub-Proxy in Google Kubernetes Engine (GKE) implementieren. Diese Anleitung richtet sich an Anwendungsentwickler und Systemarchitekten, die das Design für mobile oder clientseitige Anwendungen definieren und implementieren. Dabei wird davon ausgegangen, dass Sie mit den grundlegenden Kubernetes-Konzepten und mit Cloud Endpoints vertraut sind.
Anfragefluss für diese Anleitung
Um zu verstehen, wie Pub/Sub in eine Streamingpipeline passt, sollten Sie eine Clickstream-Analyse in Betracht ziehen. In diesem Anwendungsfall möchten Sie möglicherweise wissen, wie Nutzer mit Ihrer App interagieren. Dazu erfassen Sie die Nutzeraktivität in Echtzeit. Das folgende Diagramm zeigt den Datenfluss.
Die von der Anwendung erfassten Daten werden über einen Proxy an Pub/Sub übertragen. Pub/Sub kann nachgeschaltete Abonnenten wie Dataflow oder Dataproc haben, die die Daten für eine aussagekräftige Analyse zusammenfassen.
Das folgende Diagramm zeigt eine detaillierte Ansicht des Anfrageflusses, dem diese Anleitung folgt.
In den nächsten Abschnitten wird erläutert, wie die verschiedenen Komponenten in diesem Diagramm zusammenarbeiten.
Nutzerauthentifizierung
Apps können verschiedene Methoden zur Authentifizierung von Nutzern verwenden. Der Authentifizierungsablauf hängt jeweils von Ihrer Anwendung ab. In dieser Anleitung wird nur eine mögliche Lösung zur Authentifizierung von Nutzern gezeigt. Als Begleitmaterial zu dieser Anleitung gibt es eine Implementierung dieser Lösung.
Anfragen von der Client-App an den Pub/Sub-Proxy
Das App-Backend generiert ein kurzlebiges Authentifizierungstoken, das der Client lokal speichert (z. B. mithilfe des Android-Schlüsselspeichersystems oder der iOS-Schlüsselbunddienste). In dieser Anleitung werden zur Authentifizierung der Client-App OpenID Connect-ID-Tokens (OIDC-ID-Tokens) verwendet. Google gibt die OIDC-ID-Tokens aus und signiert es.
Die clientseitige Anwendung sendet eine Anfrage mit diesem OIDC-ID-Token an den Pub/Sub-Proxy. Der Pub/Sub-Proxy validiert das Token und leitet die Anfrage mit den entsprechenden IAM-Anmeldedaten an Pub/Sub weiter.
Nachrichten veröffentlichen
Nachdem die Client-App erfolgreich authentifiziert wurde, sendet der Pub/Sub-Proxy eine Veröffentlichungsanfrage an Pub/Sub. Mithilfe von IAM prüft Pub/Sub, ob der Aufrufer (der Pub/Sub-Proxy) die erforderlichen Berechtigungen zum Senden von Veröffentlichungsanfragen hat. In dieser Anleitung verwendet der Pub/Sub-Proxy das Compute Engine-Standarddienstkonto zur Authentifizierung bei Pub/Sub. Das Compute Engine-Standarddienstkonto hat die IAM-Rolle Bearbeiter (roles/editor
), die Publisher-Zugriffauf den Pub/Sub-Proxy bietet.
Ziele
- GKE-Cluster erstellen, um einen Pub/Sub-Proxy auszuführen
- Pub/Sub-Thema erstellen
- Pub/Sub-Proxy bereitstellen
- Endpoints für die Authentifizierung von Anfragen an den Pub/Sub-Proxy konfigurieren
- Prüfen, ob Nachrichten in Pub/Sub veröffentlicht werden
Kosten
In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:
Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.
Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.
Vorbereitung
-
Rufen Sie in der Google Cloud Console die Seite für die Projektauswahl auf.
-
Wählen Sie ein Google Cloud-Projekt aus oder erstellen Sie eines.
-
Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.
-
Aktivieren Sie Cloud Shell in der Google Cloud Console.
Unten in der Google Cloud Console wird eine Cloud Shell-Sitzung gestartet und eine Eingabeaufforderung angezeigt. Cloud Shell ist eine Shell-Umgebung, in der das Google Cloud CLI bereits installiert ist und Werte für Ihr aktuelles Projekt bereits festgelegt sind. Das Initialisieren der Sitzung kann einige Sekunden dauern.
- Definieren Sie die Umgebungsvariablen, die Sie für diese Anleitung benötigen:
export PROJECT=$(gcloud config get-value project) export REGION=us-central1 export ZONE=${REGION}-b export CLUSTER=pubsub-proxy export TOPIC=proxy-test export SERVICE_ACCOUNT=publish-test export ENDPOINTS_SERVICE="pubtest.endpoints.${PROJECT}.cloud.goog" export GENERATE_TOKEN="https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts"
- Aktivieren Sie die APIs für Cloud Build, Compute Engine, Google Kubernetes Engine, Artefaktanalyse, Container Registry, Endpoints, Service Management, Service Control und Pub/Sub:
gcloud services enable \ cloudbuild.googleapis.com \ compute.googleapis.com \ container.googleapis.com \ containeranalysis.googleapis.com \ containerregistry.googleapis.com \ endpoints.googleapis.com \ servicemanagement.googleapis.com \ servicecontrol.googleapis.com \ pubsub.googleapis.com
Pub/Sub-Thema erstellen
Erstellen Sie in Cloud Shell ein Pub/Sub-Thema, in dem Sie Nachrichten veröffentlichen wollen:
gcloud pubsub topics create $TOPIC
GKE-Cluster erstellen
Erstellen Sie in Cloud Shell einen GKE-Cluster:
gcloud container clusters create $CLUSTER \ --zone $ZONE \ --scopes "https://www.googleapis.com/auth/cloud-platform"
Rufen Sie Anmeldedaten für den ausgeführten Cluster ab:
gcloud container clusters get-credentials $CLUSTER \ --zone $ZONE \ --project $PROJECT
Container-Image erstellen
Klonen Sie in Cloud Shell das Code-Repository:
git clone https://github.com/GoogleCloudPlatform/solutions-pubsub-proxy-rest
Erstellen Sie mit Cloud Build ein Container-Image aus dem Quellcode und speichern Sie es dann in Container Registry:
cd solutions-pubsub-proxy-rest && \ gcloud builds submit --tag gcr.io/$PROJECT/pubsub-proxy:v1
Statische externe IP-Adresse erstellen
Erstellen Sie in Cloud Shell eine statische externe IP-Adresse, die später dem Load-Balancer des Pub/Sub-Proxys zugewiesen wird:
gcloud compute addresses create service-ip --region $REGION
Speichern Sie die statische IP-Adresse in der Umgebungsvariablen
PROXY_IP
:PROXY_IP=$(gcloud compute addresses describe service-ip \ --region $REGION --format='value(address)')
Endpoints bereitstellen
Der Pub/Sub-Proxy authentifiziert Anfragen von Nutzern mithilfe von Endpoints. Endpoints verwendet den Extensible Service Proxy (ESP), um API-Verwaltungsfunktionen wie Authentifizierung, Monitoring, Tracing und API-Lebenszyklusverwaltung bereitzustellen. In dieser Anleitung wird Endpoints nur für die Authentifizierung eingehender Anfragen an den Pub/Sub-Proxy verwendet.
In dieser Anleitung stellen Sie den ESP als Sidecar mit dem Pub/Sub-Proxy bereit. Der ESP fängt eingehende Anfragen ab und authentifiziert sie, bevor sie an den Pub/Sub-Proxy weitergeleitet werden.
Ersetzen Sie in Cloud Shell den Platzhalter
[PROJECT_ID]
in der Dateiopenapi.yaml
durch Ihre Google Cloud-Projekt-ID:sed -i -e "s/\[PROJECT_ID\]/$PROJECT/g" openapi.yaml
Ersetzen Sie in der OpenAPI-Manifestdatei den Platzhalter
[IP_ADDRESS]
durch den Wert vonPROXY_IP
:sed -i -e "s/\[IP_ADDRESS\]/$PROXY_IP/g" openapi.yaml
Stellen Sie die OpenAPI-Dienstdefinition in Endpoints bereit:
gcloud endpoints services deploy openapi.yaml
Der vorherige Befehl erstellt:
- Einen verwalteten Dienst mit dem Namen, den Sie im Feld "Host" in der
openapi.yaml
-Datei angegeben haben (pubtest.endpoints.project-id.cloud.goog
), wobeiproject-id
die ID Ihres Google Cloud-Projekts ist. - Einen DNS-A-Eintrag, der den Dienstnamen und die IP-Adresszuordnung des Pub/Sub-Proxy-Load-Balancers verwendet, die in der Erweiterung
x-google-endpoints
in der Dateiopenapi.yaml
definiert sind.
Während der Bereitstellung wird eine Warnung angezeigt, die Sie ignorieren können, da in dieser Anleitung anstelle von API-Schlüsseln OIDC-ID-Tokens für die Authentifizierung verwendet werden.
WARNING: openapi.yaml: Operation 'post' in path '/publish': Operation does not require an API key; callers may invoke the method without specifying an associated API-consuming project. To enable API key all the SecurityRequirement Objects (https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#security-requirement-object) inside security definition must reference at least one SecurityDefinition of type : 'apiKey'.
- Einen verwalteten Dienst mit dem Namen, den Sie im Feld "Host" in der
Prüfen Sie, ob der Dienst korrekt bereitgestellt wurde:
gcloud endpoints services describe ${ENDPOINTS_SERVICE}
Die Ausgabe sieht etwa so aus:
[...] producerProjectId: project-id serviceConfig: documentation: summary: Pub/Sub proxy exposed as an Endpoint API [...] name: pubtest.endpoints.project-id.cloud.goog title: PubSub Proxy usage: {} serviceName: pubtest.endpoints.project-id.cloud.goog
Dabei gilt:
project-id
: Die ID Ihres Google Cloud-Projekts.
Proxy bereitstellen
Generieren Sie in Cloud Shell ein selbst signiertes SSL-Zertifikat, um HTTPS-Verbindungen zum Proxy zuzulassen.
openssl req -x509 -nodes -days 365 \ -newkey rsa:2048 -keyout ./nginx.key \ -out ./nginx.crt \ -subj "/CN=${ENDPOINTS_SERVICE}"
Erstellen Sie mit dem SSL-Zertifikat und dem privaten Schlüssel ein Kubernetes-Secret:
kubectl create secret generic nginx-ssl \ --from-file=./nginx.crt \ --from-file=./nginx.key
Ersetzen Sie den Platzhalter
[PROJECT_ID]
in der Manifestdatei der Bereitstellung durch Ihre Google Cloud-Projekt-ID:sed -i -e "s/\[PROJECT_ID\]/$PROJECT/g" kube/deployment.yaml
Ersetzen Sie den Platzhalter
[IP_ADDRESS]
in der Dienstmanifestdatei durch den WertPROXY_IP
:sed -i -e "s/\[IP_ADDRESS\]/$PROXY_IP/g" kube/service.yaml
Stellen Sie den Proxy bereit:
kubectl apply -f kube/
Prüfen Sie, ob die Bereitstellung erfolgreich war:
kubectl rollout status deployment/pubsub-proxy
Die Ausgabe sieht etwa so aus:
[...] deployment "pubsub-proxy" successfully rolled out
Prüfen Sie, ob im Pod zwei Container (ESP und Pub/Sub-Proxy) ausgeführt werden:
kubectl get pods $(kubectl get pod \ -l app=pubsub-proxy \ -o jsonpath="{.items[0].metadata.name}") \ -o jsonpath={.spec.containers[*].name}
Die Ausgabe sieht etwa so aus:
esp pubsub-proxy
Achten Sie auf den Wert von
EXTERNAL-IP
, der von<pending>
in die zuvor erstellte statische externe IP-Adresse geändert wird:kubectl get svc pubsub-proxy -w
Die Ausgabe sieht etwa so aus:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE pubsub-proxy LoadBalancer 10.7.247.212 <pending> 443:31104/TCP 6m32s pubsub-proxy LoadBalancer 10.7.247.212 <PROXY_IP> 443:31104/TCP 6m5s
Drücken Sie
CTRL+C
, um die Wiedergabe zu beenden.Nachdem der Pub/Sub-Proxy erfolgreich bereitgestellt wurde, wird er unter
https://${ENDPOINTS_SERVICE}/publish
verfügbar gemacht. Es kann einige Minuten dauern, bis die neue DNS-Konfiguration verteilt wurde.Prüfen Sie die DNS-Konfiguration:
watch nslookup ${ENDPOINTS_SERVICE}
Die Ausgabe sieht etwa so aus:
Server: 169.254.169.254 Address: 169.254.169.254#53 Non-authoritative answer: Name: pubtest.endpoints.project-id.cloud.goog Address: gke-load-balancer-ip
Dabei gilt:
gke-load-balancer-ip
ist die IP-Adresse Ihres GKE-Load-Balancers (Proxy-IP).
Drücken Sie
CTRL+C
, um die Wiedergabe zu beenden.
Wenn einer der vorherigen Schritte zu einem Fehler führt, lesen Sie die Schritte zur Fehlerbehebung.
Authentifizierungstoken generieren
Das folgende Verfahren zum Generieren eines Authentifizierungstokens dient als Beispiel. Für Ihre Produktionsumgebung benötigen Sie eine Möglichkeit, mit Nutzer ihre eigenen Authentifizierungstoken generieren können. Beispielcode zum programmatischen Abrufen eines OIDC-ID-Tokens finden Sie in der Dokumentation zu Identity-Aware Proxy.
So generieren Sie ein Authentifizierungstoken:
Erstellen Sie ein Google Cloud-Dienstkonto, für das Sie ein OIDC-ID-Token generieren:
gcloud iam service-accounts create \ $SERVICE_ACCOUNT \ --display-name $SERVICE_ACCOUNT
Rufen Sie die E-Mail-Identität des Dienstkontos ab:
SA_EMAIL=${SERVICE_ACCOUNT}@${PROJECT}.iam.gserviceaccount.com
Weisen Sie dem Dienstkonto die IAM-Rolle Ersteller von Dienstkonto-Tokens (
roles/iam.serviceAccountTokenCreator
) zu:gcloud iam service-accounts add-iam-policy-binding $SA_EMAIL \ --member user:$(gcloud config get-value account) \ --role roles/iam.serviceAccountTokenCreator
Generieren Sie mithilfe der IAM Credentials API ein OIDC-ID-Token.
TOKEN=$(curl -s ${GENERATE_TOKEN}/${SA_EMAIL}:generateIdToken \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -d '{"audience": "'${ENDPOINTS_SERVICE}'", "includeEmail": "true"}' | jq -r ".token")
Der Endpoints-Dienstname wird im Feld
audience
angegeben. Dieaudience
-Anforderung identifiziert den Empfänger, für den das Token bestimmt ist.Prüfen Sie, ob das Token erfolgreich erstellt wurde:
echo $TOKEN
Das JSON-Webtoken (JWT) sieht in etwa so aus:
eyJhbGciOiJSUzI1NiIsImtpZCI6IjY4NjQyODlm[...].eyJhdWQiOiJwdWJ0ZXN0LmVuZHBvaW50cy52aXR hbC1vY3RhZ29uLTEwOTYxMi5jbG91ZC5nb[...].SjBI4TZjZAlYo6lFKkrvfAcVUp_AJzFKoSsjNbmD_n[...]
Pub/Sub über einen Proxy aufrufen
Veröffentlichen Sie in Cloud Shell eine Testnachricht:
curl -i -k -X POST https://${ENDPOINTS_SERVICE}/publish \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"topic": "'$TOPIC'", "messages": [ {"attributes": {"key1": "value1", "key2" : "value2"}, "data": "test data"}]}'
Die Ausgabe sieht etwa so aus:
HTTP/2 200 server: nginx date: Sun, 02 Jun 2019 03:53:46 GMT ...
Prüfen Sie, ob die Nachricht erfolgreich im Pub/Sub-Thema veröffentlicht wurde:
kubectl logs -f --tail=5 deployment/pubsub-proxy -c pubsub-proxy
In den Bereitstellungslogs des Pub/Sub-Proxys wird die Nachricht
Successfully published
angezeigt:2019-06-02 03:49:39.723:INFO:oejs.Server:main: Started @2554ms Jun 02, 2019 3:53:44 AM com.google.pubsub.proxy.publish.PublishMessage getPublisher INFO: Creating new publisher for: proxy-test Jun 02, 2019 3:53:47 AM com.google.pubsub.proxy.publish.PublishMessage$1 onSuccess INFO: Successfully published: 569006136173844
Fehlerbehebung
Prüfen Sie in Cloud Shell den Status der beiden Container im Pub/Sub-Proxy-Pod:
kubectl describe pods $(kubectl get pod -l app=pubsub-proxy \ -o jsonpath="{.items[0].metadata.name}")
In der Logausgabe lautet der Status der Container
Running
:[...] Containers: esp: [...] State: Running Started: Fri, 21 Jun 2019 16:41:30 +0530 Ready: True Restart Count: 0 [...] pubsub-proxy: State: Running Started: Fri, 21 Jun 2019 16:41:42 +0530 Ready: True Restart Count: 0 [...]
(Optional) Sehen Sie sich die Containerlogs an, um festzustellen, ob andere Fehler vorliegen. Führen Sie beispielsweise den folgenden Befehl aus, um die Pub/Sub-Proxy-Logs zu prüfen:
kubectl logs -f --tail=10 deployment/pubsub-proxy -c pubsub-proxy
Hilfe zur Fehlerbehebung finden Sie in den folgenden Dokumenten:
Bereinigen
Wenn Sie Kosten für Ihr Google Cloud-Konto für die in dieser Anleitung verwendeten Ressourcen vermeiden möchten, können Sie das Google Cloud-Projekt, das Sie für diese Anleitung erstellt haben, oder die mit dieser Anleitung verknüpften Ressourcen löschen.
Google Cloud-Projekt löschen
Am einfachsten vermeiden Sie weitere Kosten, indem Sie das für die Anleitung erstellte Projekt löschen.
- Wechseln Sie in der Google Cloud Console zur Seite Ressourcen verwalten.
- Wählen Sie in der Projektliste das Projekt aus, das Sie löschen möchten, und klicken Sie dann auf Löschen.
- Geben Sie im Dialogfeld die Projekt-ID ein und klicken Sie auf Shut down (Beenden), um das Projekt zu löschen.
Ressourcen löschen
Wenn Sie das in dieser Anleitung verwendete Google Cloud-Projekt beibehalten möchten, löschen Sie die einzelnen Ressourcen:
Löschen Sie den GKE-Cluster in Cloud Shell:
gcloud container clusters delete $CLUSTER --zone $ZONE --async
Löschen Sie heruntergeladenen Code, Artefakte und andere Abhängigkeiten:
cd .. && rm -rf solutions-pubsub-proxy-rest
Löschen Sie das Image in Container Registry:
gcloud container images list-tags \ gcr.io/$PROJECT/pubsub-proxy \ --format 'value(digest)' | \ xargs -I {} gcloud container images delete \ --force-delete-tags --quiet \ gcr.io/${PROJECT}/pubsub-proxy@sha256:{}
Löschen Sie das Pub/Sub-Thema:
gcloud pubsub topics delete $TOPIC
Löschen Sie das Dienstkonto:
gcloud iam service-accounts delete $SA_EMAIL
Löschen Sie Endpoints:
gcloud endpoints services delete ${ENDPOINTS_SERVICE}
Löschen Sie die statische IP-Adresse:
gcloud compute addresses delete service-ip --region $REGION
Nächste Schritte
- Authentifizierung mit Endpoints
- Architektur zur Verwendung von Pub/Sub für Aufgaben mit langer Ausführungszeit
- Referenzarchitekturen, Diagramme und Best Practices zu Google Cloud kennenlernen. Weitere Informationen zu Cloud Architecture Center