Dienstsicherheit mit proxylosem gRPC einrichten (Legacy)

In dieser Anleitung wird gezeigt, wie Sie einen Sicherheitsdienst für ein proxyloses gRPC-Service-Mesh konfigurieren.

Dieses Dokument bezieht sich nur auf Cloud Service Mesh mit den Load Balancing APIs. Dies ist ein älteres Dokument.

Voraussetzungen

Damit die Dienstsicherheit für ein proxyloses gRPC-Service-Mesh konfiguriert werden kann, müssen Sie die folgenden Voraussetzungen erfüllt sein:

Identitäts- und Zugriffsverwaltung konfigurieren

Sie benötigen die erforderlichen Berechtigungen für die Verwendung von Google Kubernetes Engine. Sie benötigen mindestens die folgenden Rollen:

  • GKE-Rolle roles/container.clusterAdmin
  • Compute Engine-Rolle roles/compute.instanceAdmin
  • Rolle roles/iam.serviceAccountUser

Zum Erstellen der für die Einrichtung erforderlichen Ressourcen benötigen Sie die Rolle compute.NetworkAdmin. Diese Rolle enthält alle notwendigen Berechtigungen zum Erstellen, Aktualisieren, Löschen, Auflisten und Verwenden (d. h. zum Verweisen in anderen Ressourcen) der erforderlichen Ressourcen. Wenn Sie der Inhaber-Bearbeiter Ihres Projekts sind, wurde Ihnen diese Rolle automatisch zugewiesen.

Beachten Sie, dass networksecurity.googleapis.com.clientTlsPolicies.use und networksecurity.googleapis.com.serverTlsPolicies.use nicht erzwungen werden, wenn Sie auf diese Ressourcen im Backend-Dienst und Ziel-HTTPS-Proxy verweisen.

Wenn diese Prüfung in Zukunft erzwungen wird, werden Sie mit der Rolle compute.NetworkAdmin keine Probleme feststellen.

Wenn Sie benutzerdefinierte Rollen verwenden, müssen Sie die entsprechende Berechtigung .use angeben, sollte diese Prüfung in Zukunft erzwungen werden. Andernfalls werden Sie in Zukunft möglicherweise feststellen, dass Ihre benutzerdefinierte Rolle nicht die erforderlichen Berechtigungen hat, um auf clientTlsPolicy oder serverTlsPolicy vom Backend-Dienst bzw. Ziel-HTTPS-Proxy zu verweisen.

Einrichtung vorbereiten

Mit PSM-Sicherheit (proxyloses Service Mesh) wird die Sicherheit für ein Service Mesh erhöht, das gemäß der Dokumentation für proxylose gRPC-Dienste für das Load-Balancing eingerichtet ist. In einem proxylosen Service Mesh verwendet ein gRPC-Client das Schema xds: im URI für den Zugriff auf den Dienst. Dadurch werden die Features für das PSM-Load-Balancing und die Endpunkterkennung aktiviert.

gRPC-Clients und -Server auf die richtige Version aktualisieren

Erstellen Sie Ihre Anwendungen mit der unterstützten Mindestversion von gRPC für Ihre Sprache (ggf. Neuerstellung).

Bootstrap-Datei aktualisieren

gRPC-Anwendungen verwenden eine einzelne Bootstrap-Datei, die alle Felder enthalten muss, die für clientseitigen und serverseitigen gRPC-Code erforderlich sind. Ein Bootstrap-Generator erstellt die Bootstrap-Datei automatisch und fügt dabei die Flags sowie Werte hinzu, die für die PSM-Sicherheit erforderlich sind. Weitere Informationen finden Sie im Abschnitt Bootstrap-Datei, der auch eine beispielhafte Bootstrap-Datei enthält.

Einrichtung: Übersicht

Dieser Einrichtungsprozess ist eine Erweiterung des Cloud Service Mesh einrichten mit GKE und proxylosen gRPC-Diensten. Auf vorhandene nicht geänderte Schritte dieses Einrichtungsverfahrens wird jeweils verwiesen.

Die wichtigsten Verbesserungen der Cloud Service Mesh-Einrichtung mit GKE:

  1. Einrichten von CA Service, in dem Sie private CA-Pools und die erforderlichen Zertifizierungsstellen erstellen
  2. Erstellen eines GKE-Clusters mit Features für GKE Workload Identity Federation for GKE und Mesh-Zertifikate sowie Einbindung in CA Service
  3. Konfigurieren der Ausstellung von Mesh-Zertifikaten im Cluster
  4. Erstellen der Client- und Serverdienstkonten
  5. Beispielserver einrichten das xDS APIs und xDS-Serveranmeldedaten verwendet, um Sicherheit zu gewährleisten Konfiguration aus dem Cloud Service Mesh.
  6. Einrichten des Beispielclients, der xDS-Anmeldedaten verwendet
  7. Cloud Service Mesh-Konfiguration aktualisieren, um die Sicherheitskonfiguration einzubeziehen.

Codebeispiele für die Verwendung von xDS-Anmeldedaten finden Sie an den folgenden Speicherorten:

Google Cloud CLI aktualisieren

Führen Sie folgenden Befehl aus, um Google Cloud CLI zu aktualisieren:

gcloud components update

Umgebungsvariablen einrichten

In dieser Anleitung verwenden Sie Cloud Shell-Befehle. Mehrfach in den Befehlen verwendete Informationen werden durch diverse Umgebungsvariablen dargestellt. Legen Sie in der Shell-Umgebung für Ihre speziellen Werte die folgenden Umgebungsvariablen fest, bevor Sie die Befehle ausführen. Jede Kommentarzeile gibt die Bedeutung der zugehörigen Umgebungsvariablen an.

# Your project ID
PROJECT_ID=YOUR_PROJECT_ID

# GKE cluster name and zone for this example.
CLUSTER_NAME="secure-psm-cluster"
ZONE="us-east1-d"

# GKE cluster URL derived from the above
GKE_CLUSTER_URL="https://container.googleapis.com/v1/projects/${PROJECT_ID}/locations/${ZONE}/clusters/${CLUSTER_NAME}"

# Workload pool to be used with the GKE cluster
WORKLOAD_POOL="${PROJECT_ID}.svc.id.goog"

# Kubernetes namespace to run client and server demo.
K8S_NAMESPACE='default'
DEMO_BACKEND_SERVICE_NAME='grpc-gke-helloworld-service'

# Compute other values
# Project number for your project
PROJNUM=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")

# VERSION is the GKE cluster version. Install and use the most recent version
# from the rapid release channel and substitute its version for
# CLUSTER_VERSION, for example:
# VERSION=latest available version
# Note that the minimum required cluster version is 1.21.4-gke.1801.
VERSION="CLUSTER_VERSION"
SA_GKE=service-${PROJNUM}@container-engine-robot.iam.gserviceaccount.com

Zugriff auf erforderliche APIs aktivieren

In diesem Abschnitt wird gezeigt, wie Sie den Zugriff auf die erforderlichen APIs aktivieren.

  1. Führen Sie den folgenden Befehl aus, um das Cloud Service Mesh und andere APIs zu aktivieren erforderlich für die proxylose Sicherheit des gRPC-Service-Mesh.

    gcloud services enable \
        container.googleapis.com \
        cloudresourcemanager.googleapis.com \
        compute.googleapis.com \
        trafficdirector.googleapis.com \
        networkservices.googleapis.com \
        networksecurity.googleapis.com \
        privateca.googleapis.com \
        gkehub.googleapis.com
    
  2. Führen Sie den folgenden Befehl aus, damit das Standarddienstkonto auf die Cloud Service Mesh Security API

    GSA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \
        --filter='displayName:Compute Engine default service account')
    
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member serviceAccount:${GSA_EMAIL} \
       --role roles/trafficdirector.client
    

GKE-Cluster erstellen oder aktualisieren

Die Sicherheit von Cloud Service Mesh-Diensten hängt von der CA Service-Einbindung in GKE ab. Der GKE-Cluster muss zusätzlich zu den Anforderungen für die Einrichtung die folgenden Anforderungen erfüllen:

  • Verwenden Sie eine Mindestclusterversion von 1.21.4-gke.1801. Wenn Sie Funktionen einer späteren Version benötigen, können Sie diese Version über den Rapid Release Channel abrufen.
  • Der GKE-Cluster muss mit Mesh-Zertifikaten aktiviert und konfiguriert sein, wie unter Zertifizierungsstellen zum Ausstellen von Zertifikaten erstellen erläutert.
  1. Erstellen Sie einen neuen Cluster, der die Workload Identity Federation for GKE verwendet. Wenn Sie einen vorhandenen Cluster aktualisieren, fahren Sie mit dem nächsten Schritt fort. Der Wert, den Sie für --tags angeben, muss mit dem Namen übereinstimmen, der an das Flag --target-tags für den Befehl firewall-rules create im Abschnitt Cloud Service Mesh mit Cloud Load Balancing-Komponenten konfigurieren übergeben wurde.

    # Create a GKE cluster with GKE managed mesh certificates.
    gcloud container clusters create CLUSTER_NAME \
      --release-channel=rapid \
      --scopes=cloud-platform \
      --image-type=cos_containerd \
      --machine-type=e2-standard-2 \
      --zone=ZONE \
      --workload-pool=PROJECT_ID.svc.id.goog \
      --enable-mesh-certificates \
      --cluster-version=CLUSTER_VERSION \
      --enable-ip-alias \
      --tags=allow-health-checks \
      --workload-metadata=GKE_METADATA
    

    Die Erstellung eines Clusters kann einige Minuten dauern.

  2. Wenn Sie einen vorhandenen Cluster verwenden, aktivieren Sie die Identitätsföderation von Arbeitslasten für GKE und GKE-Mesh-Zertifikate. Achten Sie darauf, dass der Cluster mit dem Flag --enable-ip-alias erstellt wurde, das nicht mit dem Befehl update verwendet werden kann.

    gcloud container clusters update CLUSTER_NAME \
      --enable-mesh-certificates
    
  3. Mit dem folgenden Befehl wechseln Sie zum neuen Cluster als Standardcluster für Ihre kubectl-Befehle:

    gcloud container clusters get-credentials CLUSTER_NAME \
      --zone ZONE
    

Cluster bei einer Flotte registrieren

Registrieren Sie den Cluster, den Sie unter GKE-Cluster erstellen erstellt oder aktualisiert haben bei einer Flotte. Durch Registrierung des Clusters lässt sich die projektübergreifende Konfiguration von Clustern vereinfachen.

Die Ausführung dieser Schritte kann bis zu zehn Minuten dauern.

  1. Registrieren Sie den Cluster bei der Flotte:

    gcloud container fleet memberships register CLUSTER_NAME \
      --gke-cluster=ZONE/CLUSTER_NAME \
      --enable-workload-identity --install-connect-agent \
      --manifest-output-file=MANIFEST-FILE_NAME
    

    Ersetzen Sie dabei folgende Variablen:

    • CLUSTER_NAME: Der Name Ihres Clusters.
    • ZONE: Die Zone Ihres Clusters.
    • MANIFEST-FILE_NAME: Pfad, unter dem diese Befehle das Manifest für die Registrierung generieren.

    Nach erfolgreicher Registrierung wird eine Meldung wie die folgende angezeigt:

    Finished registering the cluster CLUSTER_NAME with the fleet.
  2. Wenden Sie die generierte Manifestdatei auf Ihren Cluster an:

    kubectl apply -f MANIFEST-FILE_NAME
    

    Wenn der Anwendungsprozess erfolgreich ist, werden Meldungen wie die folgenden angezeigt:

    namespace/gke-connect created
    serviceaccount/connect-agent-sa created
    podsecuritypolicy.policy/gkeconnect-psp created
    role.rbac.authorization.k8s.io/gkeconnect-psp:role created
    rolebinding.rbac.authorization.k8s.io/gkeconnect-psp:rolebinding created
    role.rbac.authorization.k8s.io/agent-updater created
    rolebinding.rbac.authorization.k8s.io/agent-updater created
    role.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created
    clusterrole.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created
    clusterrolebinding.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created
    clusterrolebinding.rbac.authorization.k8s.io/gke-connect-feature-authorizer-20210416-01-00 created
    rolebinding.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created
    role.rbac.authorization.k8s.io/gke-connect-namespace-getter created
    rolebinding.rbac.authorization.k8s.io/gke-connect-namespace-getter created
    secret/http-proxy created
    deployment.apps/gke-connect-agent-20210416-01-00 created
    service/gke-connect-monitoring created
    secret/creds-gcp create
    
  3. Rufen Sie die Mitgliedschaftsressource aus dem Cluster ab:

    kubectl get memberships membership -o yaml
    

    Die Ausgabe sollte den Workload Identity-Pool enthalten, der von der Flotte zugewiesen wurde, wobei PROJECT_ID Ihre Projekt-ID ist:

    workload_identity_pool: PROJECT_ID.svc.id.goog
    

    Das bedeutet, dass der Cluster erfolgreich registriert wurde.

Zertifizierungsstellen zum Ausstellen von Zertifikaten erstellen

Wenn Sie Zertifikate an Ihre Pods ausstellen möchten, erstellen Sie einen CA Service-Pool und die folgenden Zertifizierungsstellen (Certificate Authorities, CA):

  • Stamm-CA. Dies ist der Root of Trust für alle ausgestellten Mesh-Zertifikate. Sie können eine vorhandene Stamm-CA verwenden, sofern vorhanden. Erstellen Sie die Stamm-CA auf der Ebene enterprise, die für die Ausgabe von langlebigen Zertifikaten mit geringem Volumen vorgesehen ist.
  • Untergeordnete CA. Diese Zertifizierungsstelle stellt Zertifikate für Arbeitslasten aus. Erstellen Sie die untergeordnete CA in der Region, in der Ihr Cluster bereitgestellt wird. Erstellen Sie die untergeordnete Zertifizierungsstelle (Certificate Authority, CA) auf der Ebene devops, die für die Ausstellung von kurzlebigen Zertifikaten mit hohem Volumen vorgesehen ist.

Das Erstellen einer untergeordneten CA ist optional. Wir empfehlen aber dringend, eine solche Zertifizierungsstelle zu verwenden, anstatt zum Ausstellen von GKE-Mesh-Zertifikaten Ihre Stamm-CA zu nutzen. Wenn Sie die Stamm-CA zum Ausstellen von Mesh-Zertifikaten verwenden, achten Sie darauf, dass der standardmäßige konfigurationsbasierte Ausstellungsmodus zulässig ist.

