Mit Dienstkonten bei Google Cloud authentifizieren

In dieser Anleitung wird erläutert, wie Sie ein Google Cloud-Dienstkonto erstellen, Rollen für die Authentifizierung bei Google Cloud-Diensten zuweisen und Anmeldedaten für Dienstkonten in Anwendungen verwenden, die auf Google Kubernetes Engine (GKE) ausgeführt werden.

In diesem Beispiel geht es Pub/Sub, wobei die Anleitung auf jeden Google Cloud-Dienst angewendet werden kann. Die Beispielanwendung in dieser Anleitung authentifiziert sich mithilfe eines Dienstkontos bei Pub/Sub und abonniert Nachrichten, die von einer Python-basierten Anwendung in einem Pub/Sub-Thema veröffentlicht werden.

Ziele

Diese Anleitung umfasst die folgenden Schritte:

  • Wie Sie ein Dienstkonto erstellen
  • Wie Sie Ihrem Dienstkonto die erforderlichen Rollen für die Arbeit mit Pub/Sub zuweisen
  • Wie Sie den Kontoschlüssel als Kubernetes Secret speichern
  • Wie Sie das Dienstkonto zur Konfiguration und Bereitstellung einer Anwendung nutzen

Die in dieser Anleitung verwendete Beispielanwendung abonniert ein Pub/Sub-Thema und stellt die veröffentlichten Nachrichten über die Standardausgabe dar. Sie müssen in der Anwendung die richtigen Berechtigungen einrichten, Nachrichten mit gcloud command-line tool veröffentlichen und den Ausgabestream des Containers prüfen, um sicherzustellen, dass die Nachrichten ordnungsgemäß empfangen werden.

Bei Dienstkonten authentifizieren

Sie können sich mit Dienstkonten bei GKE-Diensten mithilfe von Workload Identity, dem Compute Engine-Standarddienstkonto oder Secrets bei Google Cloud authentifizieren.

Workload Identity verwenden

Für das Authentifizieren bei Google Cloud-Diensten aus GKE wird Workload Identity empfohlen. Mit Workload Identity können Sie Google Cloud-Dienstkonten mithilfe von Kubernetes-Ressourcen konfigurieren. Wenn diese Authentifizierungsmethode für Ihren Anwendungsfall geeignet ist, sollte sie die erste Option sein. In diesem Beispiel soll es um Anwendungsfälle gehen, in denen Workload Identity nicht geeignet ist.

Compute Engine-Standarddienstkonto verwenden

Jeder Knoten in einem GKE-Cluster ist eine Compute Engine-Instanz. Anwendungen, die auf einem GKE-Cluster ausgeführt werden, versuchen daher standardmäßig, sich mithilfe des Compute Engine-Standarddienstkontos zu authentifizieren, und übernehmen die verknüpften Bereiche.

Dieses Standarddienstkonto hat möglicherweise nicht die erforderlichen Berechtigungen für Google Cloud-Dienste. Es ist möglich, die Bereiche des Standarddienstkontos zu erweitern. Dies kann jedoch zu Sicherheitsrisiken führen und wird nicht empfohlen.

Anmeldedaten für Dienstkonten mithilfe von Secrets verwalten

Sie können ein Dienstkonto für Ihre Anwendung erstellen und den Authentifizierungsschlüssel als Kubernetes-Secret einfügen. Diese Option ist der Schwerpunkt dieser Anleitung.

Welche Vorteile bieten Dienstkonten?

Die Verwendung separater Dienstkonten für verschiedene Anwendungen bietet die folgenden Vorteile:

  • Bessere Transparenz und Überprüfung der API-Anfragen Ihrer Anwendung

  • Die Möglichkeit, Schlüssel für bestimmte Anwendungen zu widerrufen, anstatt ein Dienstkonto freizugeben und den API-Zugriff aller Anwendungen gleichzeitig aufheben zu müssen.

  • Geringeres Risiko, wenn die Anmeldedaten des Dienstkontos bei einem potenziellen Sicherheitsvorfall kompromittiert werden

Vorbereitung

Führen Sie folgende Schritte aus, um die Kubernetes Engine API zu aktivieren:
  1. Rufen Sie in der Google Cloud Console die Seite Kubernetes Engine auf.
  2. Erstellen Sie ein Projekt oder wählen Sie eines aus.
  3. Warten Sie, bis die API und die zugehörigen Dienste aktiviert worden sind. Dieser Vorgang kann einige Minuten dauern.
  4. Die Abrechnung für das Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für Ihr Projekt aktiviert ist.

