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- und Google 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 auf diese Ressourcen in der Backend-Dienstressource 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 Verbesserungen bei der 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 GKE Workload Identity Federation for 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.com
Fü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-Diensten hängt von der CA Service-Einbindung in GKE ab. Der GKE-Cluster muss zusätzlich zu den Anforderungen für die Einrichtung die folgenden Anforderungen erfüllen:
- Verwenden Sie eine Mindestclusterversion von 1.21.4-gke.1801. Wenn Sie Funktionen einer späteren Version benötigen, können Sie diese Version über den Rapid Release Channel abrufen.
- Der GKE-Cluster muss mit Mesh-Zertifikaten aktiviert und konfiguriert sein, wie unter Zertifizierungsstellen zum Ausstellen von Zertifikaten erstellen erläutert.
Erstellen Sie einen neuen Cluster, der die Workload Identity Federation for GKE verwendet. Wenn Sie einen vorhandenen Cluster aktualisieren, fahren Sie mit dem nächsten Schritt fort. Der Wert, den Sie für
--tags
angeben, muss mit dem Namen übereinstimmen, der an das Flag--target-tags
für den Befehlfirewall-rules create
im Abschnitt Cloud Service Mesh mit Cloud Load Balancing-Komponenten konfigurieren übergeben wurde.# Create a GKE cluster with GKE managed mesh certificates. gcloud container clusters create CLUSTER_NAME \ --release-channel=rapid \ --scopes=cloud-platform \ --image-type=cos_containerd \ --machine-type=e2-standard-2 \ --zone=ZONE \ --workload-pool=PROJECT_ID.svc.id.goog \ --enable-mesh-certificates \ --cluster-version=CLUSTER_VERSION \ --enable-ip-alias \ --tags=allow-health-checks \ --workload-metadata=GKE_METADATA
Die Erstellung eines Clusters kann einige Minuten dauern.
Wenn Sie einen vorhandenen Cluster verwenden, aktivieren Sie die Identitätsföderation von Arbeitslasten für GKE und GKE-Mesh-Zertifikate. Achten Sie darauf, dass der Cluster mit dem Flag
--enable-ip-alias
erstellt wurde, das nicht mit dem Befehlupdate
verwendet 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.caManager
zu. Beachten Sie, dass für MEMBER das korrekte Format so lautet:user:userid@example.com
. Wenn diese Person der aktuelle Nutzer ist, können Sie die aktuelle Nutzer-ID mit dem Shell-Befehl$(gcloud auth list --filter=status:ACTIVE --format="value(account)")
abrufen.gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.caManager
Weisen Sie die Rolle
role/privateca.admin
für CA Service Personen zu, die IAM-Richtlinien ändern müssen, wobeiMEMBER
eine Person ist, die diesen Zugriff benötigt, insbesondere Personen, die die folgenden Schritte ausführen, welche die Rollenprivateca.auditor
undprivateca.certificateManager
gewä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.auditor
für die Stamm-CA zu, um den Zugriff vom GKE-Dienstkonto zuzulassen:gcloud privateca pools add-iam-policy-binding ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --role roles/privateca.auditor \ --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
Weisen Sie der untergeordneten CA die IAM-Rolle
privateca.certificateManager
zu, um den Zugriff vom GKE-Dienstkonto zuzulassen:gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --role roles/privateca.certificateManager \ --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
Speichern Sie die folgende
WorkloadCertificateConfig
-YAML-Konfiguration, um für Ihren Cluster festzulegen, wie Mesh-Zertifikate ausgegeben werden:apiVersion: security.cloud.google.com/v1 kind: WorkloadCertificateConfig metadata: name: default spec: # Required. The CA service that issues your certificates. certificateAuthorityConfig: certificateAuthorityServiceConfig: endpointURI: ISSUING_CA_POOL_URI # Required. The key algorithm to use. Choice of RSA or ECDSA. # # To maximize compatibility with various TLS stacks, your workloads # should use keys of the same family as your root and subordinate CAs. # # To use RSA, specify configuration such as: # keyAlgorithm: # rsa: # modulusSize: 4096 # # Currently, the only supported ECDSA curves are "P256" and "P384", and the only # supported RSA modulus sizes are 2048, 3072 and 4096. keyAlgorithm: rsa: modulusSize: 4096 # Optional. Validity duration of issued certificates, in seconds. # # Defaults to 86400 (1 day) if not specified. validityDurationSeconds: 86400 # Optional. Try to start rotating the certificate once this # percentage of validityDurationSeconds is remaining. # # Defaults to 50 if not specified. rotationWindowPercentage: 50
Dabei gilt:
- Die Projekt-ID des Projekts, in dem der Cluster ausgeführt wird.
PROJECT_ID
- Der voll qualifizierte URI der Zertifizierungsstelle, die Ihre Mesh-Zertifikate ausstellt (ISSUING_CA_POOL_URI). Dies kann entweder die untergeordnete CA (empfohlen) oder die Stamm-CA sein. Das Format dafür ist:
//privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_POOL_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
- 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_URI
Dabei gilt:
- Die Projekt-ID des Projekts, in dem der Cluster ausgeführt wird.
PROJECT_ID
- Der vollständig qualifizierte URI des Stamm-CA-Pools (ROOT_CA_POOL_URI). Das Format lautet:
//privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
- 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
name
in der Annotationcloud.google.com/neg
des Dienstes, um den NEG-Namenexample-grpc-server
festzulegen. - Die Variable
${PROJNUM}
steht für die Projektnummer Ihres Projekts. - Die Spezifikation verwendet den Abschnitt
initContainers
, um einen Bootstrap-Generator auszuführen, der den Inhalt der Bootstrap-Datei erstellt, die die proxylose gRPC-Bibliothek benötigt. Diese Bootstrap-Datei befindet sich unter/tmp/grpc-xds/td-grpc-bootstrap.json
im gRPC-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.pem
ist ein automatisch generierter privater Schlüssel.certificates.pem
ist ein Paket von PEM-formatierten Zertifikaten, die für einen anderen Pod als Clientzertifikatskette bereitgestellt oder als Serverzertifikatskette verwendet werden können.ca_certificates.pem
ist ein Paket aus PEM-formatierten Zertifikaten. Diese können als Trust-Anchors verwendet werden, wenn Sie die von einem anderen Pod bereitgestellte Clientzertifikatskette oder die Serverzertifikatskette prüfen, die beim Herstellen der Verbindung zu einem anderen Pod empfangen wurde.
Beachten Sie, dass ca_certificates.pem
Zertifikate für die lokale vertrauenswürdige Domain der Arbeitslasten enthält, also für den Arbeitslastpool des Clusters.
Das Blattzertifikat in certificates.pem
enthält die folgende SPIFFE-Identitätsbestätigung in Nur-Text:
spiffe://WORKLOAD_POOL/ns/NAMESPACE/sa/KUBERNETES_SERVICE_ACCOUNT
Für diese Bestätigung gilt Folgendes:
- WORKLOAD_POOL ist der Name des Clusterarbeitslastpools.
- NAMESPACE ist der Namespace Ihres Kubernetes-Dienstkontos.
- KUBERNETES_SERVICE_ACCOUNT ist der Name Ihres Kubernetes-Dienstkontos.
Mit der folgenden Anleitung für Ihre Sprache erstellen Sie die Spezifikation für dieses Beispiel.
Java
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 EOF
Schließ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.client
Führen Sie die folgenden Befehle aus, um zu prüfen, ob der Dienst und der Pod ordnungsgemäß erstellt wurden:
kubectl get deploy/example-grpc-server kubectl get svc/example-grpc-server
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-server
zurü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-tags
mit dem Wert übereinstimmt, den Sie für--tags
im Abschnitt GKE-Cluster erstellen oder aktualisieren festgelegt haben.gcloud compute firewall-rules create grpc-gke-allow-health-checks \ --network default --action allow --direction INGRESS \ --source-ranges 35.191.0.0/16,130.211.0.0/22 \ --target-tags allow-health-checks \ --rules tcp:50051-50052
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
Das entspricht dem Einrichten der Mesh
- und GRPCRoute
-Ressourcen unter Proxylose gRPC-Dienste einrichten.
Erstellen Sie die Spezifikation
Mesh
und 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
GRPCRoute
und 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-service
Importieren Sie die
GRPCRoute
-Ressource aus dergrpc_route.yaml
-Spezifikation.gcloud network-services grpc-routes import helloworld-grpc-route \ --source=grpc_route.yaml \ --location=global
Cloud Service Mesh mit proxyloser gRPC-Sicherheit 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 Dokument „NetworkServicesEndpointPolicy“. 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.yaml
mit den Werten der TLS-Richtlinienressource des Servers:name: "projects/PROJECT_ID/locations/global/serverTlsPolicies/server-mtls-policy" serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe mtlsPolicy: clientValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffe
Erstellen Sie eine Server-TLS-Richtlinienressource namens
server-mtls-policy
durch 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: helloworld
Erstellen Sie die Endpunktrichtlinienressource. Importieren Sie dazu die Datei
ep-mtls-psms.yaml
:gcloud beta network-services endpoint-policies import ep-mtls-psms \ --source=ep-mtls-psms.yaml --location=global
mTLS clientseitig konfigurieren
Die clientseitige Sicherheitsrichtlinie wird an den Backend-Dienst angehängt. Wenn ein Client über den Back-End-Dienst auf ein Back-End (den gRPC-Server) zugreift, wird die angehängte clientseitige Sicherheitsrichtlinie an den Client gesendet.
Erstellen Sie den Inhalt der clientseitigen TLS-Richtlinienressource in einer temporären Datei namens
client-mtls-policy.yaml
im aktuellen Verzeichnis:name: "client-mtls-policy" clientCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe serverValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffe
Erstellen Sie die clientseitige TLS-Richtlinienressource mit dem Namen
client-mtls-policy
durch 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
subjectAltNames
in 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-server
insubjectAltNames
der Name des Kubernetes-Dienstkontos ist, der in der Deployment-Spezifikation für den gRPC-Server-Pod verwendet wird.if [ -z "$PROJECT_ID" ] ; then echo Please make sure PROJECT_ID is set. ; fi cat << EOF > client-security-settings.yaml securitySettings: clientTlsPolicy: projects/${PROJECT_ID}/locations/global/clientTlsPolicies/client-mtls-policy subjectAltNames: - "spiffe://${PROJECT_ID}.svc.id.goog/ns/default/sa/example-grpc-server" EOF
Fügen Sie dem Back-End-Dienst, den Sie erstellt haben, die Nachricht
securitySettings
hinzu. Mit diesen Schritten werden der aktuelle Inhalt des Backend-Dienstes exportiert, die Client-securitySetting
-Nachricht hinzugefügt und der neue Inhalt zurückimportiert, um den Backend-Dienst zu aktualisieren.gcloud compute backend-services export grpc-gke-helloworld-service --global \ --destination=/tmp/grpc-gke-helloworld-service.yaml cat /tmp/grpc-gke-helloworld-service.yaml client-security-settings.yaml \ >/tmp/grpc-gke-helloworld-service1.yaml gcloud compute backend-services import grpc-gke-helloworld-service --global \ --source=/tmp/grpc-gke-helloworld-service1.yaml -q
Konfiguration prüfen
Die Konfiguration von Cloud Service Mesh ist jetzt abgeschlossen. Sie enthält die server- und clientseitige Sicherheit. Als Nächstes bereiten Sie die Server- und Clientarbeitslasten vor und führen sie aus. Damit ist das Beispiel abgeschlossen.
Proxylosen gRPC-Client erstellen
Dieser Schritt entspricht dem vorherigen Schritt Proxylosen gRPC-Dienst erstellen.
Sie verwenden den xDS-fähigen helloworld
-Client aus dem xDS-Beispielverzeichnis im grpc-java
-Repository. Sie erstellen den Client und führen ihn in einem Container aus, der aus einem openjdk:8-jdk
-Image erstellt wurde. Mit der gRPC-Client-Kubernetes-Spezifikation wird dabei Folgendes ausgeführt:
- Es wird ein Kubernetes-Dienstkonto
example-grpc-client
erstellt, das vom gRPC-Client-Pod verwendet wird. ${PROJNUM}
steht für die Projektnummer Ihres Projekts und muss durch die tatsächliche Nummer ersetzt werden.
Fügen Sie der Pod-Spezifikation die folgende Annotation hinzu:
annotations: security.cloud.google.com/use-workload-certificates: ""
Bei der Erstellung erhält jeder Pod ein Volume unter /var/run/secrets/workload-spiffe-credentials
.
Dieses Volume enthält Folgendes:
private_key.pem
ist ein automatisch generierter privater Schlüssel.certificates.pem
ist ein Paket von PEM-formatierten Zertifikaten, die für einen anderen Pod als Clientzertifikatskette bereitgestellt oder als Serverzertifikatskette verwendet werden können.ca_certificates.pem
ist ein Paket aus PEM-formatierten Zertifikaten. Diese können als Trust-Anchors verwendet werden, wenn Sie die von einem anderen Pod bereitgestellte Clientzertifikatskette oder die Serverzertifikatskette prüfen, die beim Herstellen der Verbindung zu einem anderen Pod empfangen wurde.
Beachten Sie, dass ca_certificates.pem
die Root-Zertifikate der lokalen Vertrauensdomain für die Arbeitslasten enthält, also für den Arbeitslastpool des Clusters.
Das Blattzertifikat in certificates.pem
enthält die folgende SPIFFE-Identitätsbestätigung in Nur-Text:
spiffe://WORKLOAD_POOL/ns/NAMESPACE/sa/KUBERNETES_SERVICE_ACCOUNT
Für diese Bestätigung gilt Folgendes:
- WORKLOAD_POOL ist der Name des Clusterarbeitslastpools.
- NAMESPACE ist der Name Ihres Kubernetes-Dienstkontos.
- KUBERNETES_SERVICE_ACCOUNT ist der Namespace Ihres Kubernetes-Dienstkontos.
Mit der folgenden Anleitung für Ihre Sprache erstellen Sie die Spezifikation für dieses Beispiel.
Java
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.client
Prüfen Sie, ob der Client-Pod ausgeführt wird:
kubectl get pods
Der Ausgabetext des Befehls sieht in etwa so aus:
NAMESPACE NAME READY STATUS RESTARTS AGE default example-grpc-client-7c969bb997-9fzjv 1/1 Running 0 104s [..skip..]
Server ausführen
Erstellen den xDS-fähigen helloworld
-Server und führen Sie ihn im zuvor erstellten Server-Pod aus.
Java
Rufen Sie den Namen des Pods ab, der für den Dienst
example-grpc-server
erstellt wurde:kubectl get pods | grep example-grpc-server
Es wird daraufhin in etwa Folgendes angezeigt:
default example-grpc-server-77548868d-l9hmf 1/1 Running 0 105s
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.json
mit 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-creds
aus, um die xDS-fähige Sicherheit festzulegen. Verwenden Sie dabei50051
als Überwachungsport undxds-server
als Serverkennung:./build/install/example-xds/bin/xds-hello-world-server --xds-creds 50051 xds-server
Nachdem der Server die erforderliche Konfiguration von Cloud Service Mesh abgerufen hat, wird Folgendes ausgegeben:
Listening on port 50051 plain text health service listening on port 50052
C++
Rufen Sie den Namen des Pods ab, der für den Dienst
example-grpc-server
erstellt wurde:kubectl get pods | grep example-grpc-server
Es wird daraufhin in etwa Folgendes angezeigt:
default example-grpc-server-77548868d-l9hmf 1/1 Running 0 105s
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.json
mit 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_server
Führen Sie den Server mit
50051
als Überwachungsport undxds_greeter_server
als Serverkennung aus:bazel-bin/examples/cpp/helloworld/xds_greeter_server --port=50051 --maintenance_port=50052 --secure
Um den Server ohne Anmeldedaten auszuführen, geben Sie Folgendes an:
bazel-bin/examples/cpp/helloworld/xds_greeter_server --nosecure
Nachdem der Server die erforderliche Konfiguration von Cloud Service Mesh abgerufen hat, wird Folgendes ausgegeben:
Listening on port 50051 plain text health service listening on port 50052
Python
Rufen Sie den Namen des Pods ab, der für den Dienst
example-grpc-server
erstellt wurde:kubectl get pods | grep example-grpc-server
Es wird daraufhin in etwa Folgendes angezeigt:
default example-grpc-server-77548868d-l9hmf 1/1 Running 0 105s
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.json
mit 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-creds
aus, um die xDS-fähige Sicherheit festzulegen. Verwenden Sie dazu50051
als Überwachungsport.python3 server.py 50051 --xds-creds
Nachdem der Server die erforderliche Konfiguration von Cloud Service Mesh abgerufen hat, wird Folgendes ausgegeben:
2021-05-06 16:10:34,042: INFO Running with xDS Server credentials 2021-05-06 16:10:34,043: INFO Greeter server listening on port 50051 2021-05-06 16:10:34,046: INFO Maintenance server listening on port 50052
Go
Rufen Sie den Namen des Pods ab, der für den Dienst
example-grpc-server
erstellt wurde:kubectl get pods | grep example-grpc-server
Es wird daraufhin in etwa Folgendes angezeigt:
default example-grpc-server-77548868d-l9hmf 1/1 Running 0 105s
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.json
mit 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_creds
aus, um die xDS-fähige Sicherheit anzugeben. Verwenden Sie dabei50051
als Überwachungsport:GRPC_GO_LOG_VERBOSITY_LEVEL=2 GRPC_GO_LOG_SEVERITY_LEVEL="info" \ go run main.go \ -xds_creds \ -port 50051
Nachdem der Server die erforderliche Konfiguration von Cloud Service Mesh abgerufen hat, wird Folgendes ausgegeben:
Using xDS credentials... Serving GreeterService on 0.0.0.0:50051 and HealthService on 0.0.0.0:50052
Der Systemdiagnoseprozess benötigt drei bis fünf Minuten, um zu zeigen, dass Ihr Dienst nach dem Serverstart fehlerfrei ist.
Client ausführen und Konfiguration prüfen
Erstellen Sie den xDS-fähigen helloworld
-Client und führen Sie ihn im zuvor erstellten Client-Pod aus.
Java
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-creds
aus, um die xDS-fähige Sicherheit, den Clientnamen und den Zielverbindungsstring anzugeben:./build/install/example-xds/bin/xds-hello-world-client --xds-creds xds-client \ xds:///helloworld-gke:8000
Die Ausgabe sollte in etwa so aussehen:
Greeting: Hello xds-client, from xds-server
C++
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-dev
curl -L https://github.com/grpc/grpc/archive/master.tar.gz | tar -xz
cd grpc-master
tools/bazel build examples/cpp/helloworld:xds_greeter_client
Führen Sie den Client mit dem Flag
--xds-creds
aus, um die xDS-fähige Sicherheit, den Clientnamen und den Zielverbindungsstring anzugeben:bazel-bin/examples/cpp/helloworld/xds_greeter_client --target=xds:///helloworld-gke:8000
Um den Client ohne Anmeldedaten auszuführen, führen Sie folgenden Befehl aus:
bazel-bin/examples/cpp/helloworld/xds_greeter_client --target=xds:///helloworld-gke:8000 --nosecure
Die Ausgabe sollte in etwa so aussehen:
Greeter received: Hello world
Python
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-creds
aus, um die xDS-fähige Sicherheit, den Clientnamen und den Zielverbindungsstring anzugeben:python3 client.py xds:///helloworld-gke:8000 --xds-creds
Die Ausgabe sollte in etwa so aussehen:
Greeter client received: Hello you from example-host!
Go
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_creds
aus, 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.
GRPCRoute
-Spezifikation aktualisieren, die zuvor ingrpc_route.yaml
gespeichert wurdename: 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-service
Importieren Sie die
GRPCRoute
-Ressource noch einmal aus dergrpc_route.yaml
-Spezifikation.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.yaml
erstellen.action: ALLOW name: helloworld-gke-authz-policy rules: - sources: - principals: - spiffe://PROJECT_ID.svc.id.goog/ns/default/sa/example-grpc-client destinations: - hosts: - helloworld-gke:8000 ports: - 50051
Importieren 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.yaml
an:authorizationPolicy: projects/${PROJECT_ID}/locations/global/authorizationPolicies/helloworld-gke-authz-policy
Die Endpunktrichtlinie gibt jetzt an, dass sowohl mTLS als auch die Autorisierungsrichtlinie für eingehende Anfragen an Pods erzwungen werden müssen, deren gRPC-Bootstrap-Dateien das Label
app:helloworld
enthalten.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:8000
Die 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:8000
zulässt../build/install/example-xds/bin/xds-hello-world-client --xds-creds xds-client \ xds:///helloworld-gke-noaccess:8000
Die Ausgabe sollte in etwa so aussehen:
WARNING: RPC failed: Status{code=PERMISSION_DENIED}
Wenn diese Ausgabe nicht angezeigt wird, wird die Autorisierungsrichtlinie möglicherweise noch nicht verwendet. Warten Sie einige Minuten und versuchen Sie es noch einmal mit der Überprüfung.
Go
Ö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:8000
zulä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
ServerTlsPolicy
diemtlsPolicy
:cat << EOF > server-tls-policy.yaml name: "server-tls-policy" serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe EOF
Verwenden Sie diese Richtlinie stattdessen in der Datei
EndpointPolicy
:cat << EOF > ep-tls-psms.yaml name: "ep-mtls-psms" type: "GRPC_SERVER" serverTlsPolicy: "projects/${PROJECT_ID}/locations/global/serverTlsPolicies/server-tls-policy" trafficPortSelector: ports: - "50051" endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: "MATCH_ALL" metadataLabels: [] EOF
Die
ClientTlsPolicy
für mTLS funktioniert auch für TLS. Der AbschnittclientCertificate
der Richtlinie kann aber entfernt werden, da er für TLS nicht erforderlich ist:cat << EOF > client-tls-policy.yaml name: "client-tls-policy" serverValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffe EOF
Dienstsicherheit mit dem Wallet-Beispiel nutzen
Dieser Abschnitt bietet eine allgemeine Übersicht, in der gezeigt wird, wie Sie das Wallet-Beispiel mit der Dienstsicherheit für Java, C++ und Go aktivieren.
Java
Den Beispielquellcode für Java finden Sie auf github.
Der Code verwendet bereits die XdsChannel
- und XdsServer
-Anmeldedaten, wenn Sie die proxylose Sicherheit konfigurieren.
Diese Anleitung beschreibt die Konfiguration des Wallet-Beispiels mit Go. Der Vorgang ist bei Java ähnlich. In der Anleitung wird ein bereits vorhandenes Docker-Image verwendet, das Sie aus dem Google Cloud-Container-Repository abrufen.
So erstellen Sie das Beispiel:
- 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_IMAGE
auf das Go-Docker-Image festlegt, und entfernen Sie die Kommentarzeichen in der Zeile, die den Wert vonWALLET_DOCKER_IMAGE
auf 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_instances
im Skript10.apis.sh
. - Erstellen Sie einen Cluster mit der Anleitung für das Beispiel
hello world
oder mit der Funktioncreate_cluster
im 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_v2
mit dem Skript40-k8s-resources.sh
. - Erstellen Sie für jeden von Ihnen erstellten Dienst eine Systemdiagnose und einen Backend-Dienst mit
create_health_check
undcreate_backend_service
im Skript50-td-components.sh
. - Erstellen Sie die Cloud Service Mesh-Routingkomponenten mit
create_routing_components
im Skript60-routing-components.sh
. - Erstellen Sie die Cloud Service Mesh-Sicherheitskomponenten für jeden Backend-Dienst mit
create_security_components
im Script70-security-components.sh
. - Erstellen Sie die Bereitstellung des Wallet-Clients mit
create_client_deployment
im 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_IMAGE
auf das Go-Docker-Image festlegt, und entfernen Sie die Kommentarzeichen in der Zeile, die den Wert vonWALLET_DOCKER_IMAGE
auf 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_instances
im Skript10.apis.sh
. - Erstellen Sie einen Cluster mit der Anleitung für das Beispiel
hello world
oder mit der Funktioncreate_cluster
im 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_v2
mit dem Skript40-k8s-resources.sh
. - Erstellen Sie für jeden von Ihnen erstellten Dienst eine Systemdiagnose und einen Backend-Dienst mit
create_health_check
undcreate_backend_service
im Skript50-td-components.sh
. - Erstellen Sie die Cloud Service Mesh-Routingkomponenten mit
create_routing_components
im Skript60-routing-components.sh
. - Erstellen Sie die Cloud Service Mesh-Sicherheitskomponenten für jeden Backend-Dienst mit
create_security_components
im Script70-security-components.sh
. - Erstellen Sie die Bereitstellung des Wallet-Clients mit
create_client_deployment
im 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.sh
und 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_instances
im Skript10.apis.sh
. - Erstellen Sie einen Cluster mit der Anleitung für das Beispiel
hello world
oder mit der Funktioncreate_cluster
im 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_v2
mit dem Skript40-k8s-resources.sh
. - Erstellen Sie für jeden von Ihnen erstellten Dienst eine Systemdiagnose und einen Backend-Dienst mit
create_health_check
undcreate_backend_service
im Skript50-td-components.sh
. - Erstellen Sie die Cloud Service Mesh-Routingkomponenten mit
create_routing_components
im Skript60-routing-components.sh
. - Erstellen Sie die Cloud Service Mesh-Sicherheitskomponenten für jeden Backend-Dienst mit
create_security_components
im Script70-security-components.sh
. - Erstellen Sie die Bereitstellung des Wallet-Clients mit
create_client_deployment
im 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.json
die Bootstrap-Datei in/tmp/bootstrap/td-grpc-bootstrap.json
im Dateisystem des Pods.--config-mesh-experimental
: Mit dieser Option können Sie den Mesh-Namen angeben, der mit derMesh
-Ressource übereinstimmt.--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 derEndpointPolicy
verwenden. 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
.
Mit den vorherigen Informationen 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-platform
erstellt. - Sie haben Ihren Kubernetes-Dienstkonten
roles/trafficdirector.client
zugewiesen. - Sie haben
roles/trafficdirector.client
Ihrem Google Cloud-Standarddienstkonto (${GSA_EMAIL} oben) zugewiesen. - Sie haben den Dienst
trafficdirector.googleapis.com
(API) aktiviert.
Ihr gRPC-Server verwendet TLS/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. Lassen 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_POOL
ist der Arbeitslastpool für den Cluster, in diesem Fall${PROJECT_ID}.svc.id.goog
.K8S_NAMESPACE
ist der Kubernetes-Namespace, den Sie für das Deployment des Dienstes verwendet haben.SERVICE_ACCOUNT
ist das Kubernetes-Dienstkonto, das Sie für das Deployment des Dienstes verwendet haben.
Prüfen Sie für jeden Kubernetes-Dienst, den Sie als Netzwerk-Endpunktgruppe an Ihren Back-End-Dienst angehängt haben, ob die SPIFFE-ID korrekt berechnet und dem Feld subjectAltNames
in der Nachricht SecuritySettings
hinzugefügt wurde.
Anwendungen können die mTLS-Zertifikate nicht mit Ihrer gRPC-Bibliothek verwenden
Wenn Ihre Anwendungen nicht in der Lage sind, die mTLS-Zertifikate mit Ihrer gRPC-Bibliothek zu nutzen, gehen Sie so vor:
Prüfen Sie, ob die Pod-Spezifikation die Annotation
security.cloud.google.com/use-workload-certificates
enthält, die unter Proxylosen gRPC-Dienst mit NEGs erstellen beschrieben wird.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
WorkloadCertificateConfig
den folgendenkeyAlgorithm
enthält:
keyAlgorithm: rsa: modulusSize: 4096
Prüfen Sie, ob die Zertifizierungsstelle die gleiche Schlüsselfamilie wie der Zertifikatschlüssel verwendet.
Das Zertifikat einer Anwendung wurde vom Client, vom Server oder von einer Peer-Anwendung abgelehnt
- 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:
WorkloadCertificateConfig
oderTrustConfig
ist falsch konfiguriert oder fehlt.- CSRs werden nicht genehmigt.
Sie können prüfen, ob die Zertifikatbereitstellung fehlschlägt, indem Sie die Pod-Ereignisse prüfen.
Prüfen Sie den Status Ihres Pods:
kubectl get pod -n POD_NAMESPACE POD_NAME
Dabei gilt:
POD_NAMESPACE
: der Namespace Ihres Pods.POD_NAME
: der Name Ihres Pods.
Prüfen Sie die letzten Ereignisse für den Pod:
kubectl describe pod -n POD_NAMESPACE POD_NAME
Wenn die Bereitstellung von Zertifikaten fehlschlägt, wird ein Ereignis mit
Type=Warning
,Reason=FailedMount
,From=kubelet
und mit einemMessage
-Feld angezeigt, das mitMountVolume.SetUp failed for volume "gke-workload-certificates"
beginnt. Das FeldMessage
enthält Informationen zur Fehlerbehebung.Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedMount 13s (x7 over 46s) kubelet MountVolume.SetUp failed for volume "gke-workload-certificates" : rpc error: code = Internal desc = unable to mount volume: store.CreateVolume, err: unable to create volume "csi-4d540ed59ef937fbb41a9bf5380a5a534edb3eedf037fe64be36bab0abf45c9c": caPEM is nil (check active WorkloadCertificateConfig)
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 yaml
Für
TrustConfig
:kubectl get TrustConfig default -o yaml
Prüfen Sie die Statusausgabe. Ein gültiges Objekt hat eine Bedingung mit
type: Ready
undstatus: "True"
.status: conditions: - lastTransitionTime: "2021-03-04T22:24:11Z" message: WorkloadCertificateConfig is ready observedGeneration: 1 reason: ConfigReady status: "True" type: Ready
Bei ungültigen Objekten wird stattdessen
status: "False"
angezeigt. Die Felderreason
undmessage
enthalten zusätzliche Informationen zur Fehlerbehebung.
CSRs sind nicht genehmigt
Wenn bei der CSR-Genehmigung ein Fehler auftritt, können Sie die Fehlerdetails in den Bedingungen type: Approved
und type: Issued
der CSR überprüfen.
Listen Sie die relevanten CSRs mithilfe von
kubectl
auf:kubectl get csr \ --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'
Wählen Sie eine CSR aus, für die entweder
Approved
und nichtIssued
gilt oder für dieApproved
nicht gilt.Rufen Sie mithilfe von kubectl Details zur ausgewählten CSR ab:
kubectl get csr CSR_NAME -o yaml
Ersetzen Sie
CSR_NAME
durch den Namen der ausgewählten CSR.
Eine gültige CSR hat eine Bedingung mit type: Approved
und status: "True"
und ein gültiges Zertifikat im Feld status.certificate
:
status:
certificate: <base64-encoded data>
conditions:
- lastTransitionTime: "2021-03-04T21:58:46Z"
lastUpdateTime: "2021-03-04T21:58:46Z"
message: Approved CSR because it is a valid SPIFFE SVID for the correct identity.
reason: AutoApproved
status: "True"
type: Approved
Informationen zur Fehlerbehebung für ungültige CSRs werden in den Feldern message
und reason
angezeigt.
Den Pods fehlen Zertifikate
Rufen Sie die Pod-Spezifikation für Ihren Pod ab:
kubectl get pod -n POD_NAMESPACE POD_NAME -o yaml
Dabei gilt:
POD_NAMESPACE
: der Namespace Ihres Pods.POD_NAME
: der Name Ihres Pods.
Prüfen Sie, ob die Pod-Spezifikation die Annotation
security.cloud.google.com/use-workload-certificates
enthält, die unter Pods für den Empfang von mTLS-Anmeldedaten konfigurieren beschrieben wird.Prüfen Sie, ob der Admission-Controller für GKE-Mesh-Zertifikate erfolgreich ein CSI-Treiber-Volume vom Typ
workloadcertificates.security.cloud.google.com
in Ihre Pod-Spezifikation eingefügt hat:volumes: ... -csi: driver: workloadcertificates.security.cloud.google.com name: gke-workload-certificates ...
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_LOCATION
Dabei gilt:
ISSUING_CA_TYPE
: der ausstellende CA-Typ, der entwedersubordinates
oderroots
sein 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_NAME
Ersetzen Sie
ROOT_CA_NAME
durch den Namen Ihrer Stammzertifizierungsstelle.Prüfen Sie in der IAM-Richtlinie, ob die Richtlinienbindung
privateca.auditor
vorhanden ist:... - members: - serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com role: roles/privateca.auditor ...
In diesem Beispiel ist
PROJECT_NUMBER
die Projektnummer Ihres Clusters.Rufen Sie die IAM-Richtlinie für die untergeordnete Zertifizierungsstelle ab:
gcloud privateca subordinates get-iam-policy SUBORDINATE_CA_NAME
Ersetzen Sie
SUBORDINATE_CA_NAME
durch den Namen der untergeordneten CA.Prüfen Sie in der IAM-Richtlinie, ob die Richtlinienbindung
privateca.certificateManager
vorhanden ist:... - members: - serviceAccount: service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com role: roles/privateca.certificateManager ...
In diesem Beispiel ist
PROJECT_NUMBER
die Projektnummer Ihres Clusters.
Anwendungen können die ausgegebenen mTLS-Anmeldedaten nicht verwenden
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 3
Prü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_LOCATION
Dabei gilt:
ISSUING_CA_TYPE
: der ausstellende CA-Typ, der entwedersubordinates
oderroots
sein muss.ISSUING_CA_NAME
: der Name der ausstellenden CA.ISSUING_CA_LOCATION
: die Region der ausstellenden Zertifizierungsstelle.
Prüfen Sie, ob der
keySpec.algorithm
in der Ausgabe der gleiche Schlüsselalgorithmus ist wie der, den Sie im YAML-ManifestWorkloadCertificateConfig
definiert haben. Sie erhalten folgende Ausgabe:config: ... subjectConfig: commonName: td-sub-ca subject: organization: TestOrgLLC subjectAltName: {} createTime: '2021-05-04T05:37:58.329293525Z' issuingOptions: includeCaCertUrl: true keySpec: algorithm: RSA_PKCS1_2048_SHA256 ...
Zertifikate werden abgelehnt
- 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 Cloud Service Mesh-Dienstsicherheit wird nur mit GKE unterstützt. Sie können die Dienstsicherheit nicht mit der Compute Engine bereitstellen.
Cloud Service Mesh unterstützt keine Szenarien, bei denen zwei oder mehr Endpunktrichtlinienressourcen vorhanden sind, die mit einem Endpunkt übereinstimmen, z. B. zwei Richtlinien mit den gleichen Labels und Ports oder zwei oder mehr Richtlinien mit unterschiedlichen Labels, die mit den Labels eines Endpunkts übereinstimmen. Weitere Informationen zum Abgleichen von Endpunktrichtlinien mit den Labels eines Endpunkts finden Sie unter APIs für EndpointPolicy.EndpointMatcher.MetadataLabelMatcher. In solchen Situationen generiert Cloud Service Mesh keine Sicherheitskonfiguration über die in Konflikt stehenden Richtlinien.