Die untergeordnete Zertifizierungsstelle kann sich in einer anderen Region als der Cluster befinden. Es wird jedoch dringend empfohlen, sie in der Region zu erstellen, in der sich auch Ihr Cluster befindet, um die Leistung zu optimieren. Stamm- und untergeordnete CAs können sich Sie dagegen in verschiedenen Regionen befinden. Die Leistung oder Verfügbarkeit wird damit nicht beeinträchtigt.

CA Service wird in diesen Regionen unterstützt:

Name der Region Beschreibung der Region
asia-east1 Taiwan
asia-east2 Hongkong
asia-northeast1 Tokio
asia-northeast2 Osaka
asia-northeast3 Seoul
asia-south1 Mumbai
asia-south2 Delhi
asia-southeast1 Singapur
asia-southeast2 Jakarta
australia-southeast1 Sydney
australia-southeast2 Melbourne
europe-central2 Warschau
europe-north1 Finnland
europe-southwest1 Madrid
europe-west1 Belgien
europe-west2 London
europe-west3 Frankfurt
europe-west4 Niederlande
europe-west6 Zürich
europe-west8 Mailand
europe-west9 Paris
europe-west10 Berlin
europe-west12 Turin
me-central1 Doha
me-central2 Dammam
me-west1 Tel Aviv
northamerica-northeast1 Montreal
northamerica-northeast2 Toronto
southamerica-east1 São Paulo
southamerica-west1 Santiago
us-central1 Iowa
us-east1 South Carolina
us-east4 Northern Virginia
us-east5 Columbus
us-south1 Dallas
us-west1 Oregon
us-west2 Los Angeles
us-west3 Salt Lake City
us-west4 Las Vegas

Die Liste der unterstützten Standorte können Sie auch mit folgendem Befehl prüfen:

gcloud privateca locations list
  1. Weisen Sie den Personen, die einen CA-Pool und eine CA erstellen, die IAM-Rolle roles/privateca.caManager zu. Beachten Sie, dass für MEMBER das korrekte Format so lautet: user:userid@example.com. Wenn diese Person der aktuelle Nutzer ist, können Sie die aktuelle Nutzer-ID mit dem Shell-Befehl $(gcloud auth list --filter=status:ACTIVE --format="value(account)") abrufen.

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=MEMBER \
      --role=roles/privateca.caManager
    
  2. Nutzern die Rolle role/privateca.admin für CA Service gewähren die IAM-Richtlinien ändern müssen, wobei MEMBER ein die diesen Zugriff benötigen, insbesondere Personen, die folgenden Schritte ausführen, um die privateca.auditor und privateca.certificateManager-Rollen:

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=MEMBER \
      --role=roles/privateca.admin
    
  3. Erstellen Sie einen Stamm-CA-Service-Pool.

    gcloud privateca pools create ROOT_CA_POOL_NAME \
      --location ROOT_CA_POOL_LOCATION \
      --tier enterprise
    
  4. Erstellen Sie eine Stamm-CA.

    gcloud privateca roots create ROOT_CA_NAME --pool ROOT_CA_POOL_NAME \
      --subject "CN=ROOT_CA_NAME, O=ROOT_CA_ORGANIZATION" \
      --key-algorithm="ec-p256-sha256" \
      --max-chain-length=1 \
      --location ROOT_CA_POOL_LOCATION
    

    Verwenden Sie für diese Demoeinrichtung die folgenden Werte für die Variablen:

    • ROOT_CA_POOL_NAME=td_sec_pool
    • ROOT_CA_NAME=pkcs2-ca
    • ROOT_CA_POOL_LOCATION=us-east1
    • ROOT_CA_ORGANIZATION="TestCorpLLC"
  5. Erstellen Sie einen untergeordneten Pool und eine untergeordnete CA. Achten Sie darauf, dass der konfigurationsbasierte Standardausstellungsmodus weiterhin zulässig ist.

    gcloud privateca pools create SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --tier devops
    
    gcloud privateca subordinates create SUBORDINATE_CA_NAME \
      --pool SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --issuer-pool ROOT_CA_POOL_NAME \
      --issuer-location ROOT_CA_POOL_LOCATION \
      --subject "CN=SUBORDINATE_CA_NAME, O=SUBORDINATE_CA_ORGANIZATION" \
      --key-algorithm "ec-p256-sha256" \
      --use-preset-profile subordinate_mtls_pathlen_0
    

    Verwenden Sie für diese Demoeinrichtung die folgenden Werte für die Variablen:

    • SUBORDINATE_CA_POOL_NAME="td-ca-pool"
    • SUBORDINATE_CA_POOL_LOCATION=us-east1
    • SUBORDINATE_CA_NAME="td-ca"
    • SUBORDINATE_CA_ORGANIZATION="TestCorpLLC"
    • ROOT_CA_POOL_NAME=td_sec_pool
    • ROOT_CA_POOL_LOCATION=us-east1
  6. Weisen Sie die IAM-Rolle privateca.auditor für die Stamm-CA zu, um den Zugriff vom GKE-Dienstkonto zuzulassen:

    gcloud privateca pools add-iam-policy-binding ROOT_CA_POOL_NAME \
     --location ROOT_CA_POOL_LOCATION \
     --role roles/privateca.auditor \
     --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
    
  7. Weisen Sie der untergeordneten CA die IAM-Rolle privateca.certificateManager zu, um den Zugriff vom GKE-Dienstkonto zuzulassen:

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --role roles/privateca.certificateManager \
      --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
    
  8. Speichern Sie die folgende WorkloadCertificateConfig-YAML-Konfiguration, um für Ihren Cluster festzulegen, wie Mesh-Zertifikate ausgegeben werden:

    apiVersion: security.cloud.google.com/v1
    kind: WorkloadCertificateConfig
    metadata:
      name: default
    spec:
      # Required. The CA service that issues your certificates.
      certificateAuthorityConfig:
        certificateAuthorityServiceConfig:
          endpointURI: ISSUING_CA_POOL_URI
    
      # Required. The key algorithm to use. Choice of RSA or ECDSA.
      #
      # To maximize compatibility with various TLS stacks, your workloads
      # should use keys of the same family as your root and subordinate CAs.
      #
      # To use RSA, specify configuration such as:
      #   keyAlgorithm:
      #     rsa:
      #       modulusSize: 4096
      #
      # Currently, the only supported ECDSA curves are "P256" and "P384", and the only
      # supported RSA modulus sizes are 2048, 3072 and 4096.
      keyAlgorithm:
        rsa:
          modulusSize: 4096
    
      # Optional. Validity duration of issued certificates, in seconds.
      #
      # Defaults to 86400 (1 day) if not specified.
      validityDurationSeconds: 86400
    
      # Optional. Try to start rotating the certificate once this
      # percentage of validityDurationSeconds is remaining.
      #
      # Defaults to 50 if not specified.
      rotationWindowPercentage: 50
    
    

    Dabei gilt:

    • Die Projekt-ID des Projekts, in dem der Cluster ausgeführt wird.
      PROJECT_ID
    • Der voll qualifizierte URI der Zertifizierungsstelle, die Ihre Mesh-Zertifikate ausstellt (ISSUING_CA_POOL_URI). Dies kann entweder die untergeordnete CA (empfohlen) oder die Stamm-CA sein. Das Format dafür ist:
      //privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_POOL_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
  9. Speichern Sie die folgende TrustConfig-YAML-Konfiguration, damit Ihr Cluster weiß, wie den bereitgestellten Zertifikaten vertraut werden soll:

    apiVersion: security.cloud.google.com/v1
    kind: TrustConfig
    metadata:
      name: default
    spec:
      # You must include a trustStores entry for the trust domain that
      # your cluster is enrolled in.
      trustStores:
      - trustDomain: PROJECT_ID.svc.id.goog
        # Trust identities in this trustDomain if they appear in a certificate
        # that chains up to this root CA.
        trustAnchors:
        - certificateAuthorityServiceURI: ROOT_CA_POOL_URI
    

    Dabei gilt:

    • Die Projekt-ID des Projekts, in dem der Cluster ausgeführt wird.
      PROJECT_ID
    • Der vollständig qualifizierte URI des Stamm-CA-Pools (ROOT_CA_POOL_URI). Das Format lautet:
      //privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
  10. Wenden Sie die Konfigurationen auf Ihren Cluster an:

    kubectl apply -f WorkloadCertificateConfig.yaml
    kubectl apply -f TrustConfig.yaml
    

Proxylosen gRPC-Dienst mit NEGs erstellen

Für PSM-Sicherheit benötigen Sie einen proxylosen gRPC-Server, der xDS verwenden kann. Sicherheitskonfiguration vom Cloud Service Mesh abrufen Dieser Schritt ähnelt der Konfiguration von GKE-Diensten mit NEGs, wie in der Anleitung zur Einrichtung des PSM-Load-Balancing erläutert. Sie verwenden hier aber den xDS-fähigen helloworld-Server im xDS-Beispiel im grpc-java-Repository anstelle des java-example-hostname-Image.

Sie erstellen diesen Server und führen ihn in einem Container aus, der aus einem openjdk:8-jdk-Image erstellt wurde. Sie können auch die benannte NEG-Funktion verwenden, mit der Sie einen Namen für die NEG angeben können. Dies vereinfacht spätere Schritte, da Ihr Deployment den Namen der NEG nicht mehr ermitteln muss.

Im Folgenden finden Sie ein vollständiges Beispiel für die Kubernetes-Spezifikation für gRPC-Server. Beachten Sie dabei Folgendes:

  • Die Spezifikation erstellt ein Kubernetes-Dienstkonto example-grpc-server, das vom gRPC-Server-Pod verwendet wird.
  • Die Spezifikation verwendet das Feld name in der Annotation cloud.google.com/neg des Dienstes, um den NEG-Namen example-grpc-server festzulegen.
  • Die Variable ${PROJNUM} steht für die Projektnummer Ihres Projekts.
  • Die Spezifikation verwendet den Abschnitt initContainers, um einen Bootstrap-Generator auszuführen, der den Inhalt der Bootstrap-Datei erstellt, die die proxylose gRPC-Bibliothek benötigt. Diese Bootstrap-Datei befindet sich unter /tmp/grpc-xds/td-grpc-bootstrap.json im gRPC-Servercontainer example-grpc-server.

Fügen Sie der Pod-Spezifikation die folgende Annotation hinzu:

 annotations:
   security.cloud.google.com/use-workload-certificates: ""

In der folgenden kompletten Spezifikationen ist die korrekte Position darin dargestellt.

Bei der Erstellung erhält jeder Pod ein Volume unter /var/run/secrets/workload-spiffe-credentials. Dieses Volume enthält Folgendes:

  • private_key.pem ist ein automatisch generierter privater Schlüssel.
  • certificates.pem ist ein Paket von PEM-formatierten Zertifikaten, die für einen anderen Pod als Clientzertifikatskette bereitgestellt oder als Serverzertifikatskette verwendet werden können.
  • ca_certificates.pem ist ein Paket aus PEM-formatierten Zertifikaten. Diese können als Trust-Anchors verwendet werden, wenn Sie die von einem anderen Pod bereitgestellte Clientzertifikatskette oder die Serverzertifikatskette prüfen, die beim Herstellen der Verbindung zu einem anderen Pod empfangen wurde.

Beachten Sie, dass ca_certificates.pem Zertifikate für die lokale vertrauenswürdige Domain der Arbeitslasten enthält, also für den Arbeitslastpool des Clusters.

Das Blattzertifikat in certificates.pem enthält die folgende SPIFFE-Identitätsbestätigung in Nur-Text:

spiffe://WORKLOAD_POOL/ns/NAMESPACE/sa/KUBERNETES_SERVICE_ACCOUNT

Für diese Bestätigung gilt Folgendes:

  • WORKLOAD_POOL ist der Name des Clusterarbeitslastpools.
  • NAMESPACE ist der Namespace Ihres Kubernetes-Dienstkontos.
  • KUBERNETES_SERVICE_ACCOUNT ist der Name Ihres Kubernetes-Dienstkontos.

Mit der folgenden Anleitung für Ihre Sprache erstellen Sie die Spezifikation für dieses Beispiel.

Java

  1. Führen Sie diesen Befehl aus, um zu prüfen, ob die Projektnummer richtig festgelegt ist:

    if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
    
  2. Erstellen Sie die Spezifikation:

    cat << EOF > example-grpc-server.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
     name: example-grpc-server
     namespace: default
     annotations:
       iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com
    ---
    apiVersion: v1
    kind: Service
    metadata:
     name: example-grpc-server
     namespace: default
     labels:
       k8s-app: example-grpc-server
     annotations:
       cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}'
    spec:
     ports:
     - name: helloworld
       port: 8080
       protocol: TCP
       targetPort: 50051
     selector:
       k8s-app: example-grpc-server
     type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
     name: example-grpc-server
     namespace: default
     labels:
       k8s-app: example-grpc-server
    spec:
     replicas: 1
     selector:
       matchLabels:
         k8s-app: example-grpc-server
     strategy: {}
     template:
       metadata:
         annotations:
            security.cloud.google.com/use-workload-certificates: ""
         labels:
           k8s-app: example-grpc-server
       spec:
         containers:
         - image: openjdk:8-jdk
           imagePullPolicy: IfNotPresent
           name: example-grpc-server
           command:
           - /bin/sleep
           - inf
           env:
           - name: GRPC_XDS_BOOTSTRAP
             value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
           ports:
           - protocol: TCP
             containerPort: 50051
           resources:
             limits:
               cpu: 800m
               memory: 512Mi
             requests:
               cpu: 100m
               memory: 512Mi
           volumeMounts:
           - name: grpc-td-conf
             mountPath: /tmp/grpc-xds/
         initContainers:
         - name: grpc-td-init
           image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
           imagePullPolicy: Always
           args:
           - --output
           - "/tmp/bootstrap/td-grpc-bootstrap.json"
           - --node-metadata=app=helloworld
           resources:
             limits:
               cpu: 100m
               memory: 100Mi
             requests:
               cpu: 10m
               memory: 100Mi
           volumeMounts:
           - name: grpc-td-conf
             mountPath: /tmp/bootstrap/
         serviceAccountName: example-grpc-server
         volumes:
         - name: grpc-td-conf
           emptyDir:
             medium: Memory
    EOF
    