Installieren Sie die folgenden Befehlszeilentools, die in dieser Anleitung verwendet werden:

  • Mit gcloud werden Kubernetes Engine-Cluster erstellt und gelöscht. gcloud ist im Google Cloud SDK enthalten.
  • kubectl wird zur Verwaltung von Kubernetes verwendet, dem Cluster-Orchestrierungssystem von Kubernetes Engine. Sie können kubectl mit gcloud installieren:
    gcloud components install kubectl

Klonen Sie den Beispielcode aus GitHub:

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/cloud-pubsub/deployment

Standards für das gcloud-Befehlszeilentool festlegen

Wenn Sie die Projekt-ID und die Optionen für die Compute Engine-Zone nicht immer wieder neu in das gcloud-Befehlszeilentool eingeben möchten, können Sie die Standardwerte festlegen:
gcloud config set project project-id
gcloud config set compute/zone compute-zone

APIs aktivieren

Aktivieren Sie für diese Anleitung die Pub/Sub API und Resource Manager API in Ihrem Projekt:

gcloud services enable cloudresourcemanager.googleapis.com pubsub.googleapis.com

Containercluster erstellen

Erstellen Sie einen Containercluster mit dem Namen pubsub-test, um die Pub/Sub-Abonnentenanwendung bereitzustellen:

gcloud container clusters create pubsub-test

Pub/Sub-Thema erstellen

Die Pub/Sub-Abonnentenanwendung verwendet ein Abo mit dem Namen echo-read für ein Pub/Sub-Thema namens echo. Erstellen Sie vor dem Deployment der Anwendung die im Folgenden aufgeführten Ressourcen.

Erstellen Sie zuerst ein Pub/Sub-Thema:

gcloud

gcloud pubsub topics create echo

Config Connector

Hinweis: Für diesen Schritt ist Config Connector erforderlich. Folgen Sie der Installationsanleitung, um Config Connector in Ihrem Cluster zu installieren.

apiVersion: pubsub.cnrm.cloud.google.com/v1beta1
kind: PubSubTopic
metadata:
  name: echo
Laden Sie dieses Manifest als Datei "topic.yaml" auf Ihren Rechner herunter, um es bereitzustellen. Führen Sie dann Folgendes aus:
kubectl apply -f topic.yaml

Erstellen Sie anschließend ein Abo:

gcloud

gcloud pubsub subscriptions create echo-read --topic=echo

Config Connector

apiVersion: pubsub.cnrm.cloud.google.com/v1beta1
kind: PubSubSubscription
metadata:
  name: echo-read
spec:
  topicRef:
    name: echo
Laden Sie dieses Manifest als Datei "subscription.yaml" auf Ihren Rechner herunter, um es bereitzustellen. Führen Sie dann Folgendes aus:
kubectl apply -f subscription.yaml

Pub/Sub-Abonnentenanwendung bereitstellen

Stellen Sie als Nächstes den Anwendungscontainer bereit, um die Nachrichten abzurufen, die im Pub/Sub-Thema veröffentlicht wurden. Diese Anwendung wurde mit Google Cloud Pub/Sub-Clientbibliotheken in Python geschrieben. Sie finden den Quellcode auf GitHub.

Die folgende Manifestdatei beschreibt ein Deployment, das eine einzelne Instanz des Docker-Images dieser Anwendung ausführt:

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pubsub
spec:
  selector:
    matchLabels:
      app: pubsub
  template:
    metadata:
      labels:
        app: pubsub
    spec:
      containers:
      - name: subscriber
        image: gcr.io/google-samples/pubsub-sample:v1

Führen Sie folgenden Befehl aus, um dieses Manifest bereitzustellen:

kubectl apply -f pubsub.yaml

Nachdem die Anwendung bereitgestellt wurde, führen Sie mit dem folgenden Befehl eine Abfrage der Pods durch:

kubectl get pods -l app=pubsub
Ausgabe:
NAME                      READY     STATUS             RESTARTS   AGE
pubsub-2009462906-1l6bh   0/1       CrashLoopBackOff   1          30s

Sie stellen fest, dass der Container nicht gestartet wurde und sich im Status CrashLoopBackOff befindet. Überprüfen Sie die Logs des Pods mit folgendem Befehl:

