Dienstsicherheit mit proxylosem gRPC einrichten
In dieser Anleitung wird gezeigt, wie Sie einen Sicherheitsdienst für ein proxyloses gRPC-Service-Mesh konfigurieren.
Voraussetzungen
Damit die Dienstsicherheit für ein proxyloses gRPC-Service-Mesh konfiguriert werden kann, müssen Sie die folgenden Voraussetzungen erfüllt sein:
- Ihre Bereitstellung erfüllt die Anforderungen unter Einrichtung von Service-Routing-APIs mit Envoy- und proxylosen Arbeitslasten vorbereiten.
- Sie müssen xDS v3 verwenden.
- Sie haben Zugriff auf die erforderlichen Funktionen der xDS-Version und des Zertifikatanbieters mit einer der folgenden Sprachen:
- gRPC Java
- gRPC C++
- gRPC Python
- gRPC Go Die erforderlichen Sprachversionen finden Sie auf github.
- Sie haben Zugriff auf den Bootstrap-Generator, Version 0.16.0. Das Bootstrap-Generator-Image befindet sich im Google Cloud -Container-Repository.
- Alle Voraussetzungen für das Load-Balancing für ein proxyloses gRPC-Service-Mesh müssen erfüllt sein.
- Sie haben ausreichende Berechtigungen zum Erstellen oder Aktualisieren der Cloud Service Mesh- undGoogle Cloud Service-Mesh-Ressourcen für das Verwenden der PSM-Sicherheit. Ausführliche Informationen zu den erforderlichen Berechtigungen finden Sie unter Einrichten von Cloud Service Mesh mit proxylosen gRPC-Diensten vorbereiten.
- Sie haben die erforderlichen Berechtigungen zur Verwendung von Certificate Authority Service, die unter Zertifizierungsstellen zum Ausstellen von Zertifikaten erstellen beschrieben werden.
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 in der Backend-Dienstressource auf diese Ressourcen 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 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 Einrichtungsvorgang ist eine Erweiterung der Cloud Service Mesh-Einrichtung mit GKE- und proxylosen gRPC-Diensten. Auf vorhandene nicht geänderte Schritte dieses Einrichtungsverfahrens wird jeweils verwiesen.
Im Folgenden sind die wichtigsten Erweiterungen für die Cloud Service Mesh-Einrichtung mit GKE aufgeführt:
- Einrichten von CA Service, in dem Sie private CA-Pools und die erforderlichen Zertifizierungsstellen erstellen
- Erstellen eines GKE-Cluster mit Features für die Identitätsföderation von Arbeitslasten für GKE und Mesh-Zertifikate sowie Einbindung in CA Service
- Konfigurieren der Ausstellung von Mesh-Zertifikaten im Cluster
- Erstellen der Client- und Serverdienstkonten
- Einrichten des Beispielservers, der xDS-APIs und xDS-Serveranmeldedaten zum Abrufen der Sicherheitskonfiguration von Cloud Service Mesh verwendet
- Einrichten des Beispielclients, der xDS-Anmeldedaten verwendet
- Aktualisieren der Cloud Service Mesh-Konfiguration für die Übernahme der Sicherheitskonfiguration
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=PROJECT_ID
# GKE cluster name and zone for this example.
CLUSTER_NAME=CLUSTER_NAME
ZONE=ZONE
gcloud config set compute/zone $ZONE
# 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.
Führen Sie den folgenden Befehl aus, um Cloud Service Mesh und andere APIs zu aktivieren, die für die Sicherheit für ein proxyloses gRPC-Service-Mesh erforderlich sind.
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.comFühren Sie den folgenden Befehl aus, damit das Standarddienstkonto auf die Cloud Service Mesh Security API zugreifen kann:
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 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.
Erstellen Sie einen neuen Cluster, der die Identitätsföderation von Arbeitslasten für GKE verwendet. Wenn Sie einen vorhandenen Cluster aktualisieren, fahren Sie mit dem nächsten Schritt fort. Der Wert, den Sie für
--tagsangeben, muss mit dem Namen übereinstimmen, der an das Flag--target-tagsfür den Befehlfirewall-rules createim 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.
Wenn Sie einen vorhandenen Cluster verwenden, aktivieren Sie die Workload Identity Federation for GKE und GKE-Mesh-Zertifikate. Achten Sie darauf, dass der Cluster mit dem Flag
--enable-ip-aliaserstellt wurde, das nicht mit dem Befehlupdateverwendet werden kann.gcloud container clusters update CLUSTER_NAME \ --enable-mesh-certificates
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.
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: Der 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.
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
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
Weisen Sie den Personen, die einen CA-Pool und eine CA erstellen, die IAM-Rolle
roles/privateca.caManagerzu. 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
Weisen Sie die Rolle
role/privateca.adminfür CA Service Personen zu, die IAM-Richtlinien ändern müssen, wobeiMEMBEReine Person ist, die diesen Zugriff benötigt, insbesondere Personen, die die folgenden Schritte ausführen, welche die Rollenprivateca.auditorundprivateca.certificateManagergewähren:gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.admin
Erstellen Sie einen Stamm-CA-Service-Pool.
gcloud privateca pools create ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --tier enterprise
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"
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
Weisen Sie die IAM-Rolle
privateca.auditorfü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"
Weisen Sie der untergeordneten CA die IAM-Rolle
privateca.certificateManagerzu, 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"
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: 50Dabei 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
- Die Projekt-ID des Projekts, in dem der Cluster ausgeführt wird.
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_URIDabei 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
- Die Projekt-ID des Projekts, in dem der Cluster ausgeführt wird.
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 die PSM-Sicherheit benötigen Sie einen proxylosen gRPC-Server, der xDS nutzen kann, um die Sicherheitskonfiguration von Cloud Service Mesh zu übernehmen. 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 verwenden auch das benannte NEG-Feature, mit dem Sie einen Namen für die NEG festlegen 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
namein der Annotationcloud.google.com/negdes Dienstes, um den NEG-Namenexample-grpc-serverfestzulegen. - 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.jsonim gRPC-Servercontainerexample-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.pemist ein automatisch generierter privater Schlüssel.certificates.pemist ein Paket von PEM-formatierten Zertifikaten, die für einen anderen Pod als Clientzertifikatskette bereitgestellt oder als Serverzertifikatskette verwendet werden können.ca_certificates.pemist 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
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
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: - --config-mesh-experimental - "grpc-mesh" - --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++
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
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: - --config-mesh-experimental - "grpc-mesh" - --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
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
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: - --config-mesh-experimental - "grpc-mesh" - --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
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
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: - --config-mesh-experimental - "grpc-mesh" - --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 EOFSchließen Sie den Vorgang wie im Folgenden dargestellt ab:
Wenden Sie die Spezifikation an:
kubectl apply -f example-grpc-server.yaml
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.clientFü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
Prüfen Sie, ob der NEG-Name korrekt ist:
gcloud compute network-endpoint-groups list \ --filter "name=example-grpc-server" --format "value(name)"Der Befehl sollte den NEG-Namen
example-grpc-serverzurückgeben.
Cloud Service Mesh mit Google Cloud Load-Balancing-Komponenten konfigurieren
Die Schritte in diesem Abschnitt ähneln denen unter 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, sind keine gRPC-Systemdiagnosen möglich, da der Systemdiagnoseclient kein gültiges Clientzertifikat für die Server bereitstellen kann. 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.
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
Erstellen Sie die Firewall. Achten Sie darauf, dass der Wert von
--target-tagsmit dem Wert übereinstimmt, den Sie für--tagsim 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
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
Hängen Sie die NEG an den Back-End-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
Ressourcen Mesh und GRPCRoute erstellen
Dies ähnelt dem Einrichten der Mesh- und GRPCRoute-Ressourcen in Proxylose gRPC-Dienste einrichten.
Erstellen Sie die Spezifikation
Meshund speichern Sie sie in einer Datei mit dem Namenmesh.yaml.name: grpc-mesh
Importieren Sie die
Mesh-Ressource aus der Spezifikation.gcloud network-services meshes import grpc-mesh \ --source=mesh.yaml \ --location=global
Erstellen Sie die Spezifikation
GRPCRouteund speichern Sie sie in einer Datei mit dem Namengrpc_route.yaml.name: helloworld-grpc-route hostnames: - helloworld-gke:8000 meshes: - projects/PROJECT_NUMBER/locations/global/meshes/grpc-mesh rules: - action: destinations: - serviceName: projects/PROJECT_NUMBER/locations/global/backendServices/grpc-gke-helloworld-serviceImportieren Sie die
GRPCRoute-Ressource aus der Spezifikationgrpc_route.yaml.gcloud network-services grpc-routes import helloworld-grpc-route \ --source=grpc_route.yaml \ --location=global
Cloud Service Mesh mit proxylosem gRPC-Sicherheitsdienst 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 oder einem unterstützten Wert an. Die unterstützten Metadatenlabels finden Sie im Feld endpointMatcher.metadataLabelMatcher.metadataLabelMatchCriteria im NetworkServicesEndpointPolicy Document. 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.
Erstellen Sie im aktuellen Verzeichnis die temporäre Datei
server-mtls-policy.yamlmit 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_spiffeErstellen Sie eine Server-TLS-Richtlinienressource namens
server-mtls-policydurch Importieren der temporären Dateiserver-mtls-policy.yaml:gcloud network-security server-tls-policies import server-mtls-policy \ --source=server-mtls-policy.yaml --location=global
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: helloworldErstellen 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.
Erstellen Sie den Inhalt der clientseitigen TLS-Richtlinienressource in einer temporären Datei namens
client-mtls-policy.yamlim aktuellen Verzeichnis:name: "client-mtls-policy" clientCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe serverValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffeErstellen Sie die clientseitige TLS-Richtlinienressource mit dem Namen
client-mtls-policydurch Importieren der temporären Dateiclient-mtls-policy.yaml:gcloud network-security client-tls-policies import client-mtls-policy \ --source=client-mtls-policy.yaml --location=global
Erstellen Sie ein Snippet in einer temporären Datei, um auf diese Richtlinie zu verweisen, und fügen Sie Details für
subjectAltNamesin derSecuritySettings-Nachricht wie im folgenden Beispiel gezeigt hinzu. Ersetzen Sie dabei${PROJECT_ID}durch den Wert der Projekt-ID. Dies ist der Wert der oben erläuterten Umgebungsvariable${PROJECT_ID}. Beachten Sie, dassexample-grpc-serverinsubjectAltNamesder 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" EOFFügen Sie dem Back-End-Dienst, den Sie erstellt haben, die Nachricht
securitySettingshinzu. 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 von Cloud Service Mesh ist jetzt abgeschlossen. Sie enthält die server- und clientseitiger 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 entspricht dem vorherigen Schritt Proxylosen gRPC-Dienst mit NEGs 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. Mit der gRPC-Client-Kubernetes-Spezifikation wird dabei Folgendes ausgeführt:
- Es wird ein Kubernetes-Dienstkonto
example-grpc-clienterstellt, 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.pemist ein automatisch generierter privater Schlüssel.certificates.pemist ein Paket von PEM-formatierten Zertifikaten, die für einen anderen Pod als Clientzertifikatskette bereitgestellt oder als Serverzertifikatskette verwendet werden können.ca_certificates.pemist 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
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
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: - --config-mesh-experimental - "grpc-mesh" - --output - --config-mesh-experimental - "grpc-mesh" - "/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++
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
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: - --config-mesh-experimental - "grpc-mesh" - --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
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
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: - --config-mesh-experimental - "grpc-mesh" - --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
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
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: - --config-mesh-experimental - "grpc-mesh" - --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:
Wenden Sie die Spezifikation an:
kubectl apply -f example-grpc-client.yaml
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.clientPrü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
Rufen Sie den Namen des Pods ab, der für den Dienst
example-grpc-servererstellt 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
Stellen Sie eine Shell-Verbindung zum Server-Pod her:
kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/bash
Prüfen Sie in der Shell, ob die Bootstrap-Datei unter
/tmp/grpc-xds/td-grpc-bootstrap.jsonmit dem Schema wie im Abschnitt Bootstrap-Datei erläutert, übereinstimmt.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
Führen Sie den Server mit dem Flag
--xds-credsaus, um die xDS-fähige Sicherheit festzulegen. Verwenden Sie dabei50051als Überwachungsport undxds-serverals Serverkennung:./build/install/example-xds/bin/xds-hello-world-server --xds-creds 50051 xds-server
Wenn 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
C++
Rufen Sie den Namen des Pods ab, der für den Dienst
example-grpc-servererstellt 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
Stellen Sie eine Shell-Verbindung zum Server-Pod her:
kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/bash
Prüfen Sie in der Shell, ob die Bootstrap-Datei unter
/tmp/grpc-xds/td-grpc-bootstrap.jsonmit dem Schema übereinstimmt, das im Abschnitt Bootstrap-Datei erläutert wird.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_serverFühren Sie den Server mit
50051als Überwachungsport undxds_greeter_serverals 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
Wenn 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
Rufen Sie den Namen des Pods ab, der für den Dienst
example-grpc-servererstellt 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
Stellen Sie eine Shell-Verbindung zum Server-Pod her:
kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/bash
Prüfen Sie in der Shell, ob die Bootstrap-Datei unter
/tmp/grpc-xds/td-grpc-bootstrap.jsonmit dem Schema übereinstimmt, das im Abschnitt Bootstrap-Datei erläutert wird.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
Führen Sie den Server mit dem Flag
--xds-credsaus, um die xDS-fähige Sicherheit festzulegen. Verwenden Sie dazu50051als Überwachungsport.python3 server.py 50051 --xds-creds
Wenn 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
Rufen Sie den Namen des Pods ab, der für den Dienst
example-grpc-servererstellt 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
Stellen Sie eine Shell-Verbindung zum Server-Pod her:
kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/sh
Prüfen Sie in der Shell, ob die Bootstrap-Datei unter
/tmp/grpc-xds/td-grpc-bootstrap.jsonmit dem Schema übereinstimmt, das im Abschnitt Bootstrap-Datei erläutert wird.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
Erstellen Sie den Server und führen Sie ihn mit dem Flag
--xds_credsaus, um die xDS-fähige Sicherheit anzugeben. Verwenden Sie dabei50051als Überwachungsport:GRPC_GO_LOG_VERBOSITY_LEVEL=2 GRPC_GO_LOG_SEVERITY_LEVEL="info" \ go run main.go \ -xds_creds \ -port 50051
Wenn 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
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
Stellen Sie eine Shell-Verbindung zum Client-Pod her:
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
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
Führen Sie den Client mit dem Flag
--xds-credsaus, 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:8000Die Ausgabe sollte in etwa so aussehen:
Greeting: Hello xds-client, from xds-server
C++
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
Stellen Sie eine Shell-Verbindung zum Client-Pod her:
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
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-devcurl -L https://github.com/grpc/grpc/archive/master.tar.gz | tar -xz
cd grpc-master
tools/bazel build examples/cpp/helloworld:xds_greeter_client
Führen Sie den Client mit dem Flag
--xds-credsaus, 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
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
Stellen Sie eine Shell-Verbindung zum Client-Pod her:
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
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
Führen Sie den Client mit dem Flag
--xds-credsaus, 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
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
Stellen Sie eine Shell-Verbindung zum Client-Pod her:
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/sh
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
Erstellen Sie den Client und führen Sie ihn mit dem Flag
--xds_credsaus, um die xDS-fähige Sicherheit, den Clientnamen und den Zielverbindungsstring anzugeben:GRPC_GO_LOG_VERBOSITY_LEVEL=2 GRPC_GO_LOG_SEVERITY_LEVEL="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.
Aktualisieren Sie die
GRPCRoute-Spezifikation, die zuvor ingrpc_route.yamlgespeichert wurde.name: helloworld-grpc-route hostnames: - helloworld-gke:8000 - helloworld-gke-noaccess:8000 meshes: - projects/PROJECT_NUMBER/locations/global/meshes/grpc-mesh rules: - action: destinations: - serviceName: projects/PROJECT_NUMBER/locations/global/backendServices/grpc-gke-helloworld-serviceImportieren Sie die
GRPCRoute-Ressource noch einmal aus der Spezifikationgrpc_route.yaml.gcloud network-services grpc-routes import helloworld-grpc-route \ --source=grpc_route.yaml \ --location=global
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
Erstellen Sie eine Autorisierungsrichtlinie, indem Sie eine Datei mit dem Namen
helloworld-gke-authz-policy.yamlerstellen.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: - 50051Importieren Sie die Richtlinie:
gcloud network-security authorization-policies import \ helloworld-gke-authz-policy \ --source=helloworld-gke-authz-policy.yaml \ --location=global
Aktualisieren Sie die Endpunktrichtlinie so, dass sie auf die neue Autorisierungsrichtlinie verweist. Hängen Sie dazu Folgendes an die Datei
ep-mtls-psms.yamlan:authorizationPolicy: projects/${PROJECT_ID}/locations/global/authorizationPolicies/helloworld-gke-authz-policyDie 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:helloworldenthalten.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
Öffnen Sie eine Shell für den Client-Pod, den Sie zuvor verwendet haben.
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
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:8000Die Ausgabe sollte in etwa so aussehen:
Greeting: Hello xds-client, from xds-server
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:8000zulässt../build/install/example-xds/bin/xds-hello-world-client --xds-creds xds-client \ xds:///helloworld-gke-noaccess:8000Die 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
Öffnen Sie eine Shell für den Client-Pod, den Sie zuvor verwendet haben.
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
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_LEVEL="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
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:8000zulässt.GRPC_GO_LOG_VERBOSITY_LEVEL=2 GRPC_GO_LOG_SEVERITY_LEVEL="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 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.
TLS anstelle von mTLS verwenden
Die Verwendung von TLS in diesem Beispiel erfordert nur eine kleine Änderung.
Löschen Sie in
ServerTlsPolicydiemtlsPolicy:cat << EOF > server-tls-policy.yaml name: "server-tls-policy" serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe EOFVerwenden 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: [] EOFDie
ClientTlsPolicyfür mTLS funktioniert auch für TLS. Der AbschnittclientCertificateder 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:
- Klonen Sie das Repository und rufen Sie die Dateien im Verzeichnis der gRPC-Beispiele ab.
- Bearbeiten Sie die Datei
00-common-env.sh. Kommentieren Sie die vorhandene Zeile aus, die den Wert vonWALLET_DOCKER_IMAGEauf das Go-Docker-Image festlegt, und entfernen Sie die Kommentarzeichen in der Zeile, die den Wert vonWALLET_DOCKER_IMAGEauf das Java-Docker-Image festlegt. - Erstellen und konfigurieren Sie Cloud Router-Instanzen mithilfe der Anleitung unter Cloud Router-Instanzen erstellen und konfigurieren oder der Funktion
create_cloud_router_instancesim Skript10.apis.sh. - Erstellen Sie einen Cluster mit der Anleitung für das Beispiel
hello worldoder mit der Funktioncreate_clusterim Skript20-cluster.sh. - Erstellen Sie private Zertifizierungsstellen mithilfe der Anleitung für CA Service oder des Skripts
30-private-ca-setup.sh. - 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_v2mit dem Skript40-k8s-resources.sh. - Erstellen Sie für jeden von Ihnen erstellten Dienst eine Systemdiagnose und einen Backend-Dienst mit
create_health_checkundcreate_backend_serviceim Skript50-td-components.sh. - Erstellen Sie die Cloud Service Mesh-Routingkomponenten mit
create_routing_componentsim Skript60-routing-components.sh. - Erstellen Sie die Cloud Service Mesh-Sicherheitskomponenten für jeden Backend-Dienst mit
create_security_componentsim Skript70-security-components.sh. - Erstellen Sie die Bereitstellung des Wallet-Clients mit
create_client_deploymentim Skript75-client-deployment.sh. - 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:
- Klonen Sie das Repository und rufen Sie die Dateien im Verzeichnis der gRPC-Beispiele ab.
- Bearbeiten Sie die Datei
00-common-env.sh. Kommentieren Sie die vorhandene Zeile aus, die den Wert vonWALLET_DOCKER_IMAGEauf das Go-Docker-Image festlegt, und entfernen Sie die Kommentarzeichen in der Zeile, die den Wert vonWALLET_DOCKER_IMAGEauf das C++-Docker-Image festlegt. - Erstellen und konfigurieren Sie Cloud Router-Instanzen mithilfe der Anleitung unter Cloud Router-Instanzen erstellen und konfigurieren oder der Funktion
create_cloud_router_instancesim Skript10.apis.sh. - Erstellen Sie einen Cluster mit der Anleitung für das Beispiel
hello worldoder mit der Funktioncreate_clusterim Skript20-cluster.sh. - Erstellen Sie private Zertifizierungsstellen mithilfe der Anleitung für CA Service oder des Skripts
30-private-ca-setup.sh. - 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_v2mit dem Skript40-k8s-resources.sh. - Erstellen Sie für jeden von Ihnen erstellten Dienst eine Systemdiagnose und einen Backend-Dienst mit
create_health_checkundcreate_backend_serviceim Skript50-td-components.sh. - Erstellen Sie die Cloud Service Mesh-Routingkomponenten mit
create_routing_componentsim Skript60-routing-components.sh. - Erstellen Sie die Cloud Service Mesh-Sicherheitskomponenten für jeden Backend-Dienst mit
create_security_componentsim Skript70-security-components.sh. - Erstellen Sie die Bereitstellung des Wallet-Clients mit
create_client_deploymentim Skript75-client-deployment.sh. - 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:
- Klonen Sie das Repository und rufen Sie die Dateien im Verzeichnis der gRPC-Beispiele ab.
- Bearbeiten Sie die Datei
00-common-env.shund legen Sie die korrekten Werte für die Umgebungsvariablen fest. - Erstellen und konfigurieren Sie Cloud Router-Instanzen mithilfe der Anleitung unter Cloud Router-Instanzen erstellen und konfigurieren oder der Funktion
create_cloud_router_instancesim Skript10.apis.sh. - Erstellen Sie einen Cluster mit der Anleitung für das Beispiel
hello worldoder mit der Funktioncreate_clusterim Skript20-cluster.sh. - Erstellen Sie private Zertifizierungsstellen mithilfe der Anleitung für CA Service oder des Skripts
30-private-ca-setup.sh. - 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_v2mit dem Skript40-k8s-resources.sh. - Erstellen Sie für jeden von Ihnen erstellten Dienst eine Systemdiagnose und einen Backend-Dienst mit
create_health_checkundcreate_backend_serviceim Skript50-td-components.sh. - Erstellen Sie die Cloud Service Mesh-Routingkomponenten mit
create_routing_componentsim Skript60-routing-components.sh. - Erstellen Sie die Cloud Service Mesh-Sicherheitskomponenten für jeden Backend-Dienst mit
create_security_componentsim Skript70-security-components.sh. - Erstellen Sie die Bereitstellung des Wallet-Clients mit
create_client_deploymentim Skript75-client-deployment.sh. - 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. Im Folgenden sehen Sie ein Beispiel für eine Bootstrap-Datei:
{
"xds_servers": [
{
"server_uri": "trafficdirector.googleapis.com:443",
"channel_creds": [
{
"type": "google_default"
}
],
"server_features": [
"xds_v3"
]
}
],
"authorities": {
"traffic-director-c2p.xds.googleapis.com": {
"xds_servers": [
{
"server_uri": "dns:///directpath-pa.googleapis.com",
"channel_creds": [
{
"type": "google_default"
}
],
"server_features": [
"xds_v3",
"ignore_resource_deletion"
]
}
],
"client_listener_resource_name_template": "xdstp://traffic-director-c2p.xds.googleapis.com/envoy.config.listener.v3.Listener/%s"
}
},
"node": {
"id": "projects/9876012345/networks/mesh:grpc-mesh/nodes/b59f49cc-d95a-4462-9126-112f794d5dd3",
"cluster": "cluster",
"metadata": {
"INSTANCE_IP": "10.28.2.8",
"TRAFFICDIRECTOR_DIRECTPATH_C2P_IPV6_CAPABLE": true,
"TRAFFICDIRECTOR_GCP_PROJECT_NUMBER": "223606568246",
"TRAFFICDIRECTOR_NETWORK_NAME": "default",
"app": "helloworld"
},
"locality": {
"zone": "us-central1-c"
}
},
"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"
}
}
},
"server_listener_resource_name_template": "grpc/server?xds.resource.listening_address=%s"
}
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 stellt eine eindeutige Identität des gRPC-Clients für Cloud Service Mesh bereit. 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 |
Für gRPC-Server erforderlich. gRPC verwendet diesen Wert, um den Ressourcennamen zum Abrufen der Überwachungsressource aus Cloud Service Mesh für die serverseitige Sicherheitskonfiguration und andere Konfigurationen zu erstellen. gRPC nutzt den Wert, um daraus 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:
|
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.jsondie Bootstrap-Datei in/tmp/bootstrap/td-grpc-bootstrap.jsonim Dateisystem des Pods.--config-mesh-experimental: Mit dieser Option können Sie den Mesh-Namen angeben, der derMesh-Ressource entspricht.--node-metadata: Mit diesem Flag geben Sie den Inhalt der Knotenmetadaten in der Bootstrap-Datei an. Dies ist erforderlich, wenn Sie Metadaten-Label-Matcher in derEndpointPolicyverwenden. Dabei nutzt Cloud Service Mesh die Labeldaten aus dem Abschnitt der Knotenmetadaten der Bootstrap-Datei. Das Argument wird im Format "Schlüssel=Wert" angegeben, z. B.--node-metadata version=prod --node-metadata type=grpc.
Damit wird im Knotenmetadatenabschnitt der Bootstrap-Datei Folgendes hinzugefügt:
{
"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
gcloud 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 die Konfiguration nicht von 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-platformerstellt. - Sie haben Ihren Kubernetes-Dienstkonten
roles/trafficdirector.clientzugewiesen. - Sie haben Ihrem Standarddienstkonto für Google Cloud (${GSA_EMAIL} oben)
roles/trafficdirector.clientzugewiesen. - Sie haben den Dienst
trafficdirector.googleapis.com(API) aktiviert.
Ihr gRPC-Server verwendet TLS/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.
- 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:
- Sie verwenden Anmeldedaten in Klartextform auf Client- und Serverseite ODER
- Sie legen keine Sicherheit für den Back-End-Dienst und die Endpunktrichtlinie in der Cloud Service Mesh-Konfiguration fest.
Folgen Sie der Anleitung unter Fehlerbehebung bei proxylosen Cloud Service Mesh-Deployments, da in Ihrem Deployment keine Sicherheitseinrichtung vorhanden ist.
Ändern Sie Ihre Arbeitslasten so, dass sie xDS-Anmeldedaten im Klartext oder unsichere Anmeldedaten als Fallback-Anmeldedaten verwenden. Übernehmen Sie die Cloud Service Mesh-Konfiguration mit deaktivierter Sicherheit wie oben erläutert. Obwohl es in diesem Fall gRPC zulässt, dass Cloud Service Mesh die Sicherheit konfiguriert, sendet Cloud Service Mesh keine Sicherheitsinformationen. In diesem Fall sollte gRPC als Fallback auf Klartext- (oder unsichere) -Anmeldedaten zurückgreifen, die wie im ersten Fall oben funktionieren sollten. Wenn dies nicht funktioniert, gehen Sie so vor:
- 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.
- 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.
- 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.
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.Aktivieren Sie TLS (anstelle von mTLS) in Ihrem Service Mesh wie oben erläutert und starten Sie Ihre Client- und Serverarbeitslasten neu.
- 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.
- 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_POOList der Arbeitslastpool für den Cluster, in diesem Fall${PROJECT_ID}.svc.id.goog.K8S_NAMESPACEist der Kubernetes-Namespace, den Sie für das Deployment des Dienstes verwendet haben.SERVICE_ACCOUNTist 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:
Prüfen Sie, ob die Pod-Spezifikation die Annotation
security.cloud.google.com/use-workload-certificatesenthält, die unter Proxylosen gRPC-Dienst mit NEGs erstellen beschrieben wird.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:
- Zertifikatskette in Verbindung mit Blattzertifikat: "/var/run/secrets/workload-spiffe-credentials/certificates.pem"
- Privater Schlüssel: "/var/run/secrets/workload-spiffe-credentials/private_key.pem"
- CA-Paket: "/var/run/secrets/workload-spiffe-credentials/ca_certificates.pem"
Wenn die Zertifikate aus dem vorherigen Schritt nicht verfügbar sind, gehen Sie so vor:
gcloud privateca subordinates describe SUBORDINATE_CA_POOL_NAME
--location=LOCATIONPrü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.
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"
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
Prüfen Sie, ob Ihre gRPC-Java-Anwendung in der YAML-Datei
WorkloadCertificateConfigden folgendenkeyAlgorithmenthält:
keyAlgorithm: rsa: modulusSize: 4096Prü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
- Prüfen Sie, ob die Peer-Anwendung das gleiche Vertrauens-Bundle verwendet, um das Zertifikat zu prüfen.
- 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:
WorkloadCertificateConfigoderTrustConfigist 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.
Prüfen Sie den Status Ihres Pods:
kubectl get pod -n POD_NAMESPACE POD_NAMEDabei gilt:
POD_NAMESPACE: der Namespace Ihres Pods.POD_NAME: der Name Ihres Pods.
Prüfen Sie die letzten Ereignisse für den Pod:
kubectl describe pod -n POD_NAMESPACE POD_NAMEWenn die Bereitstellung von Zertifikaten fehlschlägt, wird ein Ereignis mit
Type=Warning,Reason=FailedMount,From=kubeletund mit einemMessage-Feld angezeigt, das mitMountVolume.SetUp failed for volume "gke-workload-certificates"beginnt. Das FeldMessageenthä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)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.
Rufen Sie den aktuellen Status ab.
Für
WorkloadCertificateConfig:kubectl get WorkloadCertificateConfig default -o yamlFür
TrustConfig:kubectl get TrustConfig default -o yamlPrüfen Sie die Statusausgabe. Ein gültiges Objekt hat eine Bedingung mit
type: Readyundstatus: "True".status: conditions: - lastTransitionTime: "2021-03-04T22:24:11Z" message: WorkloadCertificateConfig is ready observedGeneration: 1 reason: ConfigReady status: "True" type: ReadyBei ungültigen Objekten wird stattdessen
status: "False"angezeigt. Die Felderreasonundmessageenthalten 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.
Listen Sie die relevanten CSRs mithilfe von
kubectlauf:kubectl get csr \ --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'Wählen Sie eine CSR aus, für die entweder
Approvedund nichtIssuedgilt oder für dieApprovednicht gilt.Rufen Sie mithilfe von kubectl Details zur ausgewählten CSR ab:
kubectl get csr CSR_NAME -o yamlErsetzen Sie
CSR_NAMEdurch 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
Rufen Sie die Pod-Spezifikation für Ihren Pod ab:
kubectl get pod -n POD_NAMESPACE POD_NAME -o yamlDabei gilt:
POD_NAMESPACE: der Namespace Ihres Pods.POD_NAME: der Name Ihres Pods.
Prüfen Sie, ob die Pod-Spezifikation die Annotation
security.cloud.google.com/use-workload-certificatesenthält, die unter Pods für den Empfang von mTLS-Anmeldedaten konfigurieren beschrieben wird.Prüfen Sie, ob der Admission-Controller für GKE-Mesh-Zertifikate erfolgreich ein CSI-Treiber-Volume vom Typ
workloadcertificates.security.cloud.google.comin Ihre Pod-Spezifikation eingefügt hat:volumes: ... -csi: driver: workloadcertificates.security.cloud.google.com name: gke-workload-certificates ...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 ...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
- Zertifikatsketten-Bundle:
Wenn die Dateien nicht verfügbar sind, gehen Sie so vor:
Rufen Sie die CA Service-Instanz (Vorschau) für den Cluster ab:
kubectl get workloadcertificateconfigs default -o jsonpath '{.spec.certificateAuthorityConfig.certificateAuthorityServiceConfig.endpointURI}'Rufen Sie den Status der CA Service-Instanz (Vorschau) ab:
gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \ --location ISSUING_CA_LOCATIONDabei gilt:
ISSUING_CA_TYPE: der ausstellende CA-Typ, der entwedersubordinatesoderrootssein muss.ISSUING_CA_NAME: der Name der ausstellenden CA.ISSUING_CA_LOCATION: die Region der ausstellenden Zertifizierungsstelle.
Rufen Sie die IAM-Richtlinie für die Stamm-CA ab:
gcloud privateca roots get-iam-policy ROOT_CA_NAMEErsetzen Sie
ROOT_CA_NAMEdurch den Namen Ihrer Stammzertifizierungsstelle.Prüfen Sie in der IAM-Richtlinie, ob die Richtlinienbindung
privateca.auditorvorhanden ist:... - members: - serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com role: roles/privateca.auditor ...In diesem Beispiel ist
PROJECT_NUMBERdie Projektnummer Ihres Clusters.Rufen Sie die IAM-Richtlinie für die untergeordnete Zertifizierungsstelle ab:
gcloud privateca subordinates get-iam-policy SUBORDINATE_CA_NAMEErsetzen Sie
SUBORDINATE_CA_NAMEdurch den Namen der untergeordneten CA.Prüfen Sie in der IAM-Richtlinie, ob die Richtlinienbindung
privateca.certificateManagervorhanden ist:... - members: - serviceAccount: service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com role: roles/privateca.certificateManager ...In diesem Beispiel ist
PROJECT_NUMBERdie Projektnummer Ihres Clusters.
Anwendungen können die ausgegebenen mTLS-Anmeldedaten nicht verwenden
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"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 3Prüfen Sie, ob die ausstellende Zertifizierungsstelle die gleiche Schlüsselfamilie wie der Zertifikatschlüssel verwendet.
Rufen Sie den Status der CA Service-Instanz (Vorschau) ab:
gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \ --location ISSUING_CA_LOCATIONDabei gilt:
ISSUING_CA_TYPE: der ausstellende CA-Typ, der entwedersubordinatesoderrootssein muss.ISSUING_CA_NAME: der Name der ausstellenden CA.ISSUING_CA_LOCATION: die Region der ausstellenden Zertifizierungsstelle.
Prüfen Sie, ob der
keySpec.algorithmin der Ausgabe der gleiche Schlüsselalgorithmus ist wie der, den Sie im YAML-ManifestWorkloadCertificateConfigdefiniert 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
- Prüfen Sie, ob die Peer-Anwendung dasselbe Vertrauens-Bundle verwendet, um das Zertifikat zu verifizieren.
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"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.
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 Dienstsicherheit von Cloud Service Mesh wird nur mit GKE unterstützt. Sie können die Dienstsicherheit nicht mit 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 aus einer der in Konflikt stehenden Richtlinien.