C++

  1. Führen Sie diesen Befehl aus, um zu prüfen, ob die Projektnummer richtig festgelegt ist:

    if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
    
  2. Erstellen Sie die Spezifikation:

    cat << EOF > example-grpc-server.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
     name: example-grpc-server
     namespace: default
     annotations:
       iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com
    ---
    apiVersion: v1
    kind: Service
    metadata:
     name: example-grpc-server
     namespace: default
     labels:
       k8s-app: example-grpc-server
     annotations:
       cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}'
    spec:
     ports:
     - name: helloworld
       port: 8080
       protocol: TCP
       targetPort: 50051
     selector:
       k8s-app: example-grpc-server
     type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
     name: example-grpc-server
     namespace: default
     labels:
       k8s-app: example-grpc-server
    spec:
     replicas: 1
     selector:
       matchLabels:
         k8s-app: example-grpc-server
     strategy: {}
     template:
       metadata:
         annotations:
            security.cloud.google.com/use-workload-certificates: ""
         labels:
           k8s-app: example-grpc-server
       spec:
         containers:
         - image: phusion/baseimage:18.04-1.0.0
           imagePullPolicy: IfNotPresent
           name: example-grpc-server
           command:
           - /bin/sleep
           - inf
           env:
           - name: GRPC_XDS_BOOTSTRAP
             value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
           ports:
           - protocol: TCP
             containerPort: 50051
           resources:
             limits:
               cpu: 8
               memory: 8Gi
             requests:
               cpu: 300m
               memory: 512Mi
           volumeMounts:
           - name: grpc-td-conf
             mountPath: /tmp/grpc-xds/
         initContainers:
         - name: grpc-td-init
           image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
           imagePullPolicy: Always
           args:
           - --output
           - "/tmp/bootstrap/td-grpc-bootstrap.json"
           - --node-metadata=app=helloworld
           resources:
             limits:
               cpu: 100m
               memory: 100Mi
             requests:
               cpu: 10m
               memory: 100Mi
           volumeMounts:
           - name: grpc-td-conf
             mountPath: /tmp/bootstrap/
         serviceAccountName: example-grpc-server
         volumes:
         - name: grpc-td-conf
           emptyDir:
             medium: Memory
    EOF
    

Python

  1. Führen Sie diesen Befehl aus, um zu prüfen, ob die Projektnummer richtig festgelegt ist:

    if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
    
  2. Erstellen Sie die Spezifikation:

    cat << EOF > example-grpc-server.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
     name: example-grpc-server
     namespace: default
     annotations:
       iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com
    ---
    apiVersion: v1
    kind: Service
    metadata:
     name: example-grpc-server
     namespace: default
     labels:
       k8s-app: example-grpc-server
     annotations:
       cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}'
    spec:
     ports:
     - name: helloworld
       port: 8080
       protocol: TCP
       targetPort: 50051
     selector:
       k8s-app: example-grpc-server
     type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
     name: example-grpc-server
     namespace: default
     labels:
       k8s-app: example-grpc-server
    spec:
     replicas: 1
     selector:
       matchLabels:
         k8s-app: example-grpc-server
     strategy: {}
     template:
       metadata:
         annotations:
            security.cloud.google.com/use-workload-certificates: ""
         labels:
           k8s-app: example-grpc-server
       spec:
         containers:
         - image: phusion/baseimage:18.04-1.0.0
           imagePullPolicy: IfNotPresent
           name: example-grpc-server
           command:
           - /bin/sleep
           - inf
           env:
           - name: GRPC_XDS_BOOTSTRAP
             value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
           ports:
           - protocol: TCP
             containerPort: 50051
           resources:
             limits:
               cpu: 8
               memory: 8Gi
             requests:
               cpu: 300m
               memory: 512Mi
           volumeMounts:
           - name: grpc-td-conf
             mountPath: /tmp/grpc-xds/
         initContainers:
         - name: grpc-td-init
           image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
           imagePullPolicy: Always
           args:
           - --output
           - "/tmp/bootstrap/td-grpc-bootstrap.json"
           - --node-metadata=app=helloworld
           resources:
             limits:
               cpu: 100m
               memory: 100Mi
             requests:
               cpu: 10m
               memory: 100Mi
           volumeMounts:
           - name: grpc-td-conf
             mountPath: /tmp/bootstrap/
         serviceAccountName: example-grpc-server
         volumes:
         - name: grpc-td-conf
           emptyDir:
             medium: Memory
    EOF
    

Go

  1. Führen Sie diesen Befehl aus, um zu prüfen, ob die Projektnummer richtig festgelegt ist:

    if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
    
  2. Erstellen Sie die Spezifikation:

    cat << EOF > example-grpc-server.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
     name: example-grpc-server
     namespace: default
     annotations:
       iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com
    ---
    apiVersion: v1
    kind: Service
    metadata:
     name: example-grpc-server
     namespace: default
     labels:
       k8s-app: example-grpc-server
     annotations:
       cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}'
    spec:
     ports:
     - name: helloworld
       port: 8080
       protocol: TCP
       targetPort: 50051
     selector:
       k8s-app: example-grpc-server
     type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
     name: example-grpc-server
     namespace: default
     labels:
       k8s-app: example-grpc-server
    spec:
     replicas: 1
     selector:
       matchLabels:
         k8s-app: example-grpc-server
     strategy: {}
     template:
       metadata:
         annotations:
            security.cloud.google.com/use-workload-certificates: ""
         labels:
           k8s-app: example-grpc-server
       spec:
         containers:
         - image: golang:1.16-alpine
           imagePullPolicy: IfNotPresent
           name: example-grpc-server
           command:
           - /bin/sleep
           - inf
           env:
           - name: GRPC_XDS_BOOTSTRAP
             value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
           ports:
           - protocol: TCP
             containerPort: 50051
           resources:
             limits:
               cpu: 8
               memory: 8Gi
             requests:
               cpu: 300m
               memory: 512Mi
           volumeMounts:
           - name: grpc-td-conf
             mountPath: /tmp/grpc-xds/
         initContainers:
         - name: grpc-td-init
           image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
           imagePullPolicy: Always
           args:
           - --output
           - "/tmp/bootstrap/td-grpc-bootstrap.json"
           - --node-metadata=app=helloworld
           resources:
             limits:
               cpu: 100m
               memory: 100Mi
             requests:
               cpu: 10m
               memory: 100Mi
           volumeMounts:
           - name: grpc-td-conf
             mountPath: /tmp/bootstrap/
         serviceAccountName: example-grpc-server
         volumes:
         - name: grpc-td-conf
           emptyDir:
             medium: Memory
    EOF
    

    Schließen Sie den Vorgang wie im Folgenden dargestellt ab:

  1. Wenden Sie die Spezifikation an:

    kubectl apply -f example-grpc-server.yaml
    
  2. Weisen Sie dem Dienstkonto die erforderlichen Rollen zu:

    gcloud iam service-accounts add-iam-policy-binding \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:${PROJECT_ID}.svc.id.goog[default/example-grpc-server]" \
      ${PROJNUM}-compute@developer.gserviceaccount.com
    
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member "serviceAccount:${PROJECT_ID}.svc.id.goog[default/example-grpc-server]" \
      --role roles/trafficdirector.client
    
  3. Führen Sie die folgenden Befehle aus, um zu prüfen, ob der Dienst und der Pod ordnungsgemäß erstellt wurden:

    kubectl get deploy/example-grpc-server
    kubectl get svc/example-grpc-server
    
  4. Prüfen Sie, ob der NEG-Name korrekt ist:

    gcloud compute network-endpoint-groups list \
        --filter "name=example-grpc-server" --format "value(name)"
    

    Es wird erwartet, dass der vorherige Befehl den NEG-Namen example-grpc-server zurückgibt.

Cloud Service Mesh mit Google Cloud Load Balancing-Komponenten konfigurieren

Die Schritte in diesem Abschnitt ähneln denen in Cloud Service Mesh mit Load-Balancing-Komponenten konfigurieren Es gibt jedoch einige Änderungen, die in den folgenden Abschnitten beschrieben werden.

Systemdiagnose, Firewallregel und Backend-Dienst erstellen

Wenn der gRPC-Server für die Verwendung von mTLS konfiguriert ist, funktionieren gRPC-Systemdiagnosen nicht. Der Client für die Systemdiagnose kann kein gültiges Clientzertifikat bereitstellen. zu den Servern. Dafür stehen Ihnen zwei Möglichkeiten zur Verfügung:

Beim ersten Ansatz erstellt der Server einen zusätzlichen Bereitstellungsport, der als Systemdiagnoseport festgelegt wird. Dieser wird an einen speziellen Systemdiagnosedienst als Nur-Text oder in Form von TLS für diesen Port angehängt.

Der xDS-Beispielserver helloworld verwendet PORT_NUMBER + 1 als Systemdiagnoseport in Klartextform. In diesem Beispiel wird 50052 als Systemdiagnoseport verwendet, da 50051 der Port des gRPC-Anwendungsservers ist.

Beim zweiten Ansatz konfigurieren Sie die Systemdiagnose so, dass nur die TCP-Verbindung zum Bereitstellungsport der Anwendung geprüft wird. Dadurch wird nur die Konnektivität geprüft. Außerdem wird bei nicht erfolgreichen TLS-Handshakes unnötiger Traffic zum Server generiert. Daher empfehlen wir, den ersten Ansatz zu verwenden.

  1. Erstellen Sie die Systemdiagnose. Beachten Sie, dass die Systemdiagnose erst gestartet wird, wenn Sie den Server erstellt und gestartet haben.

    • Wenn Sie für die Systemdiagnose einen eigenen Bereitstellungsport erstellen möchten (wird von uns empfohlen), verwenden Sie folgenden Befehl:

      gcloud compute health-checks create grpc grpc-gke-helloworld-hc \
       --enable-logging --port 50052
      
    • Wenn Sie eine TCP-Systemdiagnose erstellen möchten (wird von uns nicht empfohlen), verwenden Sie den folgenden Befehl:

      gcloud compute health-checks create tcp grpc-gke-helloworld-hc \
      --use-serving-port
      
  2. Erstellen Sie die Firewall. Achten Sie darauf, dass der Wert von --target-tags mit dem Wert übereinstimmt, den Sie für --tags im Abschnitt GKE-Cluster erstellen oder aktualisieren festgelegt haben.

    gcloud compute firewall-rules create grpc-gke-allow-health-checks \
      --network default --action allow --direction INGRESS \
      --source-ranges 35.191.0.0/16,130.211.0.0/22 \
      --target-tags allow-health-checks \
      --rules tcp:50051-50052
    
  3. Erstellen Sie den Backend-Dienst:

    gcloud compute backend-services create grpc-gke-helloworld-service \
       --global \
       --load-balancing-scheme=INTERNAL_SELF_MANAGED \
       --protocol=GRPC \
       --health-checks grpc-gke-helloworld-hc
    
  4. Hängen Sie die NEG an den Backend-Dienst an:

    gcloud compute backend-services add-backend grpc-gke-helloworld-service \
       --global \
       --network-endpoint-group example-grpc-server \
       --network-endpoint-group-zone ${ZONE} \
       --balancing-mode RATE \
       --max-rate-per-endpoint 5
    

Routingregelzuordnung erstellen

Das funktioniert ähnlich wie das Erstellen einer Routingregelzuordnung in Cloud Service Mesh-Einrichtung mit Google Kubernetes Engine und proxylosen gRPC-Diensten.

  1. Erstellen Sie die URL-Zuordnung:

    gcloud compute url-maps create grpc-gke-url-map \
       --default-service grpc-gke-helloworld-service
    
  2. Fügen Sie der URL-Zuordnung den Pfad-Matcher hinzu:

    gcloud compute url-maps add-path-matcher grpc-gke-url-map \
       --default-service grpc-gke-helloworld-service \
       --path-matcher-name grpc-gke-path-matcher \
       --new-hosts helloworld-gke:8000
    
  3. Erstellen Sie den gRPC-Zielproxy:

    gcloud compute target-grpc-proxies create grpc-gke-proxy \
       --url-map grpc-gke-url-map --validate-for-proxyless
    
  4. Erstellen Sie die Weiterleitungsregel:

    gcloud compute forwarding-rules create grpc-gke-forwarding-rule \
      --global \
      --load-balancing-scheme=INTERNAL_SELF_MANAGED \
      --address=0.0.0.0 \
      --target-grpc-proxy=grpc-gke-proxy \
      --ports 8000 \
      --network default
    

Cloud Service Mesh mit proxylosem gRPC-Sicherheitssystem konfigurieren

Dieses Beispiel zeigt, wie Sie mTLS auf Client- und Serverseite konfigurieren.

Format für Richtlinienverweise

Beachten Sie das folgende erforderliche Format, um auf Server-TLS- und Client-TLS-Richtlinien zu verweisen:

projects/PROJECT_ID/locations/global/[serverTlsPolicies|clientTlsPolicies]/[server-tls-policy|client-mtls-policy]

Beispiel:

projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy

mTLS serverseitig konfigurieren

Als Erstes erstellen Sie eine Server-TLS-Richtlinie. Die Richtlinie legt für den gRPC-Server fest, dass die Konfiguration für das Plug-in certificateProvicerInstance verwendet wird, die über den Namen google_cloud_private_spiffe für das Identitätszertifikat identifiziert wird, das Teil des serverCertificate ist. Der Abschnitt mtlsPolicy gibt die mTLS-Sicherheit an und verwendet die gleiche google_cloud_private_spiffe wie die Plug-in-Konfiguration für die clientValidationCa. Dies ist die Spezifikation für das Stammzertifikat (Validierung).

Als Nächstes erstellen Sie eine Endpunktrichtlinie. Damit wird festgelegt, dass ein Backend, z. B. ein gRPC-Server, mithilfe von Port 50051 mit einem beliebigen oder keinen Metadatenlabels die angehängte Server-TLS-Richtlinie mit dem Namen server-mtls-policy empfängt. Metadatenlabels geben Sie mit MATCH_ALL an. Sie erstellen die Endpunktrichtlinie mit der temporären Datei ep-mtls-psms.yaml, die die Werte für die Endpunktrichtlinienressource enthält, mithilfe der bereits definierten Richtlinie.

  1. Erstellen Sie im aktuellen Verzeichnis die temporäre Datei server-mtls-policy.yaml mit den Werten der TLS-Richtlinienressource des Servers:

    name: "projects/${PROJECT_ID}/locations/global/serverTlsPolicies/server-mtls-policy"
    serverCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    mtlsPolicy:
      clientValidationCa:
      - certificateProviderInstance:
          pluginInstance: google_cloud_private_spiffe
    
  2. Erstellen Sie eine Server-TLS-Richtlinienressource namens server-mtls-policy durch Importieren der temporären Datei server-mtls-policy.yaml:

    gcloud network-security server-tls-policies import server-mtls-policy \
      --source=server-mtls-policy.yaml --location=global
    
  3. Erstellen Sie die Endpunktrichtlinie durch Anlegen der temporären Datei ep-mtls-psms.yaml:

    name: "ep-mtls-psms"
    type: "GRPC_SERVER"
    serverTlsPolicy: "projects/${PROJECT_ID}/locations/global/serverTlsPolicies/server-mtls-policy"
    trafficPortSelector:
      ports:
      - "50051"
    endpointMatcher:
      metadataLabelMatcher:
        metadataLabelMatchCriteria: "MATCH_ALL"
        metadataLabels:
        - labelName: app
          labelValue: helloworld
    
  4. Erstellen Sie die Endpunktrichtlinienressource. Importieren Sie dazu die Datei ep-mtls-psms.yaml:

    gcloud beta network-services endpoint-policies import ep-mtls-psms \
      --source=ep-mtls-psms.yaml --location=global
    