kubectl logs -l app=pubsub

Ausgabe:

...
google.gax.errors.RetryError: RetryError(Exception occurred in retry method that
was not classified as transient, caused by <_Rendezvous (StatusCode.PERMISSION_DENIED, scopes.) of RPC that terminated with Request had insufficient authentication>)

Der Stacktrace und die Fehlermeldung zeigen an, dass die Anwendung keine Berechtigungen hat, um den Pub/Sub-Dienst abzufragen.

Anmeldedaten für das Dienstkonto erstellen

Damit Ihre Anwendung in GKE auf Google Cloud-Dienste zugreifen kann, verwenden Sie Dienstkonten. Mithilfe von Dienstkonten können Sie eine Reihe von IAM-Berechtigungen (Identity and Access Management) für Ihre Anwendung definieren.

Console

So erstellen Sie ein Dienstkonto:

  1. Rufen Sie in der Cloud Console die Seite Dienstkonten auf.

    Zur Seite „Dienstkonten“

  2. Klicken Sie auf Dienstkonto erstellen.

  3. Geben Sie unter Dienstkontodetails einen Dienstkontonamen ein, z. B. pubsub-app.

  4. Optional können Sie auch die Dienstkonto-ID ändern und eine Beschreibung hinzufügen.

  5. Klicken Sie auf Erstellen.

  6. Wählen Sie unter Diesem Dienstkonto Zugriff auf ein Projekt gewähren aus der Drop-down-Liste Rolle auswählen die Option Pub/Sub-Subscriber aus.

  7. Klicken Sie auf Weiter und dann auf Fertig, um das Dienstkonto zu erstellen.

  8. Klicken Sie in der Liste der Dienstkonten neben dem erstellten Dienstkonto auf Aktionen > Schlüssel verwalten.

  9. Klicken Sie auf Schlüssel hinzufügen > Neuen Schlüssel erstellen.

  10. Wählen Sie unter Schlüsseltyp die Option JSON aus.

  11. Klicken Sie auf Erstellen.

Nach der Erstellung des Schlüssels wird eine JSON-Datei mit den Anmeldedaten des Dienstkontos auf Ihren Computer heruntergeladen. Mit dieser Schlüsseldatei konfigurieren Sie die Anwendung für die Authentifizierung bei der Pub/Sub API.

Config Connector

Laden Sie zuerst die folgende Ressource als Datei "service-account.yaml" herunter.

apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMServiceAccount
metadata:
  name: pubsub-app
spec:
  displayName: Service account for PubSub example

Führen Sie dann diesen Befehl aus:

kubectl apply -f service-account.yaml

Wenden Sie als Nächstes die Rolle "Pub/Sub-Abonnent" auf das Dienstkonto an. Laden Sie die folgende Ressource als Datei "service-account-policy.yaml" herunter. Ersetzen Sie [PROJECT_ID] durch Ihre Projekt-ID.

apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
  name: policy-member-binding
spec:
  member: serviceAccount:pubsub-app@[PROJECT_ID].iam.gserviceaccount.com
  role: roles/pubsub.subscriber
  resourceRef:
    apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
    kind: Project
    external: projects/[PROJECT_ID]

Führen Sie dann diesen Befehl aus:

kubectl apply -f service-account-policy.yaml

Anmeldedaten als Secret importieren

Jetzt, da Sie den Dienstkontoschlüssel haben, müssen Sie ihn irgendwie in Ihren Container laden. Ihr erster Impuls ist vielleicht, einen Schritt in Ihr Dockerfile einzufügen, aber Dienstkontoschlüssel sind sicherheitsrelevante Dateien, die nicht in Container-Images gespeichert werden sollten.

Stattdessen bietet Kubernetes den Ressourcentyp Secret, um private Dateien zur Laufzeit sicher in Pods bereitzustellen.

kubectl

Führen Sie zum Speichern der JSON-Schlüsseldatei als Secret mit der Bezeichnung pubsub-key den im Folgenden aufgeführten Befehl aus. Er enthält den Pfad zu der heruntergeladenen Datei mit den Anmeldedaten für das Dienstkonto enthält.

kubectl create secret generic pubsub-key --from-file=key.json=PATH-TO-KEY-FILE.json