mTLS clientseitig konfigurieren

Die clientseitige Sicherheitsrichtlinie wird an den Backend-Dienst angehängt. Wenn ein Client über den Back-End-Dienst auf ein Back-End (den gRPC-Server) zugreift, wird die angehängte clientseitige Sicherheitsrichtlinie an den Client gesendet.

  1. Erstellen Sie die Ressourceninhalte der TLS-Clientrichtlinie in einer temporären Datei namens client-mtls-policy.yaml im aktuellen Verzeichnis:

    name: "client-mtls-policy"
    clientCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    serverValidationCa:
    - certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    
  2. Erstellen Sie die clientseitige TLS-Richtlinienressource mit dem Namen client-mtls-policy durch Importieren der temporären Datei client-mtls-policy.yaml:

    gcloud network-security client-tls-policies import client-mtls-policy \
      --source=client-mtls-policy.yaml --location=global
    
  3. Erstellen Sie ein Snippet in einer temporären Datei, um auf diese Richtlinie zu verweisen, und fügen Sie Details für subjectAltNames in der SecuritySettings-Nachricht wie im folgenden Beispiel gezeigt hinzu. Ersetzen Sie ${PROJECT_ID} durch Ihre Projekt-ID, Wert der zuvor beschriebenen Umgebungsvariablen ${PROJECT_ID}. Beachten Sie, dass example-grpc-server in subjectAltNames der Name des Kubernetes-Dienstkontos ist, der in der Deployment-Spezifikation für den gRPC-Server-Pod verwendet wird.

    if [ -z "$PROJECT_ID" ] ; then echo Please make sure PROJECT_ID is set. ; fi
    cat << EOF > client-security-settings.yaml
    securitySettings:
      clientTlsPolicy: projects/${PROJECT_ID}/locations/global/clientTlsPolicies/client-mtls-policy
      subjectAltNames:
        - "spiffe://${PROJECT_ID}.svc.id.goog/ns/default/sa/example-grpc-server"
    EOF
    
  4. Fügen Sie dem Back-End-Dienst, den Sie erstellt haben, die Nachricht securitySettings hinzu. Mit diesen Schritten werden der aktuelle Inhalt des Backend-Dienstes exportiert, die Client-securitySetting-Nachricht hinzugefügt und der neue Inhalt zurückimportiert, um den Backend-Dienst zu aktualisieren.

    gcloud compute backend-services export grpc-gke-helloworld-service --global \
      --destination=/tmp/grpc-gke-helloworld-service.yaml
    
    cat /tmp/grpc-gke-helloworld-service.yaml client-security-settings.yaml \
      >/tmp/grpc-gke-helloworld-service1.yaml
    
    gcloud compute backend-services import grpc-gke-helloworld-service --global \
      --source=/tmp/grpc-gke-helloworld-service1.yaml -q
    

Konfiguration prüfen

Die Konfiguration des Cloud Service Mesh ist jetzt abgeschlossen, einschließlich der Server- und für die clientseitige Sicherheit. Als Nächstes bereiten Sie die Server- und Clientarbeitslasten vor und führen sie aus. Damit ist das Beispiel abgeschlossen.

Proxylosen gRPC-Client erstellen

Dieser Schritt ähnelt dem vorherigen Abschnitt Proxylosen gRPC-Dienst erstellen. Sie verwenden den xDS-fähigen helloworld-Client aus dem xDS-Beispielverzeichnis im grpc-java-Repository. Sie erstellen den Client und führen ihn in einem Container aus, der aus einem openjdk:8-jdk-Image erstellt wurde. Die Kubernetes-Spezifikation des gRPC-Clients folgen.

  • Es wird ein Kubernetes-Dienstkonto example-grpc-client erstellt, das vom gRPC-Client-Pod verwendet wird.
  • ${PROJNUM} steht für die Projektnummer Ihres Projekts und muss durch die tatsächliche Nummer ersetzt werden.

Fügen Sie der Pod-Spezifikation die folgende Annotation hinzu:

  annotations:
    security.cloud.google.com/use-workload-certificates: ""

Bei der Erstellung erhält jeder Pod ein Volume unter /var/run/secrets/workload-spiffe-credentials. Dieses Volume enthält Folgendes:

  • private_key.pem ist ein automatisch generierter privater Schlüssel.
  • certificates.pem ist ein Paket von PEM-formatierten Zertifikaten, die für einen anderen Pod als Clientzertifikatskette bereitgestellt oder als Serverzertifikatskette verwendet werden können.
  • ca_certificates.pem ist ein Paket aus PEM-formatierten Zertifikaten. Diese können als Trust-Anchors verwendet werden, wenn Sie die von einem anderen Pod bereitgestellte Clientzertifikatskette oder die Serverzertifikatskette prüfen, die beim Herstellen der Verbindung zu einem anderen Pod empfangen wurde.

Beachten Sie, dass ca_certificates.pem die Root-Zertifikate der lokalen Vertrauensdomain für die Arbeitslasten enthält, also für den Arbeitslastpool des Clusters.

Das Blattzertifikat in certificates.pem enthält die folgende SPIFFE-Identitätsbestätigung in Nur-Text:

spiffe://WORKLOAD_POOL/ns/NAMESPACE/sa/KUBERNETES_SERVICE_ACCOUNT

Für diese Bestätigung gilt Folgendes:

  • WORKLOAD_POOL ist der Name des Clusterarbeitslastpools.
  • NAMESPACE ist der Name Ihres Kubernetes-Dienstkontos.
  • KUBERNETES_SERVICE_ACCOUNT ist der Namespace Ihres Kubernetes-Dienstkontos.

Mit der folgenden Anleitung für Ihre Sprache erstellen Sie die Spezifikation für dieses Beispiel.

Java

  1. Führen Sie diesen Befehl aus, um zu prüfen, ob die Projektnummer richtig festgelegt ist:

    if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
    
  2. Erstellen Sie die folgende Spezifikation:

    cat << EOF > example-grpc-client.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: example-grpc-client
      namespace: default
      annotations:
        iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: example-grpc-client
      namespace: default
      labels:
        k8s-app: example-grpc-client
    spec:
      replicas: 1
      selector:
        matchLabels:
          k8s-app: example-grpc-client
      strategy: {}
      template:
        metadata:
          annotations:
            security.cloud.google.com/use-workload-certificates: ""
          labels:
            k8s-app: example-grpc-client
        spec:
          containers:
          - image: openjdk:8-jdk
            imagePullPolicy: IfNotPresent
            name: example-grpc-client
            command:
            - /bin/sleep
            - inf
            env:
            - name: GRPC_XDS_BOOTSTRAP
              value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
            resources:
              limits:
                cpu: 800m
                memory: 512Mi
              requests:
                cpu: 100m
                memory: 512Mi
            volumeMounts:
            - name: grpc-td-conf
              mountPath: /tmp/grpc-xds/
          initContainers:
          - name: grpc-td-init
            image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
            imagePullPolicy: Always
            args:
            - --output
            - "/tmp/bootstrap/td-grpc-bootstrap.json"
            resources:
              limits:
                cpu: 100m
                memory: 100Mi
              requests:
                cpu: 10m
                memory: 100Mi
            volumeMounts:
            - name: grpc-td-conf
              mountPath: /tmp/bootstrap/
          serviceAccountName: example-grpc-client
          volumes:
          - name: grpc-td-conf
            emptyDir:
              medium: Memory
    EOF
    

C++

  1. Führen Sie diesen Befehl aus, um zu prüfen, ob die Projektnummer richtig festgelegt ist:

    if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
    
  2. Erstellen Sie die folgende Spezifikation:

    cat << EOF > example-grpc-client.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: example-grpc-client
      namespace: default
      annotations:
        iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: example-grpc-client
      namespace: default
      labels:
        k8s-app: example-grpc-client
    spec:
      replicas: 1
      selector:
        matchLabels:
          k8s-app: example-grpc-client
      strategy: {}
      template:
        metadata:
          annotations:
            security.cloud.google.com/use-workload-certificates: ""
          labels:
            k8s-app: example-grpc-client
        spec:
          containers:
          - image: phusion/baseimage:18.04-1.0.0
            imagePullPolicy: IfNotPresent
            name: example-grpc-client
            command:
            - /bin/sleep
            - inf
            env:
            - name: GRPC_XDS_BOOTSTRAP
              value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
            resources:
              limits:
                cpu: 8
                memory: 8Gi
              requests:
                cpu: 300m
                memory: 512Mi
            volumeMounts:
            - name: grpc-td-conf
              mountPath: /tmp/grpc-xds/
          initContainers:
          - name: grpc-td-init
            image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
            imagePullPolicy: Always
            args:
            - --output
            - "/tmp/bootstrap/td-grpc-bootstrap.json"
            resources:
              limits:
                cpu: 100m
                memory: 100Mi
              requests:
                cpu: 10m
                memory: 100Mi
            volumeMounts:
            - name: grpc-td-conf
              mountPath: /tmp/bootstrap/
          serviceAccountName: example-grpc-client
          volumes:
          - name: grpc-td-conf
            emptyDir:
              medium: Memory
    EOF
    

Python

  1. Führen Sie den folgenden Befehl aus, um sicherzustellen, dass die Projektnummer richtig festgelegt ist:

    if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
    
  2. Erstellen Sie die folgende Spezifikation:

    cat << EOF > example-grpc-client.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: example-grpc-client
      namespace: default
      annotations:
        iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: example-grpc-client
      namespace: default
      labels:
        k8s-app: example-grpc-client
    spec:
      replicas: 1
      selector:
        matchLabels:
          k8s-app: example-grpc-client
      strategy: {}
      template:
        metadata:
          annotations:
            security.cloud.google.com/use-workload-certificates: ""
          labels:
            k8s-app: example-grpc-client
        spec:
          containers:
          - image: phusion/baseimage:18.04-1.0.0
            imagePullPolicy: IfNotPresent
            name: example-grpc-client
            command:
            - /bin/sleep
            - inf
            env:
            - name: GRPC_XDS_BOOTSTRAP
              value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
            resources:
              limits:
                cpu: 8
                memory: 8Gi
              requests:
                cpu: 300m
                memory: 512Mi
            volumeMounts:
            - name: grpc-td-conf
              mountPath: /tmp/grpc-xds/
          initContainers:
          - name: grpc-td-init
            image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
            imagePullPolicy: Always
            args:
            - --output
            - "/tmp/bootstrap/td-grpc-bootstrap.json"
            resources:
              limits:
                cpu: 100m
                memory: 100Mi
              requests:
                cpu: 10m
                memory: 100Mi
            volumeMounts:
            - name: grpc-td-conf
              mountPath: /tmp/bootstrap/
          serviceAccountName: example-grpc-client
          volumes:
          - name: grpc-td-conf
            emptyDir:
              medium: Memory
    EOF
    

Go

  1. Führen Sie den folgenden Befehl aus, um sicherzustellen, dass die Projektnummer richtig festgelegt ist:

    if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
    
  2. Erstellen Sie die folgende Spezifikation:

    cat << EOF > example-grpc-client.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: example-grpc-client
      namespace: default
      annotations:
        iam.gke.io/gcp-service-account: ${PROJNUM}-compute@developer.gserviceaccount.com
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: example-grpc-client
      namespace: default
      labels:
        k8s-app: example-grpc-client
    spec:
      replicas: 1
      selector:
        matchLabels:
          k8s-app: example-grpc-client
      strategy: {}
      template:
        metadata:
          annotations:
            security.cloud.google.com/use-workload-certificates: ""
          labels:
            k8s-app: example-grpc-client
        spec:
          containers:
          - image: golang:1.16-alpine
            imagePullPolicy: IfNotPresent
            name: example-grpc-client
            command:
            - /bin/sleep
            - inf
            env:
            - name: GRPC_XDS_BOOTSTRAP
              value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
            resources:
              limits:
                cpu: 8
                memory: 8Gi
              requests:
                cpu: 300m
                memory: 512Mi
            volumeMounts:
            - name: grpc-td-conf
              mountPath: /tmp/grpc-xds/
          initContainers:
          - name: grpc-td-init
            image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
            imagePullPolicy: Always
            args:
            - --output
            - "/tmp/bootstrap/td-grpc-bootstrap.json"
            resources:
              limits:
                cpu: 100m
                memory: 100Mi
              requests:
                cpu: 10m
                memory: 100Mi
            volumeMounts:
            - name: grpc-td-conf
              mountPath: /tmp/bootstrap/
          serviceAccountName: example-grpc-client
          volumes:
          - name: grpc-td-conf
            emptyDir:
              medium: Memory
    EOF
    

Schließen Sie den Vorgang wie im Folgenden dargestellt ab:

  1. Wenden Sie die Spezifikation an:

    kubectl apply -f example-grpc-client.yaml
    
  2. Weisen Sie dem Dienstkonto die erforderlichen Rollen zu:

    gcloud iam service-accounts add-iam-policy-binding \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:${PROJECT_ID}.svc.id.goog[default/example-grpc-client]" \
      ${PROJNUM}-compute@developer.gserviceaccount.com
    
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member "serviceAccount:${PROJECT_ID}.svc.id.goog[default/example-grpc-client]" \
      --role roles/trafficdirector.client
    
  3. Prüfen Sie, ob der Client-Pod ausgeführt wird:

    kubectl get pods
    

    Der Ausgabetext des Befehls sieht in etwa so aus:

    NAMESPACE   NAME                                    READY   STATUS    RESTARTS   AGE
    default     example-grpc-client-7c969bb997-9fzjv    1/1     Running   0          104s
    [..skip..]
    

Server ausführen

Erstellen den xDS-fähigen helloworld-Server und führen Sie ihn im zuvor erstellten Server-Pod aus.

Java

  1. Rufen Sie den Namen des Pods ab, der für den Dienst example-grpc-server erstellt wurde:

    kubectl get pods | grep example-grpc-server
    

    Es wird daraufhin in etwa Folgendes angezeigt:

    default    example-grpc-server-77548868d-l9hmf     1/1    Running   0     105s
    
  2. Stellen Sie eine Shell-Verbindung zum Server-Pod her:

    kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/bash
    
  3. Prüfen Sie in der Shell, ob die Bootstrap-Datei unter /tmp/grpc-xds/td-grpc-bootstrap.json mit dem Schema wie im Abschnitt Bootstrap-Datei erläutert, übereinstimmt.

  4. Laden Sie die gRPC-Java-Version 1.42.1 herunter und erstellen Sie die Serveranwendung xds-hello-world.

    curl -L https://github.com/grpc/grpc-java/archive/v1.42.1.tar.gz | tar -xz
    
    cd grpc-java-1.42.1/examples/example-xds
    
    ../gradlew --no-daemon installDist
    
  5. Führen Sie den Server mit dem Flag --xds-creds aus, um die xDS-fähige Sicherheit festzulegen. Verwenden Sie dabei 50051 als Überwachungsport und xds-server als Serverkennung:

    ./build/install/example-xds/bin/xds-hello-world-server --xds-creds 50051 xds-server
    
  6. Nachdem der Server die erforderliche Konfiguration Cloud Service Mesh erhalten Sie die folgende Ausgabe:

    Listening on port 50051
    plain text health service listening on port 50052
    

C++

  1. Rufen Sie den Namen des Pods ab, der für den Dienst example-grpc-server erstellt wurde:

    kubectl get pods | grep example-grpc-server
    

    Es wird daraufhin in etwa Folgendes angezeigt:

    default    example-grpc-server-77548868d-l9hmf     1/1    Running   0     105s
    
  2. Stellen Sie eine Shell-Verbindung zum Server-Pod her:

    kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/bash
    
  3. Prüfen Sie in der Shell, ob die Bootstrap-Datei unter /tmp/grpc-xds/td-grpc-bootstrap.json mit dem Schema übereinstimmt, das im Abschnitt Bootstrap-Datei erläutert wird.

  4. Laden Sie gRPC C++ herunter und erstellen Sie die Serveranwendung xds-hello-world.

    apt-get update -y && \
            apt-get install -y \
                build-essential \
                clang \
                python3 \
                python3-dev
    
    curl -L https://github.com/grpc/grpc/archive/master.tar.gz | tar -xz
    
    cd grpc-master
    
    tools/bazel build examples/cpp/helloworld:xds_greeter_server
    
  5. Führen Sie den Server mit 50051 als Überwachungsport und xds_greeter_server als Serverkennung aus:

    bazel-bin/examples/cpp/helloworld/xds_greeter_server --port=50051 --maintenance_port=50052 --secure
    

    Um den Server ohne Anmeldedaten auszuführen, geben Sie Folgendes an:

    bazel-bin/examples/cpp/helloworld/xds_greeter_server --nosecure
    
  6. Nachdem der Server die erforderliche Konfiguration von Cloud Service Mesh abgerufen hat, wird Folgendes ausgegeben:

    Listening on port 50051
    plain text health service listening on port 50052
    

Python

  1. Rufen Sie den Namen des Pods ab, der für den Dienst example-grpc-server erstellt wurde:

    kubectl get pods | grep example-grpc-server
    

    Es wird daraufhin in etwa Folgendes angezeigt:

    default    example-grpc-server-77548868d-l9hmf     1/1    Running   0     105s
    
  2. Stellen Sie eine Shell-Verbindung zum Server-Pod her:

    kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/bash
    
  3. Prüfen Sie in der Shell, ob die Bootstrap-Datei unter /tmp/grpc-xds/td-grpc-bootstrap.json mit dem Schema übereinstimmt, das im Abschnitt Bootstrap-Datei erläutert wird.

  4. Laden Sie gRPC Python Version 1.41.0 herunter und erstellen Sie die Beispielanwendung.

    apt-get update -y
    
    apt-get install -y python3 python3-pip
    
    curl -L https://github.com/grpc/grpc/archive/v1.41.x.tar.gz | tar -xz
    
    cd grpc-1.41.x/examples/python/xds/
    
    python3 -m virtualenv venv
    
    source venv/bin/activate
    
    python3 -m pip install -r requirements.txt
    

  5. Führen Sie den Server mit dem Flag --xds-creds aus, um die xDS-fähige Sicherheit festzulegen. Verwenden Sie dazu 50051 als Überwachungsport.

    python3 server.py 50051 --xds-creds
    
  6. Nachdem der Server die erforderliche Konfiguration von Cloud Service Mesh abgerufen hat, wird Folgendes ausgegeben:

    2021-05-06 16:10:34,042: INFO     Running with xDS Server credentials
    2021-05-06 16:10:34,043: INFO     Greeter server listening on port 50051
    2021-05-06 16:10:34,046: INFO     Maintenance server listening on port 50052
    

Go

  1. Rufen Sie den Namen des Pods ab, der für den Dienst example-grpc-server erstellt wurde:

    kubectl get pods | grep example-grpc-server
    

    Es wird daraufhin in etwa Folgendes angezeigt:

    default    example-grpc-server-77548868d-l9hmf     1/1    Running   0     105s
    
  2. Stellen Sie eine Shell-Verbindung zum Server-Pod her:

    kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/sh
    
  3. Prüfen Sie in der Shell, ob die Bootstrap-Datei unter /tmp/grpc-xds/td-grpc-bootstrap.json mit dem Schema übereinstimmt, das im Abschnitt Bootstrap-Datei erläutert wird.

  4. Laden Sie die gRPC-Go-Version 1.41.0 herunter und wechseln Sie zum Verzeichnis mit der Serveranwendung xds-hello-world.

    apk add curl
    
    curl -L https://github.com/grpc/grpc-go/archive/v1.42.0.tar.gz | tar -xz
    
    cd grpc-go-1.42.0/examples/features/xds/server
    
    
  5. Erstellen Sie den Server und führen Sie ihn mit dem Flag --xds_creds aus, um die xDS-fähige Sicherheit anzugeben. Verwenden Sie dabei 50051 als Überwachungsport:

    GRPC_GO_LOG_VERBOSITY_LEVEL=2 GRPC_GO_LOG_SEVERITY="info" \
      go run main.go \
      -xds_creds \
      -port 50051
    
  6. Nachdem der Server die erforderliche Konfiguration von Cloud Service Mesh abgerufen hat, wird Folgendes ausgegeben:

    Using xDS credentials...
    Serving GreeterService on 0.0.0.0:50051 and HealthService on 0.0.0.0:50052
    

Der Systemdiagnoseprozess benötigt drei bis fünf Minuten, um zu zeigen, dass Ihr Dienst nach dem Serverstart fehlerfrei ist.

Client ausführen und Konfiguration prüfen

Erstellen Sie den xDS-fähigen helloworld-Client und führen Sie ihn im zuvor erstellten Client-Pod aus.

Java

  1. Rufen Sie den Namen des Client-Pods ab:

    kubectl get pods | grep example-grpc-client
    

    Es wird daraufhin Folgendes angezeigt:

    default    example-grpc-client-7c969bb997-9fzjv     1/1    Running   0     105s
    
  2. Stellen Sie eine Shell-Verbindung zum Client-Pod her:

    kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
    
  3. Laden Sie in der Befehls-Shell die gRPC-Java-Version 1.42.1 herunter und erstellen Sie die Clientanwendung xds-hello-world.

    curl -L https://github.com/grpc/grpc-java/archive/v1.42.1.tar.gz | tar -xz
    
    cd grpc-java-1.42.1/examples/example-xds
    
    ../gradlew --no-daemon installDist
    
  4. Führen Sie den Client mit dem Flag --xds-creds aus, um die xDS-fähige Sicherheit, den Clientnamen und den Zielverbindungsstring anzugeben:

    ./build/install/example-xds/bin/xds-hello-world-client --xds-creds xds-client \
          xds:///helloworld-gke:8000
    

    Die Ausgabe sollte in etwa so aussehen:

    Greeting: Hello xds-client, from xds-server
    

C++

  1. Rufen Sie den Namen des Client-Pods ab:

    kubectl get pods | grep example-grpc-client
    

    Es wird daraufhin Folgendes angezeigt:

    default    example-grpc-client-7c969bb997-9fzjv     1/1    Running   0     105s
    
  2. Stellen Sie eine Shell-Verbindung zum Client-Pod her:

    kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
    
  3. Laden Sie in der Shell gRPC C++ herunter und erstellen Sie die Clientanwendung xds-hello-world.

    apt-get update -y && \
            apt-get install -y \
                build-essential \
                clang \
                python3 \
                python3-dev
    
    curl -L https://github.com/grpc/grpc/archive/master.tar.gz | tar -xz
    
    cd grpc-master
    
    tools/bazel build examples/cpp/helloworld:xds_greeter_client
    
  4. Führen Sie den Client mit dem Flag --xds-creds aus, um die xDS-fähige Sicherheit, den Clientnamen und den Zielverbindungsstring anzugeben:

    bazel-bin/examples/cpp/helloworld/xds_greeter_client --target=xds:///helloworld-gke:8000
    

    Um den Client ohne Anmeldedaten auszuführen, führen Sie folgenden Befehl aus:

    bazel-bin/examples/cpp/helloworld/xds_greeter_client --target=xds:///helloworld-gke:8000 --nosecure
    

    Die Ausgabe sollte in etwa so aussehen:

    Greeter received: Hello world
    

Python

  1. Rufen Sie den Namen des Client-Pods ab:

    kubectl get pods | grep example-grpc-client
    

    Es wird daraufhin Folgendes angezeigt:

    default    example-grpc-client-7c969bb997-9fzjv     1/1    Running   0     105s
    
  2. Stellen Sie eine Shell-Verbindung zum Client-Pod her:

    kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
    
  3. Laden Sie in der Shell die Python-Version 1.41.0 herunter und erstellen Sie die Beispielclientanwendung.

    apt-get update -y
    apt-get install -y python3 python3-pip
    python3 -m pip install virtualenv
    curl -L https://github.com/grpc/grpc/archive/v1.41.x.tar.gz | tar -xz
    cd grpc-1.41.x/examples/python/xds/
    python3 -m virtualenv venv
    source venv/bin/activate
    python3 -m pip install -r requirements.txt
    
  4. Führen Sie den Client mit dem Flag --xds-creds aus, um die xDS-fähige Sicherheit, den Clientnamen und den Zielverbindungsstring anzugeben:

    python3 client.py xds:///helloworld-gke:8000 --xds-creds
    

    Die Ausgabe sollte in etwa so aussehen:

    Greeter client received: Hello you from example-host!
    

Go

  1. Rufen Sie den Namen des Client-Pods ab:

    kubectl get pods | grep example-grpc-client
    

    Es wird daraufhin Folgendes angezeigt:

    default    example-grpc-client-7c969bb997-9fzjv     1/1    Running   0     105s
    
  2. Stellen Sie eine Shell-Verbindung zum Client-Pod her:

    kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/sh
    
  3. Sobald Sie sich in der Shell befinden, laden Sie die gRPC-Go-Version 1.42.0 herunter und wechseln Sie zum Verzeichnis mit der Clientanwendung xds-hello-world.

    apk add curl
    
    curl -L https://github.com/grpc/grpc-go/archive/v1.42.0.tar.gz | tar -xz
    
    cd grpc-go-1.42.0/examples/features/xds/client
    
  4. Erstellen Sie den Client und führen Sie ihn mit dem Flag --xds_creds aus, um anzugeben, xDS-fähige Sicherheit, Clientname und Zielverbindungsstring:

    GRPC_GO_LOG_VERBOSITY_LEVEL=2 GRPC_GO_LOG_SEVERITY="info" \
      go run main.go \
      -xds_creds \
      -name xds-client \
      -target xds:///helloworld-gke:8000
    

    Die Ausgabe sollte in etwa so aussehen:

    Greeting: Hello xds-client, from example-grpc-server-77548868d-l9hmf
    

Zugriff auf Dienstebene mit einer Autorisierungsrichtlinie konfigurieren

Für die Unterstützung von Autorisierungsrichtlinien ist die gRFC-A41-Unterstützung erforderlich. Die erforderlichen Sprachversionen finden Sie auf github.

Folgen Sie dieser Anleitung, um den Zugriff auf Dienstebene mit Autorisierungsrichtlinien zu konfigurieren. Informieren Sie sich vor dem Erstellen von Autorisierungsrichtlinien über die Warnung unter Zugriff mithilfe der Autorisierung einschränken.

Erstellen Sie einen zusätzlichen Hostnamen, mit dem der Client auf den Dienst helloworld-gke verweisen kann, um die Überprüfung der Konfiguration zu vereinfachen.

gcloud compute url-maps add-host-rule grpc-gke-url-map \
   --path-matcher-name grpc-gke-path-matcher \
   --hosts helloworld-gke-noaccess:8000

In der folgenden Anleitung wird eine Autorisierungsrichtlinie erstellt, die Anfragen zulässt, die vom Konto example-grpc-client gesendet werden, in dem der Hostname helloworld-gke:8000 und der Port 50051 ist.

gcloud

  1. Erstellen Sie eine Autorisierungsrichtlinie, indem Sie eine Datei mit dem Namen helloworld-gke-authz-policy.yaml erstellen.

    action: ALLOW
    name: helloworld-gke-authz-policy
    rules:
    - sources:
      - principals:
        - spiffe://PROJECT_ID.svc.id.goog/ns/default/sa/example-grpc-client
      destinations:
      - hosts:
        - helloworld-gke:8000
        ports:
        - 50051
    
  2. Importieren Sie die Richtlinie:

    gcloud network-security authorization-policies import \
      helloworld-gke-authz-policy \
      --source=helloworld-gke-authz-policy.yaml \
      --location=global
    
  3. Aktualisieren Sie die Endpunktrichtlinie so, dass sie auf die neue Autorisierungsrichtlinie verweist. Hängen Sie dazu Folgendes an die Datei ep-mtls-psms.yaml an:

    authorizationPolicy: projects/${PROJECT_ID}/locations/global/authorizationPolicies/helloworld-gke-authz-policy
    

    Die Endpunktrichtlinie gibt jetzt an, dass sowohl mTLS als auch die Autorisierungsrichtlinie für eingehende Anfragen an Pods erzwungen werden müssen, deren gRPC-Bootstrap-Dateien das Label app:helloworld enthalten.

  4. Importieren Sie die Richtlinie:

    gcloud network-services endpoint-policies import ep-mtls-psms \
      --source=ep-mtls-psms.yaml --location=global
    