Mit diesem Befehl wird ein Secret mit dem Namen pubsub-key erstellt, das die Datei key.json mit den Inhalten des privaten Schlüssels enthält, den Sie von der Cloud Console heruntergeladen haben. Nachdem Sie das Secret erstellt haben, entfernen Sie die Schlüsseldatei von Ihrem Computer.

Config Connector

Laden Sie die folgende Ressource als Datei "service-account-key.yaml" herunter.

apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMServiceAccountKey
metadata:
  name: pubsub-key
spec:
  publicKeyType: TYPE_X509_PEM_FILE
  keyAlgorithm: KEY_ALG_RSA_2048
  privateKeyType: TYPE_GOOGLE_CREDENTIALS_FILE
  serviceAccountRef:
    name: pubsub-app

Führen Sie dann diesen Befehl aus:

kubectl apply -f service-account-key.yaml

Anwendung mit dem Secret konfigurieren

Um das Secret pubsub-key in Ihrer Anwendung zu verwenden, ändern Sie die Deployment-Spezifikation in:

  1. Definieren Sie ein Volume mit dem Secret.
  2. Stellen Sie das Secret-Volume im Anwendungscontainer bereit.
  3. Stellen Sie ein, dass die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS auf die Schlüsseldatei in der Secret-Volume-Bereitstellung verweist.

Die aktualisierte Manifestdatei sieht so aus:

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pubsub
spec:
  selector:
    matchLabels:
      app: pubsub
  template:
    metadata:
      labels:
        app: pubsub
    spec:
      volumes:
      - name: google-cloud-key
        secret:
          secretName: pubsub-key
      containers:
      - name: subscriber
        image: gcr.io/google-samples/pubsub-sample:v1
        volumeMounts:
        - name: google-cloud-key
          mountPath: /var/secrets/google
        env:
        - name: GOOGLE_APPLICATION_CREDENTIALS
          value: /var/secrets/google/key.json

Mit dieser Manifestdatei werden folgende Felder festgelegt, damit die Anmeldedaten für die Anwendung zur Verfügung stehen:

  • Ein Volume mit dem Namen google-cloud-key, das das Secret mit dem Namen pubsub-key verwendet.

  • Eine Volume-Bereitstellung, die google-cloud-key im Verzeichnis /var/secrets/google innerhalb des Containers verfügbar macht.

  • Eine Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS, die als /var/secrets/google/key.json festgelegt ist. Sie enthält die Datei mit den Anmeldedaten, nachdem das Secret als Volume im Container bereitgestellt wurde.

Beachten Sie, dass die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS von Google Cloud-Clientbibliotheken automatisch erkannt wird – in diesem Fall der Pub/Sub-Client für Python.

Führen Sie folgenden Befehl aus, um dieses Manifest bereitzustellen:

kubectl apply -f pubsub-with-secret.yaml

Prüfen Sie, ob der Pod-Status Running lautet:

kubectl get pods -l app=pubsub
Ausgabe:
NAME                     READY     STATUS    RESTARTS   AGE
pubsub-652482369-2d6h2   1/1       Running   0          29m

Empfang von Pub/Sub-Nachrichten testen

Nachdem Sie nun die Anwendung konfiguriert haben, veröffentlichen Sie im Pub/Sub-Thema eine Nachricht mit dem Namen echo:

gcloud pubsub topics publish echo --message="Hello, world!"

Innerhalb von wenigen Sekunden wird die Nachricht von der Anwendung übernommen und in den Ausgabestream gedruckt. Mit dem folgenden Befehl können Sie die Protokolle des bereitgestellten Pods überprüfen:

kubectl logs -l app=pubsub
Ausgabe:
Pulling messages from Pub/Sub subscription...
[2017-06-19 12:31:42.501123] ID=130941112144812 Data=Hello, world!

Sie haben jetzt in GKE eine Anwendung für die Authentifizierung bei der Pub/Sub API mit Dienstkonto-Anmeldedaten konfiguriert.

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie entweder das Projekt, das die Ressourcen enthält, oder Sie behalten das Projekt und löschen die einzelnen Ressourcen.

  1. Bereinigen Sie das Pub/Sub-Abo und -Thema:

    gcloud pubsub subscriptions delete echo-read
    gcloud pubsub topics delete echo
  2. Löschen Sie den Containercluster:

    gcloud container clusters delete pubsub-test

Weitere Informationen