Autorisierungsrichtlinie validieren

Folgen Sie dieser Anleitung, um zu prüfen, ob die Autorisierungsrichtlinie ordnungsgemäß funktioniert.

Java

  1. Öffnen Sie eine Shell für den Client-Pod, den Sie zuvor verwendet haben.

    kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
    
  2. Führen Sie in der Befehls-Shell die folgenden Befehle aus, um die Einrichtung zu validieren.

    cd grpc-java-1.42.1/examples/example-xds
    ./build/install/example-xds/bin/xds-hello-world-client --xds-creds xds-client \
          xds:///helloworld-gke:8000
    

    Die Ausgabe sollte in etwa so aussehen:

    Greeting: Hello xds-client, from xds-server
    
  3. Führen Sie den Client mit dem alternativen Servernamen noch einmal aus. Beachten Sie, dass dies ein Fehlerfall ist. Die Anfrage ist ungültig, da die Autorisierungsrichtlinie nur den Zugriff auf den Hostnamen helloworld-gke:8000 zulässt.

    ./build/install/example-xds/bin/xds-hello-world-client --xds-creds xds-client \
          xds:///helloworld-gke-noaccess:8000
    

    Die Ausgabe sollte in etwa so aussehen:

    WARNING: RPC failed: Status{code=PERMISSION_DENIED}
    

    Wenn diese Ausgabe nicht angezeigt wird, wird die Autorisierungsrichtlinie möglicherweise noch nicht verwendet. Warten Sie einige Minuten und versuchen Sie es noch einmal mit der Überprüfung.

Go

  1. Öffnen Sie eine Shell für den Client-Pod, den Sie zuvor verwendet haben.

    kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
    
  2. Führen Sie in der Befehls-Shell die folgenden Befehle aus, um die Einrichtung zu validieren.

    cd grpc-go-1.42.0/examples/features/xds/client
    GRPC_GO_LOG_VERBOSITY_LEVEL=2 GRPC_GO_LOG_SEVERITY="info" \
      go run main.go \
      -xds_creds \
      -name xds-client \
      -target xds:///helloworld-gke:8000
    

    Die Ausgabe sollte in etwa so aussehen:

    Greeting: Hello xds-client, from example-grpc-server-77548868d-l9hmf
    
  3. Führen Sie den Client mit dem alternativen Servernamen noch einmal aus. Beachten Sie, dass dies ein Fehlerfall ist. Die Anfrage ist ungültig, da die Autorisierungsrichtlinie nur den Zugriff auf den Hostnamen helloworld-gke:8000 zulässt.

    GRPC_GO_LOG_VERBOSITY_LEVEL=2 GRPC_GO_LOG_SEVERITY="info" \
      go run main.go \
      -xds_creds \
      -name xds-client \
      -target xds:///helloworld-gke-noaccess:8000
    

    Die Ausgabe sollte in etwa so aussehen:

    could not greet: rpc error: code = PermissionDenied desc = Incoming RPC is not allowed: rpc error: code = PermissionDenied desc = incoming RPC did not match an allow policy
    exit status 1
    

    Wenn Sie diese Ausgabe nicht sehen, ist die Autorisierungsrichtlinie möglicherweise nicht in genutzt haben. Warten Sie einige Minuten und versuchen Sie es noch einmal mit der Überprüfung.

TLS anstelle von mTLS verwenden

Die Verwendung von TLS in diesem Beispiel erfordert nur eine kleine Änderung.

  1. Löschen Sie in ServerTlsPolicy die mtlsPolicy:

    cat << EOF > server-tls-policy.yaml
    name: "server-tls-policy"
    serverCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    EOF
    
  2. Verwenden Sie diese Richtlinie stattdessen in der Datei EndpointPolicy:

    cat << EOF > ep-tls-psms.yaml
    name: "ep-mtls-psms"
    type: "GRPC_SERVER"
    serverTlsPolicy: "projects/${PROJECT_ID}/locations/global/serverTlsPolicies/server-tls-policy"
    trafficPortSelector:
      ports:
      - "50051"
    endpointMatcher:
      metadataLabelMatcher:
        metadataLabelMatchCriteria: "MATCH_ALL"
        metadataLabels: []
    EOF
    
  3. Die ClientTlsPolicy für mTLS funktioniert auch für TLS. Der Abschnitt clientCertificate der Richtlinie kann aber entfernt werden, da er für TLS nicht erforderlich ist:

    cat << EOF > client-tls-policy.yaml
    name: "client-tls-policy"
    serverValidationCa:
    - certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    EOF
    

Dienstsicherheit mit dem Wallet-Beispiel nutzen

Dieser Abschnitt bietet eine allgemeine Übersicht, in der gezeigt wird, wie Sie das Wallet-Beispiel mit der Dienstsicherheit für Java, C++ und Go aktivieren.

Java

Den Beispielquellcode für Java finden Sie auf github. Der Code verwendet bereits die XdsChannel- und XdsServer-Anmeldedaten, wenn Sie die proxylose Sicherheit konfigurieren.

Diese Anleitung beschreibt die Konfiguration des Wallet-Beispiels mit Go. Der Vorgang ist bei Java ähnlich. In der Anleitung wird ein bereits vorhandenes Docker-Image verwendet, das Sie aus dem Google Cloud-Container-Repository abrufen.

So erstellen Sie das Beispiel:

  1. Klonen Sie das Repository und rufen Sie die Dateien im Verzeichnis der gRPC-Beispiele ab.
  2. Bearbeiten Sie die Datei 00-common-env.sh. Kommentieren Sie die vorhandene Zeile aus, die den Wert von WALLET_DOCKER_IMAGE auf das Go-Docker-Image festlegt, und entfernen Sie die Kommentarzeichen in der Zeile, die den Wert von WALLET_DOCKER_IMAGE auf das Java-Docker-Image festlegt.
  3. Erstellen und konfigurieren Sie Cloud Router-Instanzen mithilfe der Anleitung unter Cloud Router-Instanzen erstellen und konfigurieren oder der Funktion create_cloud_router_instances im Skript 10.apis.sh.
  4. Erstellen Sie einen Cluster mit der Anleitung für das Beispiel hello world oder mit der Funktion create_cluster im Skript 20-cluster.sh.
  5. Erstellen Sie private Zertifizierungsstellen mithilfe der Anleitung für CA Service oder des Skripts 30-private-ca-setup.sh.
  6. Erstellen Sie Kubernetes-Ressourcen, einschließlich Dienstkonten, Namespaces, Kubernetes-Diensten, NEGs und serverseitiger Bereitstellung für alle Dienste: account, stats, stats_premium, wallet_v1, wallet_v2 mit dem Skript 40-k8s-resources.sh.
  7. Erstellen Sie für jeden von Ihnen erstellten Dienst eine Systemdiagnose und einen Backend-Dienst mit create_health_check und create_backend_service im Skript 50-td-components.sh.
  8. Erstellen Sie die Cloud Service Mesh-Routingkomponenten mit create_routing_components im Skript 60-routing-components.sh.
  9. Cloud Service Mesh-Sicherheitskomponenten für jeden Back-End-Dienst erstellen Verwenden Sie create_security_components im Skript 70-security-components.sh.
  10. Erstellen Sie die Bereitstellung des Wallet-Clients mit create_client_deployment im Skript 75-client-deployment.sh.
  11. Prüfen Sie die Konfiguration. Starten Sie dazu den Client wie unter Mit grpc-wallet-Clients prüfen beschrieben.

C++

Den Beispielquellcode für C++ finden Sie auf github. Der Code verwendet bereits die XdsChannel- und XdsServer-Anmeldedaten, wenn Sie die proxylose Sicherheit konfigurieren.

Diese Anleitung beschreibt die Konfiguration des Wallet-Beispiels mit Go. Der Prozess ist für C++ ähnlich. In der Anleitung wird ein bereits vorhandenes Docker-Image verwendet, das Sie aus dem Google Cloud-Container-Repository abrufen.

So erstellen Sie das Beispiel:

  1. Klonen Sie das Repository und rufen Sie die Dateien im Verzeichnis der gRPC-Beispiele ab.
  2. Bearbeiten Sie die Datei 00-common-env.sh. Kommentieren Sie die vorhandene Zeile aus, die den Wert von WALLET_DOCKER_IMAGE auf das Go-Docker-Image festlegt, und entfernen Sie die Kommentarzeichen in der Zeile, die den Wert von WALLET_DOCKER_IMAGE auf das C++-Docker-Image festlegt.
  3. Erstellen und konfigurieren Sie Cloud Router-Instanzen mithilfe der Anleitung unter Cloud Router-Instanzen erstellen und konfigurieren oder der Funktion create_cloud_router_instances im Skript 10.apis.sh.
  4. Erstellen Sie einen Cluster mit der Anleitung für das Beispiel hello world oder mit der Funktion create_cluster im Skript 20-cluster.sh.
  5. Erstellen Sie private Zertifizierungsstellen mithilfe der Anleitung für CA Service oder des Skripts 30-private-ca-setup.sh.
  6. Erstellen Sie Kubernetes-Ressourcen, einschließlich Dienstkonten, Namespaces, Kubernetes-Diensten, NEGs und serverseitiger Bereitstellung für alle Dienste: account, stats, stats_premium, wallet_v1, wallet_v2 mit dem Skript 40-k8s-resources.sh.
  7. Erstellen Sie für jeden von Ihnen erstellten Dienst eine Systemdiagnose und einen Backend-Dienst mit create_health_check und create_backend_service im Skript 50-td-components.sh.
  8. Erstellen Sie die Cloud Service Mesh-Routingkomponenten mit create_routing_components im Skript 60-routing-components.sh.
  9. Cloud Service Mesh-Sicherheitskomponenten für jeden Back-End-Dienst erstellen Verwenden Sie create_security_components im Skript 70-security-components.sh.
  10. Erstellen Sie die Bereitstellung des Wallet-Clients mit create_client_deployment im Skript 75-client-deployment.sh.
  11. Prüfen Sie die Konfiguration. Starten Sie dazu den Client wie unter Mit grpc-wallet-Clients prüfen beschrieben.

Go

Den Beispielquellcode für Go finden Sie auf github. Der Code verwendet bereits die XdsChannel- und XdsServer-Anmeldedaten, wenn Sie die proxylose Sicherheit konfigurieren.

In der Anleitung wird ein bereits vorhandenes Docker-Image verwendet, das Sie aus dem Google Cloud-Container-Repository abrufen.

So erstellen Sie das Beispiel:

  1. Klonen Sie das Repository und rufen Sie die Dateien im Verzeichnis der gRPC-Beispiele ab.
  2. Bearbeiten Sie die Datei 00-common-env.sh und legen Sie die korrekten Werte für die Umgebungsvariablen fest.
  3. Erstellen und konfigurieren Sie Cloud Router-Instanzen mithilfe der Anleitung unter Cloud Router-Instanzen erstellen und konfigurieren oder der Funktion create_cloud_router_instances im Skript 10.apis.sh.
  4. Erstellen Sie einen Cluster mit der Anleitung für das Beispiel hello world oder mit der Funktion create_cluster im Skript 20-cluster.sh.
  5. Erstellen Sie private Zertifizierungsstellen mithilfe der Anleitung für CA Service oder des Skripts 30-private-ca-setup.sh.
  6. Erstellen Sie Kubernetes-Ressourcen, einschließlich Dienstkonten, Namespaces, Kubernetes-Diensten, NEGs und serverseitiger Bereitstellung für alle Dienste: account, stats, stats_premium, wallet_v1, wallet_v2 mit dem Skript 40-k8s-resources.sh.
  7. Erstellen Sie für jeden von Ihnen erstellten Dienst eine Systemdiagnose und einen Backend-Dienst mit create_health_check und create_backend_service im Skript 50-td-components.sh.
  8. Erstellen Sie die Cloud Service Mesh-Routingkomponenten mit create_routing_components im Skript 60-routing-components.sh.
  9. Cloud Service Mesh-Sicherheitskomponenten für jeden Back-End-Dienst erstellen Verwenden Sie create_security_components im Skript 70-security-components.sh.
  10. Erstellen Sie die Bereitstellung des Wallet-Clients mit create_client_deployment im Skript 75-client-deployment.sh.
  11. Prüfen Sie die Konfiguration. Starten Sie dazu den Client wie unter Mit grpc-wallet-Clients prüfen beschrieben.

Bootstrap-Datei

Im Rahmen der Einrichtung in dieser Anleitung wird ein Bootstrap-Generator verwendet, um die erforderliche Bootstrap-Datei zu generieren. Dieser Abschnitt bietet Referenzinformationen für die eigentliche Bootstrap-Datei.

Die Bootstrap-Datei enthält Konfigurationsinformationen, die für proxylosen gRPC-Code erforderlich sind, einschließlich Verbindungsinformationen für den xDS-Server. Die Bootstrap-Datei enthält auch eine Sicherheitskonfiguration, die für das Feature der proxylosen gRPC-Sicherheit benötigt wird. Der gRPC-Server benötigt ein zusätzliches Feld, wie in den folgenden Abschnitten beschrieben. Ein Beispiel für eine Bootstrap-Datei sieht so aus:

{
  "xds_servers": [
    {
      "server_uri": "trafficdirector.googleapis.com:443",
      "channel_creds": [
        {
          "type": "google_default"
        }
      ],
      "server_features": [
        "xds_v3"
      ]
    }
  ],
  "node": {
    "cluster": "cluster",
    "id": "projects/9876012345/networks/default/nodes/client1",
    "metadata": {
      "TRAFFICDIRECTOR_GCP_PROJECT_NUMBER": "9876012345",
      "TRAFFICDIRECTOR_NETWORK_NAME": "default",
      "INSTANCE_IP": "10.0.0.3"
    },
    "locality": {
      "zone": "us-central1-a"
    }
  },
  "server_listener_resource_name_template": "grpc/server?xds.resource.listening_address=%s",
  "certificate_providers": {
    "google_cloud_private_spiffe": {
      "plugin_name": "file_watcher",
      "config": {
        "certificate_file": "/var/run/secrets/workload-spiffe-credentials/certificates.pem",
        "private_key_file": "/var/run/secrets/workload-spiffe-credentials/private_key.pem",
        "ca_certificate_file": "/var/run/secrets/workload-spiffe-credentials/ca_certificates.pem",
        "refresh_interval": "600s"
      }
    }
  }
}

Bootstrap-Datei für den Sicherheitsdienst aktualisieren

Die folgenden Felder geben Änderungen in Bezug auf die Nutzung von Sicherheit und xDS v3 wieder:

Das Feld id in node bietet eine eindeutige Identität für den gRPC-Client, um Cloud Service Mesh. Sie müssen die Google Cloud-Projektnummer und den Netzwerknamen mithilfe der Knoten-ID im folgenden Format angeben:

projects/{project number}/networks/{network name}/nodes/[UNIQUE_ID]

Ein Beispiel für die Projektnummer 1234 und das Standardnetzwerk sieht so aus:

projects/1234/networks/default/nodes/client1

Das Feld INSTANCE_IP ist die IP-Adresse des Pods oder enthält 0.0.0.0 zur Angabe von INADDR_ANY. Dieses Feld wird vom gRPC-Server verwendet, um die Überwachungsressource aus Cloud Service Mesh für die serverseitige Sicherheit abzurufen.

Felder der Sicherheitskonfiguration in der Bootstrap-Datei

JSON-Schlüssel Typ Wert Hinweise
server_listener_resource_name_template String grpc/server?xds.resource.listening_address=%s Erforderlich für gRPC-Server. gRPC verwendet diesen Wert, um den Ressourcennamen zum Abrufen der Listener-Ressource aus dem Cloud Service Mesh für serverseitige Sicherheit und andere Konfigurationen zu erstellen. gRPC verwendet diesen String, um den String für den Ressourcennamen zu bilden.
certificate_providers JSON-Struktur google_cloud_private_spiffe Erforderlich. Der Wert ist eine JSON-Struktur, die eine Zuordnung von Namen zu Zertifikatsanbieterinstanzen darstellt. Mit einer Zertifikatsanbieterinstanz werden Identitäts- und Stammzertifikate abgerufen. Die Bootstrap-Beispieldatei enthält den Namen google_cloud_private_spiffe mit der JSON-Struktur der Zertifikatanbieterinstanz als Wert. Jede JSON-Struktur der Zertifikatanbieterinstanz enthält zwei Felder:
  • plugin_name: Erforderlicher Wert, der angibt, welches Zertifikatanbieter-Plug-in gemäß der gRPC-Plug-in-Architektur für Zertifikatanbieter verwendet werden soll. gRPC unterstützt das für diese Einrichtung verwendete Filewatch-Plug-in. Der Plug-in-Name lautet file_watcher.
  • config: Erforderlicher Wert, der den JSON-Konfigurationsblog für das Plug-in file_watcher angibt. Das Schema und der Inhalt sind vom Plug-in abhängig.

In der JSON-config-Struktur für das Plug-in file_watcher ist Folgendes enthalten:

  • certificate_file: Erforderlicher String. Dieser Wert steht für den Speicherort des Identitätszertifikats.
  • private_key_file: Erforderlicher String. Der Wert steht für den Speicherort der Datei für den privaten Schlüssel, der mit dem Identitätszertifikat übereinstimmen muss.
  • ca_certificate_file: Erforderlicher String. Der Wert steht für den Speicherort des Stammzertifikats, das auch als Vertrauens-Bundle bezeichnet wird.
  • refresh_interval: Optionaler String. Der Wert gibt das Aktualisierungsintervall an, das mithilfe der Stringdarstellung der JSON-Zuordnung einer Dauer festgelegt wird. Der Standardwert ist "600s". Das entspricht einer Dauer von 10 Minuten.

Bootstrap-Generator

Das Container-Image des Bootstrap-Generators ist unter gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 verfügbar. Den zugehörigen Quellcode finden Sie unter https://github.com/GoogleCloudPlatform/traffic-director-grpc-bootstrap. Am häufigsten werden folgende Befehlszeilenoptionen verwendet:

  • --output: Mit dieser Option geben Sie an, wohin die Ausgabe-Bootstrap-Datei geschrieben werden soll. Beispielsweise generiert der Befehl --output /tmp/bootstrap/td-grpc-bootstrap.json die Bootstrap-Datei in /tmp/bootstrap/td-grpc-bootstrap.json im Dateisystem des Pods.
  • --node-metadata: Mit diesem Flag geben Sie den Inhalt der Knotenmetadaten in der Bootstrap-Datei an. Dies ist erforderlich, wenn Sie Metadaten-Label-Matcher verwenden in Die EndpointPolicy, in der Cloud Service Mesh die Labeldaten verwendet im Abschnitt mit den Knotenmetadaten der Bootstrap-Datei. Das Argument wird im Format "Schlüssel=Wert" angegeben, z. B. --node-metadata version=prod --node-metadata type=grpc.

Durch diese Optionen wird im Abschnitt „Knotenmetadaten“ des Bootstrap Folgendes hinzugefügt: Datei:

{
  "node": {
...
    "metadata": {
      "version": "prod",
      "type": "grpc",
...
    },
...
  },
...
}

Bereitstellung löschen

Optional können Sie diese Befehle ausführen, um die Bereitstellung zu löschen, die Sie in dieser Anleitung erstellt haben.

Führen Sie den folgenden Befehl aus, um den Cluster zu löschen:

gcloud container clusters delete CLUSTER_NAME --zone ZONE --quiet

Führen Sie die folgenden Befehle aus, um die von Ihnen erstellten Ressourcen zu löschen:

gcloud compute backend-services delete grpc-gke-helloworld-service --global --quiet
cloud compute network-endpoint-groups delete example-grpc-server --zone ZONE --quiet
gcloud compute firewall-rules delete grpc-gke-allow-health-checks --quiet
gcloud compute health-checks delete grpc-gke-helloworld-hc --quiet
gcloud network-services endpoint-policies delete ep-mtls-psms \
    --location=global --quiet
gcloud network-security authorization-policies delete helloworld-gke-authz-policy \
   --location=global --quiet
gcloud network-security client-tls-policies delete client-mtls-policy \
    --location=global --quiet
gcloud network-security server-tls-policies delete server-tls-policy \
    --location=global --quiet
gcloud network-security server-tls-policies delete server-mtls-policy \
    --location=global --quiet

Fehlerbehebung

Folgen Sie dieser Anleitung, um eventuelle Probleme im Rahmen der Bereitstellung von Sicherheit zu beheben.

Arbeitslasten können keine Konfiguration aus Cloud Service Mesh abrufen

Dies betrifft eine Fehlermeldung wie beispielsweise die folgende:

PERMISSION_DENIED: Request had insufficient authentication scopes.

Folgende Punkte sollten beachtet werden:

  • Sie haben den GKE-Cluster mit dem Argument --scopes=cloud-platform erstellt.
  • Sie haben Ihren Kubernetes-Dienstkonten roles/trafficdirector.client zugewiesen.
  • Sie haben roles/trafficdirector.client Ihrem Google Cloud-Standarddienstkonto (${GSA_EMAIL} oben) zugewiesen.
  • Sie haben den Dienst trafficdirector.googleapis.com (API) aktiviert.

Ihr gRPC-Server verwendet TLS oder mTLS auch bei korrekter Cloud Service Mesh-Konfiguration nicht

Prüfen Sie, ob in der Konfiguration der Endpunktrichtlinien GRPC_SERVER angegeben ist. Wenn Sie stattdessen SIDECAR_PROXY festgelegt haben, wird die Konfiguration von gRPC ignoriert.

Sie können den GKE-Cluster nicht mit der angeforderten Clusterversion erstellen

Der Befehl zum Erstellen des GKE-Clusters schlägt eventuell mit einer Fehlermeldung wie der folgenden fehl:

Node version "1.20.5-gke.2000" is unsupported.

Achten Sie darauf, dass Sie in Ihrem Befehl zum Erstellen eines Clusters das Argument --release-channel rapid verwendet wird. Für die richtige Version für diesen Release verwenden Sie den Rapid Release Channel.

Der Fehler No usable endpoint wird angezeigt

Wenn ein Client aufgrund eines No usable endpoint-Fehlers nicht mit dem Server kommunizieren kann, hat die Systemdiagnose möglicherweise die Server-Back-Ends als fehlerhaft markiert. Führen Sie in diesem Fall folgenden gcloud-Befehl aus, um den Status der Back-Ends zu prüfen:

gcloud compute backend-services get-health grpc-gke-helloworld-service --global

Wenn der Befehl den Back-End-Status als fehlerhaft zurückgibt, kann dies folgende Gründe haben:

  • Die Firewall wurde nicht erstellt oder sie enthält nicht den korrekten Quell-IP-Bereich.
  • Die Ziel-Tags in Ihrer Firewall stimmen nicht mit den Tags im von Ihnen erstellten Cluster überein.

Arbeitslasten können in der eingerichteten Sicherheit nicht kommunizieren

Wenn Ihre Arbeitslasten nicht mehr kommunizieren können, nachdem Sie die Sicherheit für Ihr proxyloses Service Mesh eingerichtet haben, folgen Sie dieser Anleitung zur Ermittlung der Ursache.

  1. Deaktivieren Sie die proxylose Sicherheit und beheben Sie Probleme in den Load-Balancing-Anwendungsfällen des proxylosen Service Mesh. Sie haben zwei Möglichkeiten, um die Sicherheit im Service Mesh zu deaktivieren:
    1. Sie verwenden Anmeldedaten in Klartextform auf Client- und Serverseite ODER
    2. konfigurieren Sie keine Sicherheit für den Back-End-Dienst und die Endpunktrichtlinie in der Cloud Service Mesh-Konfiguration.

Folgen Sie der Anleitung unter Fehlerbehebung bei proxylosen Cloud Service Mesh-Deployments, da in Ihrem Deployment keine Sicherheitseinrichtung vorhanden ist.

  1. Ändern Sie Ihre Arbeitslasten so, dass xDS-Anmeldedaten im Nur-Text- oder unsicheren Format verwendet werden Anmeldedaten als Fallback-Anmeldedaten. Lassen Sie die Cloud Service Mesh-Konfiguration mit deaktivierter Sicherheit wie oben erläutert. In diesem Fall Obwohl gRPC Cloud Service Mesh die Konfiguration der Sicherheit ermöglicht, Cloud Service Mesh sendet keine Sicherheitsinformationen. In diesem Fall sendet gRPC auf Nur-Text- oder unsichere Anmeldedaten zurückgreifen, was funktionieren sollte. ähnlich wie im ersten zuvor beschriebenen Fall. Sollte dieser Fall nicht funktionieren, Gehen Sie so vor:

    1. Erhöhen Sie die Protokollierungsebene auf Client- und Serverseite, die zwischen gRPC und Cloud Service Mesh ausgetauschten xDS-Nachrichten sehen.
    2. Sorgen Sie dafür, dass für Cloud Service Mesh keine Sicherheit in den CDS- und LDS-Antworten aktiviert ist, die an die Arbeitslasten gesendet werden.
    3. Sorgen Sie dafür, dass die Arbeitslasten in den Kanälen nicht den TLS- oder mTLS-Modus verwenden. Wenn Logeinträge in Bezug auf TLS-Handshakes vorhanden sind, prüfen Sie den Quellcode Ihrer Anwendung, ob unsichere oder Klartext-Anmeldedaten für den Fallback verwendet werden. Wenn der Anwendungsquellcode korrekt ist, liegt die Ursache möglicherweise an einem Programmfehler in der gRPC-Bibliothek.
  2. Prüfen Sie mit den Schritten zur Fehlerbehebung in diesem Nutzerhandbuch, ob die CA-Dienst-Einbindung in Ihren GKE-Cluster ordnungsgemäß funktioniert. Sorgen Sie dafür, dass die von diesem Feature bereitgestellten Zertifikate und Schlüssel im angegebenen Verzeichnis /var/run/secrets/workload-spiffe-credentials/ verfügbar sind.

  3. Aktivieren Sie wie zuvor beschrieben TLS (anstelle von mTLS) in Ihrem Mesh-Netzwerk und starten Sie es neu. Ihre Client- und Serverarbeitslasten.

    1. Erhöhen Sie die Logging-Ebene sowohl client- als auch serverseitig, damit die xDS-Nachrichten angezeigt werden, die zwischen gRPC und Cloud Service Mesh ausgetauscht werden.
    2. Achten Sie darauf, dass für Cloud Service Mesh die Sicherheit in den CDS- und LDS-Antworten aktiviert ist, die an die Arbeitslasten gesendet werden.

Client schlägt mit CertificateException und der Fehlermeldung Peer certificate SAN check failed fehl

Dies deutet auf ein Problem mit den subjectAltNames-Werten in der SecuritySettings-Nachricht hin. Diese Werte basieren auf den Kubernetes-Diensten, die Sie für Ihren Back-End-Dienst erstellt haben. Jedem von Ihnen erstellten Kubernetes-Dienst ist eine SPIFFE-ID im folgenden Format zugeordnet:

spiffe://${WORKLOAD_POOL}/ns/${K8S_NAMESPACE}/sa/${SERVICE_ACCOUNT}

Dabei gilt:

  • WORKLOAD_POOL ist der Arbeitslastpool für den Cluster, in diesem Fall ${PROJECT_ID}.svc.id.goog.
  • K8S_NAMESPACE ist der Kubernetes-Namespace, den Sie für das Deployment des Dienstes verwendet haben.
  • SERVICE_ACCOUNT ist das Kubernetes-Dienstkonto, das Sie für das Deployment des Dienstes verwendet haben.

Prüfen Sie für jeden Kubernetes-Dienst, den Sie als Netzwerk-Endpunktgruppe an Ihren Back-End-Dienst angehängt haben, ob die SPIFFE-ID korrekt berechnet und dem Feld subjectAltNames in der Nachricht SecuritySettings hinzugefügt wurde.

Anwendungen können die mTLS-Zertifikate nicht mit Ihrer gRPC-Bibliothek verwenden

Wenn Ihre Anwendungen nicht in der Lage sind, die mTLS-Zertifikate mit Ihrer gRPC-Bibliothek zu nutzen, gehen Sie so vor:

  1. Prüfen Sie, ob die Pod-Spezifikation die Annotation security.cloud.google.com/use-workload-certificates enthält, die unter Proxylosen gRPC-Dienst mit NEGs erstellen beschrieben wird.

  2. Prüfen Sie, ob die Dateien, die die Zertifikatskette zusammen mit dem Blattzertifikat, dem privaten Schlüssel und den vertrauenswürdigen CA-Zertifikaten enthalten, unter den folgenden Pfaden im Pod zugänglich sind:

    1. Zertifikatskette in Verbindung mit Blattzertifikat: "/var/run/secrets/workload-spiffe-credentials/certificates.pem"
    2. Privater Schlüssel: "/var/run/secrets/workload-spiffe-credentials/private_key.pem"
    3. CA-Paket: "/var/run/secrets/workload-spiffe-credentials/ca_certificates.pem"
  3. Wenn die Zertifikate aus dem vorherigen Schritt nicht verfügbar sind, gehen Sie so vor:

      gcloud privateca subordinates describe SUBORDINATE_CA_POOL_NAME 
    --location=LOCATION

    1. Prüfen Sie, ob die Steuerungsebene von GKE die richtige IAM-Rollenbindung hat, die ihr Zugriff auf den CA-Dienst gewährt:

      # Get the IAM policy for the CA
      gcloud privateca roots get-iam-policy ROOT_CA_POOL_NAME
      
      # Verify that there is an IAM binding granting access in the following format
      - members:
      - serviceAccount:service-projnumber@container-engine-robot.iam.gserviceaccount.com
      role: roles/privateca.certificateManager
      
      # Where projnumber is the project number (e.g. 2915810291) for the GKE cluster.
      
    2. Prüfen Sie, ob das Zertifikat abgelaufen ist. Dieses besteht aus der Zertifikatskette und dem Blattzertifikat unter /var/run/secrets/workload-spiffe-credentials/certificates.pem. Führen Sie dazu den folgenden Befehl aus:

      cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
      

    3. Prüfen Sie mit dem folgenden Befehl, ob der Schlüsseltyp von Ihrer Anwendung unterstützt wird:

      cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3
      

    4. Prüfen Sie, ob Ihre gRPC-Java-Anwendung in der YAML-Datei WorkloadCertificateConfig den folgenden keyAlgorithm enthält:

      keyAlgorithm:
        rsa:
          modulusSize: 4096
    
  4. Prüfen Sie, ob die Zertifizierungsstelle die gleiche Schlüsselfamilie wie der Zertifikatschlüssel verwendet.

Das Zertifikat einer Anwendung wurde vom Client, vom Server oder von einer Peer-Anwendung abgelehnt

  1. Prüfen Sie, ob die Peer-Anwendung das gleiche Vertrauens-Bundle verwendet, um das Zertifikat zu prüfen.
  2. Prüfen Sie, ob das verwendete Zertifikat abgelaufen ist (Zertifikatskette in Verbindung mit Blattzertifikat): "/var/run/secrets/workload-spiffe-credentials/certificates.pem".

Pods bleiben im Status „Ausstehend“

Wenn die Pods während der Einrichtung im Status "Ausstehend" verbleiben, erhöhen Sie die CPU- und Arbeitsspeicherressourcen für die Pods in der Deployment-Spezifikation.

Cluster mit dem Flag --enable-mesh-certificates kann nicht erstellt werden

Prüfen Sie, ob die neueste Version der gcloud CLI ausgeführt wird:

gcloud components update

Beachten Sie, dass das Flag --enable-mesh-certificates nur mit gcloud beta funktioniert.

Pods werden nicht gestartet

Pods, die GKE-Mesh-Zertifikate verwenden, starten möglicherweise nicht, wenn die Zertifikatbereitstellung fehlschlägt. Das kann in Situationen wie den folgenden passieren:

  • WorkloadCertificateConfig oder TrustConfig ist falsch konfiguriert oder fehlt.
  • CSRs werden nicht genehmigt.

Sie können prüfen, ob die Zertifikatbereitstellung fehlschlägt, indem Sie die Pod-Ereignisse prüfen.

  1. Prüfen Sie den Status Ihres Pods:

    kubectl get pod -n POD_NAMESPACE POD_NAME
    

    Dabei gilt:

    • POD_NAMESPACE: der Namespace Ihres Pods.
    • POD_NAME: der Name Ihres Pods.
  2. Prüfen Sie die letzten Ereignisse für den Pod:

    kubectl describe pod -n POD_NAMESPACE POD_NAME
    
  3. Wenn die Bereitstellung von Zertifikaten fehlschlägt, wird ein Ereignis mit Type=Warning, Reason=FailedMount, From=kubelet und mit einem Message-Feld angezeigt, das mit MountVolume.SetUp failed for volume "gke-workload-certificates" beginnt. Das Feld Message enthält Informationen zur Fehlerbehebung.

    Events:
      Type     Reason       Age                From       Message
      ----     ------       ----               ----       -------
      Warning  FailedMount  13s (x7 over 46s)  kubelet    MountVolume.SetUp failed for volume "gke-workload-certificates" : rpc error: code = Internal desc = unable to mount volume: store.CreateVolume, err: unable to create volume "csi-4d540ed59ef937fbb41a9bf5380a5a534edb3eedf037fe64be36bab0abf45c9c": caPEM is nil (check active WorkloadCertificateConfig)
    
  4. Führen Sie die folgenden Schritte zur Fehlerbehebung aus, wenn die Pods nicht starten, weil falsch konfigurierte Objekte oder abgelehnte CSRs vorliegen.

WorkloadCertificateConfig oder TrustConfig ist falsch konfiguriert

Prüfen Sie, ob die WorkloadCertificateConfig- und TrustConfig-Objekte korrekt erstellt wurden. Sie können Fehlkonfigurationen für eines dieser Objekte mit kubectl diagnostizieren.

  1. Rufen Sie den aktuellen Status ab.

    Für WorkloadCertificateConfig:

    kubectl get WorkloadCertificateConfig default -o yaml
    

    Für TrustConfig:

    kubectl get TrustConfig default -o yaml
    
  2. Prüfen Sie die Statusausgabe. Ein gültiges Objekt hat eine Bedingung mit type: Ready und status: "True".

    status:
      conditions:
      - lastTransitionTime: "2021-03-04T22:24:11Z"
        message: WorkloadCertificateConfig is ready
        observedGeneration: 1
        reason: ConfigReady
        status: "True"
        type: Ready
    

    Bei ungültigen Objekten wird stattdessen status: "False" angezeigt. Die Felder reason und message enthalten zusätzliche Informationen zur Fehlerbehebung.

CSRs sind nicht genehmigt

Wenn bei der CSR-Genehmigung ein Fehler auftritt, können Sie die Fehlerdetails in den Bedingungen type: Approved und type: Issued der CSR überprüfen.

  1. Listen Sie die relevanten CSRs mithilfe von kubectl auf:

    kubectl get csr \
      --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'
    
  2. Wählen Sie eine CSR aus, für die entweder Approved und nicht Issued gilt oder für die Approved nicht gilt.

  3. Rufen Sie mithilfe von kubectl Details zur ausgewählten CSR ab:

    kubectl get csr CSR_NAME -o yaml
    

    Ersetzen Sie CSR_NAME durch den Namen der ausgewählten CSR.

Eine gültige CSR hat eine Bedingung mit type: Approved und status: "True" und ein gültiges Zertifikat im Feld status.certificate:

status:
  certificate: <base64-encoded data>
  conditions:
  - lastTransitionTime: "2021-03-04T21:58:46Z"
    lastUpdateTime: "2021-03-04T21:58:46Z"
    message: Approved CSR because it is a valid SPIFFE SVID for the correct identity.
    reason: AutoApproved
    status: "True"
    type: Approved

Informationen zur Fehlerbehebung für ungültige CSRs werden in den Feldern message und reason angezeigt.

Den Pods fehlen Zertifikate

  1. Rufen Sie die Pod-Spezifikation für Ihren Pod ab:

    kubectl get pod -n POD_NAMESPACE POD_NAME -o yaml
    

    Dabei gilt:

    • POD_NAMESPACE: der Namespace Ihres Pods.
    • POD_NAME: der Name Ihres Pods.
  2. Prüfen Sie, ob die Pod-Spezifikation die Annotation security.cloud.google.com/use-workload-certificates enthält, die unter Pods für den Empfang von mTLS-Anmeldedaten konfigurieren beschrieben wird.

  3. Prüfen Sie, ob der Admission-Controller für GKE-Mesh-Zertifikate erfolgreich ein CSI-Treiber-Volume vom Typ workloadcertificates.security.cloud.google.com in Ihre Pod-Spezifikation eingefügt hat:

    volumes:
    ...
    -csi:
      driver: workloadcertificates.security.cloud.google.com
      name: gke-workload-certificates
    ...
    
  4. Prüfen Sie, ob in jedem der Container eine Volume-Bereitstellung vorhanden ist:

    containers:
    - name: ...
      ...
      volumeMounts:
      - mountPath: /var/run/secrets/workload-spiffe-credentials
        name: gke-workload-certificates
        readOnly: true
      ...
    
  5. Prüfen Sie, ob die folgenden Zertifikatpakete und der private Schlüssel an den angegebenen Speicherorten im Pod verfügbar sind:

    • Zertifikatsketten-Bundle: /var/run/secrets/workload-spiffe-credentials/certificates.pem
    • Privater Schlüssel: /var/run/secrets/workload-spiffe-credentials/private_key.pem
    • CA-Trust-Anchor-Paket: /var/run/secrets/workload-spiffe-credentials/ca_certificates.pem
  6. Wenn die Dateien nicht verfügbar sind, gehen Sie so vor:

    1. Rufen Sie die CA Service-Instanz (Vorschau) für den Cluster ab:

      kubectl get workloadcertificateconfigs default -o jsonpath '{.spec.certificateAuthorityConfig.certificateAuthorityServiceConfig.endpointURI}'
      
    2. Rufen Sie den Status der CA Service-Instanz (Vorschau) ab:

      gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \
        --location ISSUING_CA_LOCATION
      

      Dabei gilt:

      • ISSUING_CA_TYPE: der ausstellende CA-Typ, der entweder subordinates oder roots sein muss.
      • ISSUING_CA_NAME: der Name der ausstellenden CA.
      • ISSUING_CA_LOCATION: die Region der ausstellenden Zertifizierungsstelle.
    3. Rufen Sie die IAM-Richtlinie für die Stamm-CA ab:

      gcloud privateca roots get-iam-policy ROOT_CA_NAME
      

      Ersetzen Sie ROOT_CA_NAME durch den Namen Ihrer Stammzertifizierungsstelle.

    4. Prüfen Sie in der IAM-Richtlinie, ob die Richtlinienbindung privateca.auditor vorhanden ist:

      ...
      - members:
        - serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com
        role: roles/privateca.auditor
      ...
      

      In diesem Beispiel ist PROJECT_NUMBER die Projektnummer Ihres Clusters.

    5. Rufen Sie die IAM-Richtlinie für die untergeordnete Zertifizierungsstelle ab:

      gcloud privateca subordinates get-iam-policy SUBORDINATE_CA_NAME
      

      Ersetzen Sie SUBORDINATE_CA_NAME durch den Namen der untergeordneten CA.

    6. Prüfen Sie in der IAM-Richtlinie, ob die Richtlinienbindung privateca.certificateManager vorhanden ist:

      ...
      - members:
        - serviceAccount: service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com
        role: roles/privateca.certificateManager
      ...
      

      In diesem Beispiel ist PROJECT_NUMBER die Projektnummer Ihres Clusters.

Anwendungen können die ausgegebenen mTLS-Anmeldedaten nicht verwenden

  1. Prüfen Sie, ob das Zertifikat noch gültig ist:

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
    
  2. Prüfen Sie, ob der verwendete Schlüsseltyp von der Anwendung unterstützt wird.

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3
    
  3. Prüfen Sie, ob die ausstellende Zertifizierungsstelle die gleiche Schlüsselfamilie wie der Zertifikatschlüssel verwendet.

    1. Rufen Sie den Status der CA Service-Instanz (Vorschau) ab:

      gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \
        --location ISSUING_CA_LOCATION
      

      Dabei gilt:

      • ISSUING_CA_TYPE: der ausstellende CA-Typ, der entweder subordinates oder roots sein muss.
      • ISSUING_CA_NAME: der Name der ausstellenden CA.
      • ISSUING_CA_LOCATION: die Region der ausstellenden Zertifizierungsstelle.
    2. Prüfen Sie, ob der keySpec.algorithm in der Ausgabe der gleiche Schlüsselalgorithmus ist wie der, den Sie im YAML-Manifest WorkloadCertificateConfig definiert haben. Sie erhalten folgende Ausgabe:

      config:
        ...
        subjectConfig:
          commonName: td-sub-ca
          subject:
            organization: TestOrgLLC
          subjectAltName: {}
      createTime: '2021-05-04T05:37:58.329293525Z'
      issuingOptions:
        includeCaCertUrl: true
      keySpec:
        algorithm: RSA_PKCS1_2048_SHA256
       ...
      

Zertifikate werden abgelehnt

  1. Prüfen Sie, ob die Peer-Anwendung dasselbe Vertrauens-Bundle verwendet, um das Zertifikat zu verifizieren.
  2. Prüfen Sie, ob das Zertifikat noch gültig ist:

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
    
  3. Prüfen Sie, ob der Clientcode regelmäßig die Anmeldedaten aus dem Dateisystem aktualisiert, wenn die Go API für das Neuladen der Anmeldedaten für gRPC nicht verwendet wird.

  4. Prüfen Sie, ob sich Ihre Arbeitslasten in derselben vertrauenswürdigen Domain wie Ihre Zertifizierungsstelle befinden. GKE-Mesh-Zertifikate unterstützen die Kommunikation zwischen Arbeitslasten in einer einzigen vertrauenswürdigen Domain.

Beschränkungen

Die Cloud Service Mesh-Dienstsicherheit wird nur mit GKE unterstützt. Sie können die Dienstsicherheit nicht mit der Compute Engine bereitstellen.

Cloud Service Mesh unterstützt keine Szenarien, bei denen zwei oder mehr Endpunktrichtlinienressourcen vorhanden sind, die mit einem Endpunkt übereinstimmen, z. B. zwei Richtlinien mit den gleichen Labels und Ports oder zwei oder mehr Richtlinien mit unterschiedlichen Labels, die mit den Labels eines Endpunkts übereinstimmen. Weitere Informationen zum Abgleichen von Endpunktrichtlinien mit den Labels eines Endpunkts finden Sie unter APIs für EndpointPolicy.EndpointMatcher.MetadataLabelMatcher. In solchen Situationen generiert Cloud Service Mesh keine Sicherheitskonfiguration über die in Konflikt stehenden Richtlinien.