Configurer la sécurité du service avec gRPC sans proxy
Ce guide explique comment configurer un service de sécurité pour un maillage de services gRPC sans proxy.
Exigences
Avant de configurer la sécurité du service pour le maillage de services gRPC sans proxy, assurez-vous que vous remplissez les conditions suivantes.
- Votre déploiement répond aux exigences Préparez-vous à la configuration sur des API de routage de services avec Envoy et des charges de travail sans proxy.
- Vous devez utiliser xDS v3.
- Vous avez accès à la version xDS requise et au fournisseur de certificats requis avec l'un des langages suivants :
- gRPC Java
- gRPC C++
- gRPC Python
- gRPC Go Vous trouverez les versions de langages requises sur GitHub.
- Vous avez accès au générateur d'amorçage, version 0.16.0. L'image du générateur d'amorçage se trouve dans le dépôt de conteneurs Google Cloud.
- Vous remplissez toutes les conditions préalables pour l'équilibrage de charge du maillage de services gRPC sans proxy.
- Vous disposez des autorisations suffisantes pour créer ou mettre à jour les ressources du maillage de services Cloud et Google Cloud afin d'utiliser la sécurité PSM. Pour obtenir des informations complètes sur les autorisations requises, consultez la page Préparer la configuration de Cloud Service Mesh avec des services gRPC sans proxy.
- Vous disposez des autorisations nécessaires pour utiliser Certificate Authority Service, décrit dans la section Créer des autorités de certification pour émettre des certificats.
Configurer la gestion de l'authentification et des accès (IAM)
Vous devez disposer des autorisations requises pour utiliser Google Kubernetes Engine. Vous devez au moins disposer des rôles suivants :
- Rôle GKE
roles/container.clusterAdmin
- Rôle Compute Engine
roles/compute.instanceAdmin
- Rôle
roles/iam.serviceAccountUser
Pour créer les ressources requises pour la configuration, vous devez disposer du rôle compute.NetworkAdmin
. Ce rôle contient toutes les autorisations nécessaires pour créer, mettre à jour, supprimer, répertorier et utiliser (c'est-à-dire, y faire référence dans d'autres ressources) les ressources requises. Si vous êtes le propriétaire ou l'éditeur du projet, ce rôle vous est automatiquement attribué.
Notez que les autorisations networksecurity.googleapis.com.clientTlsPolicies.use
et networksecurity.googleapis.com.serverTlsPolicies.use
ne sont pas appliquées lorsque vous référencez ces ressources dans la ressource de service de backend.
Si cette autorisation est appliquée par la suite et que vous utilisez le rôle compute.NetworkAdmin
, vous ne remarquerez aucun problème lors de l'application de cette vérification.
Si vous utilisez des rôles personnalisés et que cette vérification est appliquée ultérieurement, vous devez inclure l'autorisation .use
correspondante. Sinon, à l'avenir,
il se peut que votre rôle personnalisé ne dispose pas des autorisations nécessaires
pour faire référence à clientTlsPolicy
ou serverTlsPolicy
à partir du service de backend.
Préparer la configuration
La sécurité du maillage de services sans proxy (PSM, Proxyless Service Mesh) ajoute une sécurité à un maillage de services configuré pour l'équilibrage de charge conformément à la documentation des services gRPC sans proxy. Dans un maillage de services sans proxy, un client gRPC utilise le schéma xds:
dans l'URI pour accéder au service, ce qui active les fonctionnalités PSM d'équilibrage de charge et de découverte des points de terminaison.
Mettre à jour les clients et les serveurs gRPC vers la version appropriée
Compilez ou recompilez vos applications en utilisant la version gRPC minimale compatible avec votre langage.
Mettre à jour le fichier d'amorçage
Les applications gRPC utilisent un seul fichier d'amorçage, qui doit comporter tous les champs obligatoires pour le code côté client et côté serveur gRPC. Un générateur d'amorçage génère automatiquement le fichier d'amorçage pour inclure les options et les valeurs dont la sécurité PSM a besoin. Pour en savoir plus, consultez la section Fichier d'amorçage, qui inclut un exemple de fichier d'amorçage.
Vue d'ensemble de la configuration
Ce processus de configuration est une extension de la configuration du service de maillage de services Cloud avec GKE et des services gRPC sans proxy. Les étapes existantes non modifiées de cette configuration sont référencées partout où elles s'appliquent.
Les principales améliorations apportées à la configuration de Cloud Service Mesh avec GKE sont les suivantes :
- Configurer CA Service dans lequel vous créez des pools d'autorités de certification privés et les autorités de certification requises.
- Créer un cluster GKE avec GKE Fédération d'identité de charge de travail pour GKE, fonctionnalités de certificats de maillage et service CA l'intégration.
- Configurer l'émission de certificats de maillage sur le cluster.
- Créer les comptes de service client et serveur.
- Configurer l'exemple de serveur qui utilise les API xDS et les identifiants du serveur xDS pour acquérir la configuration de sécurité auprès de Cloud Service Mesh.
- Configurer l'exemple de client qui utilise des identifiants xDS.
- Mettre à jour la configuration de Cloud Service Mesh pour inclure la configuration de sécurité
Vous pouvez consulter des exemples de code pour utiliser des identifiants xDS aux emplacements suivants :
Mettre à jour Google Cloud CLI
Pour mettre à jour Google Cloud CLI, exécutez la commande suivante :
gcloud components update
Configurer des variables d'environnement
Dans ce guide, vous utilisez les commandes Cloud Shell et les informations répétées dans ces commandes sont représentées par diverses variables d'environnement. Définissez vos valeurs spécifiques dans les variables d'environnement suivantes dans l'environnement shell avant d'exécuter les commandes. Chaque ligne de commentaire indique la signification de la variable d'environnement associée.
# 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
Activer l'accès aux API requises
Cette section vous explique comment activer l'accès aux API requises.
Exécutez la commande suivante pour activer Cloud Service Mesh et les autres API requises pour la sécurité du maillage de services gRPC sans proxy.
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
Exécutez la commande suivante pour autoriser le compte de service par défaut à accéder à l'API de sécurité Cloud Service Mesh.
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
Créer ou mettre à jour un cluster GKE
La sécurité du service Cloud Service Mesh dépend de l'intégration du service CA à GKE. Le cluster GKE doit répondre aux exigences suivantes, en plus de celles concernant la configuration :
- Utilisez au moins la version de cluster 1.21.4-gke.1801. Si vous avez besoin de fonctionnalités disponibles dans une version ultérieure, vous pouvez obtenir cette version auprès de la version précoce.
- Le cluster GKE doit être activé et configuré avec des certificats de maillage, comme décrit dans la section Créer des autorités de certification pour émettre des certificats.
Créez un cluster qui utilise la fédération d'identité de charge de travail pour GKE. Si vous mettez à jour un cluster existant, passez à l'étape suivante. La valeur que vous indiquez pour
--tags
doit correspondre au nom transmis à l'option--target-tags
pour Commandefirewall-rules create
de la section Configurer Cloud Service Mesh avec les composants Cloud Load Balancing# 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
La création du cluster peut prendre plusieurs minutes.
Si vous utilisez un cluster existant, activez la fédération d'identité de charge de travail pour GKE et les certificats de maillage GKE. Assurez-vous que le cluster a été créé avec l'option
--enable-ip-alias
, qui ne peut pas être utilisée avec la commandeupdate
.gcloud container clusters update CLUSTER_NAME \ --enable-mesh-certificates
Exécutez la commande suivante pour passer au nouveau cluster en tant que cluster par défaut pour vos commandes
kubectl
:gcloud container clusters get-credentials CLUSTER_NAME \ --zone ZONE
Enregistrer des clusters avec un parc
Enregistrez le cluster que vous avez créé ou mis à jour à la section Créer un cluster GKE avec un parc. L'enregistrement du cluster vous permet de configurer des clusters plus facilement dans plusieurs projets.
Notez que ces étapes peuvent prendre jusqu'à 10 minutes pour chacune d'entre elles.
Enregistrez votre cluster dans le parc :
gcloud container fleet memberships register CLUSTER_NAME \ --gke-cluster=ZONE/CLUSTER_NAME \ --enable-workload-identity --install-connect-agent \ --manifest-output-file=MANIFEST-FILE_NAME
comme suit :
- CLUSTER_NAME : nom de votre cluster
- ZONE : zone de votre cluster.
- MANIFEST-FILE_NAME: chemin d'accès où ces commandes générer le fichier manifeste pour l'enregistrement.
Une fois le processus d'enregistrement terminé, un message de ce type s'affiche :
Finished registering the cluster CLUSTER_NAME with the fleet.
Appliquez le fichier manifeste généré à votre cluster :
kubectl apply -f MANIFEST-FILE_NAME
Une fois le processus d'application réussi, des messages de ce type s'affichent :
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
Récupérez la ressource d'appartenance à partir du cluster :
kubectl get memberships membership -o yaml
Le résultat doit inclure le pool Workoad Identity attribué par le parc, où PROJECT_ID est l'ID de votre projet:
workload_identity_pool: PROJECT_ID.svc.id.goog
Cela signifie que le cluster a bien été enregistré.
Créer des autorités de certification pour émettre des certificats
Pour émettre des certificats sur vos pods, créez un pool CA Service et les autorités de certification suivantes :
- Autorité de certification racine Il s'agit de la racine de confiance pour tous les certificats de maillages émis. Vous pouvez utiliser une autorité de certification racine existante, si vous en avez une. Créez l'autorité de certification racine au niveau
enterprise
, conçu pour l'émission de certificats de longue durée, à faible volume. - Autorité de certification subordonnée Cette autorité de certification délivre des certificats pour les charges de travail. Créez l'autorité de certification subordonnée dans la région où votre cluster est déployé. Créez l'autorité de certification subordonnée au niveau
devops
, conçu pour l'émission de certificats de courte durée, à volume élevé.
La création d'une autorité de certification subordonnée est facultative, mais nous vous recommandons vivement d'en créer une plutôt que d'utiliser votre autorité de certification racine pour émettre des certificats de maillage GKE. Si vous décidez d'utiliser l'autorité de certification racine pour émettre des certificats de maillage, assurez-vous que le mode d'émission basé sur la configuration par défaut reste autorisé.
L'autorité de certification subordonnée peut se trouver dans une région différente de votre cluster, mais nous vous recommandons vivement de la créer dans la même région que votre cluster pour optimiser les performances. Toutefois, vous pouvez créer des autorités de certification racine et subordonnées dans différentes régions sans affecter les performances ou la disponibilité.
Les régions suivantes sont compatibles avec CA Service :
Nom de la région | Description de la région |
---|---|
asia-east1 |
Taïwan |
asia-east2 |
Hong Kong |
asia-northeast1 |
Tokyo |
asia-northeast2 |
Osaka |
asia-northeast3 |
Séoul |
asia-south1 |
Mumbai |
asia-south2 |
Delhi |
asia-southeast1 |
Singapour |
asia-southeast2 |
Jakarta |
australia-southeast1 |
Sydney |
australia-southeast2 |
Melbourne |
europe-central2 |
Varsovie |
europe-north1 |
Finlande |
europe-southwest1 |
Madrid |
europe-west1 |
Belgique |
europe-west2 |
Londres |
europe-west3 |
Francfort |
europe-west4 |
Pays-Bas |
europe-west6 |
Zurich |
europe-west8 |
Milan |
europe-west9 |
Paris |
europe-west10 |
Berlin |
europe-west12 |
Turin |
me-central1 |
Doha |
me-central2 |
Dammam |
me-west1 |
Tel-Aviv |
northamerica-northeast1 |
Montréal |
northamerica-northeast2 |
Toronto |
southamerica-east1 |
São Paulo |
southamerica-west1 |
Santiago |
us-central1 |
Iowa |
us-east1 |
Caroline du Sud |
us-east4 |
Virginie du Nord |
us-east5 |
Columbus |
us-south1 |
Dallas |
us-west1 |
Oregon |
us-west2 |
Los Angeles |
us-west3 |
Salt Lake City |
us-west4 |
Las Vegas |
Vous pouvez également vérifier la liste des emplacements acceptés en exécutant la commande suivante :
gcloud privateca locations list
Accordez le rôle IAM
roles/privateca.caManager
aux utilisateurs qui créent un pool d'autorités de certification et une autorité de certification. Notez que le format approprié de MEMBER estuser:userid@example.com
. Si cette personne est l'utilisateur actuel, vous pouvez obtenir son ID à l'aide de la commande shell$(gcloud auth list --filter=status:ACTIVE --format="value(account)")
.gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.caManager
Accorder à des personnes le rôle
role/privateca.admin
pour Certificate Authority Service qui doivent modifier les stratégies IAM, oùMEMBER
est un qui a besoin de cet accès, en particulier toute personne les étapes qui suivent pour accorder les autorisationsprivateca.auditor
et Rôlesprivateca.certificateManager
:gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.admin
Créez le pool CA Service racine.
gcloud privateca pools create ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --tier enterprise
Créez une autorité de certification racine.
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
Pour cette configuration de démonstration, utilisez les valeurs suivantes pour les variables :
- ROOT_CA_POOL_NAME=td_sec_pool
- ROOT_CA_NAME=pkcs2-ca
- ROOT_CA_POOL_LOCATION=us-east1
- ROOT_CA_ORGANIZATION="TestCorpLLC"
Créez le pool et l'autorité de certification subordonnés. Assurez-vous que le mode d'émission basé sur la configuration par défaut reste autorisé.
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
Pour cette configuration de démonstration, utilisez les valeurs suivantes pour les variables :
- 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
Attribuez le rôle IAM
privateca.auditor
au pool d'autorités de certification racine pour autoriser l'accès à partir du compte de service GKE :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"
Accordez le rôle IAM
privateca.certificateManager
au pool d'autorités de certification subordonné pour autoriser l'accès à partir du compte de service GKE :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"
Enregistrez la configuration YAML
WorkloadCertificateConfig
suivante pour indiquer à votre cluster comment émettre des certificats de maillage :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
Remplacez les éléments suivants :
- ID du projet dans lequel s'exécute votre cluster :
PROJECT_ID
- URI complet de l'autorité de certification qui émet vos certificats de maillage (ISSUING_CA_POOL_URI). Il peut s'agir de votre autorité de certification subordonnée (recommandé) ou de votre autorité de certification racine. Il a le format suivant :
//privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_POOL_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
- ID du projet dans lequel s'exécute votre cluster :
Enregistrez la configuration YAML
TrustConfig
suivante pour indiquer à votre cluster comment approuver les certificats émis :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
Remplacez les éléments suivants :
- ID du projet dans lequel s'exécute votre cluster :
PROJECT_ID
- URI complet du pool d'autorités de certification racine (ROOT_CA_POOL_URI). Son format est le suivant :
//privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
- ID du projet dans lequel s'exécute votre cluster :
Appliquez les configurations à votre cluster.
kubectl apply -f WorkloadCertificateConfig.yaml kubectl apply -f TrustConfig.yaml
Créer un service gRPC sans proxy avec des NEG
Pour la sécurité PSM, vous avez besoin d'un serveur gRPC sans proxy capable d'utiliser xDS pour acquérir la configuration de sécurité de Cloud Service Mesh. Cette étape est semblable à la configuration des services GKE avec des NEG dans le guide de configuration de l'équilibrage de charge PSM, à la différence que vous utilisez le serveur helloworld
compatible xDS de l'exemple xDS dans le dépôt grpc-java
au lieu de l'image java-example-hostname
.
Vous créez et exécutez ce serveur dans un conteneur créé à partir d'une image openjdk:8-jdk
.
Vous allez également utiliser la fonctionnalité NEG nommée, qui vous permet de spécifier un nom pour le NEG. Cela simplifie les étapes ultérieures, car votre déploiement connaît le nom du NEG sans avoir à le rechercher.
Voici un exemple complet de la spécification Kubernetes du serveur gRPC. Notez les points suivants :
- La spécification crée un compte de service Kubernetes
example-grpc-server
qui est utilisé par le pod du serveur gRPC. - La spécification utilise le champ
name
de l'annotationcloud.google.com/neg
du service pour spécifier le nom du NEGexample-grpc-server
. - La variable
${PROJNUM}
représente le numéro de votre projet. - La spécification utilise la section
initContainers
pour exécuter un générateur d'amorçage afin de remplir le fichier d'amorçage nécessaire à la bibliothèque gRPC sans proxy. Ce fichier d'amorçage se trouve à l'emplacement/tmp/grpc-xds/td-grpc-bootstrap.json
dans le conteneur de serveur gRPC appeléexample-grpc-server
.
Ajoutez l'annotation suivante à votre spécification de pod :
annotations: security.cloud.google.com/use-workload-certificates: ""
L'emplacement approprié est indiqué dans la spécification complète qui suit.
Lors de la création, chaque pod reçoit un volume à /var/run/secrets/workload-spiffe-credentials
.
Ce volume contient les éléments suivants :
private_key.pem
est une clé privée générée automatiquement.certificates.pem
est un bundle de certificats au format PEM qui peuvent être présentés à un autre pod sous la forme d'une chaîne de certificats client, ou utilisés comme chaîne de certificats de serveur.ca_certificates.pem
est un bundle de certificats au format PEM à utiliser en tant qu'ancres de confiance pour valider la chaîne de certificats client présentée par un autre pod, ou la chaîne de certificats du serveur reçue lors de la connexion à un autre pod.
Notez que ca_certificates.pem
contient des certificats pour le domaine de confiance local pour les charges de travail, qui correspond au pool de charges de travail du cluster.
Le certificat feuille dans certificates.pem
contient l'assertion d'identité SPIFFE en texte brut suivante :
spiffe://WORKLOAD_POOL/ns/NAMESPACE/sa/KUBERNETES_SERVICE_ACCOUNT
Dans cette assertion :
- WORKLOAD_POOL est le nom du pool de charges de travail du cluster.
- NAMESPACE est l'espace de noms de votre compte de service Kubernetes.
- KUBERNETES_SERVICE_ACCOUNT est le nom de votre compte de service Kubernetes.
Les instructions suivantes propres à votre langage créent la spécification à utiliser dans cet exemple.
Java
Exécutez la commande suivante pour vous assurer que le numéro de projet est correctement défini :
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Créez la spécification :
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++
Exécutez la commande suivante pour vous assurer que le numéro de projet est correctement défini :
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Créez la spécification :
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
Exécutez la commande suivante pour vous assurer que le numéro de projet est correctement défini :
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Créez la spécification :
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
Exécutez la commande suivante pour vous assurer que le numéro de projet est correctement défini :
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Créez la spécification :
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
Suivez la procédure ci-dessous.
Appliquez la spécification :
kubectl apply -f example-grpc-server.yaml
Attribuez les rôles requis au compte de service :
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
Exécutez les commandes suivantes pour vérifier que le service et le pod ont été créés correctement :
kubectl get deploy/example-grpc-server kubectl get svc/example-grpc-server
Vérifiez que le nom du NEG est correct :
gcloud compute network-endpoint-groups list \ --filter "name=example-grpc-server" --format "value(name)"
La commande doit renvoyer le nom du NEG
example-grpc-server
.
Configurer Cloud Service Mesh avec les composants d'équilibrage de charge Google Cloud
Les étapes de cette section sont semblables à celles de la section Configurer Cloud Service Mesh avec des composants d'équilibrage de charge Toutefois, des modifications sont apportées, comme décrit dans les sections suivantes.
Créer la vérification d'état, la règle de pare-feu et le service de backend
Lorsque le serveur gRPC est configuré pour utiliser mTLS, les vérifications d'état gRPC ne fonctionnent pas, car le client de vérification de l'état ne peut pas présenter de certificat client valide aux serveurs. Vous pouvez résoudre cela de l'une des manières suivantes.
Dans la première approche, vous demandez au serveur de créer un port de diffusion supplémentaire désigné en tant que port de vérification d'état. Celui-ci est associé à un service de vérification d'état spécial, en tant que texte brut ou TLS.
L'exemple de serveur helloworld
xDS
utilise PORT_NUMBER
+ 1 comme port de vérification de l'état en texte brut. L'exemple utilise 50052 comme port de vérification de l'état, car 50051 est le port du serveur d'applications gRPC.
Dans la seconde approche, vous configurez la vérification de l'état pour vérifier uniquement la connectivité TCP au port de diffusion de l'application. Cela ne vérifie que la connectivité et génère également du trafic inutile vers le serveur en cas de handshakes TLS ayant échoué. C'est pourquoi nous vous recommandons de suivre la première approche.
Créez la vérification d'état. Notez que la vérification d'état ne démarre pas tant que vous n'avez pas créé et démarré le serveur.
Si vous créez un port de diffusion désigné pour la vérification d'état, ce que nous recommandons, utilisez cette commande :
gcloud compute health-checks create grpc grpc-gke-helloworld-hc \ --enable-logging --port 50052
Si vous créez une vérification de l'état TCP, ce qui n'est pas recommandé, utilisez cette commande:
gcloud compute health-checks create tcp grpc-gke-helloworld-hc \ --use-serving-port
Créez le pare-feu. Assurez-vous que la valeur de
--target-tags
correspond à celle que vous avez fournie pour--tags
dans la section Créer ou mettre à jour un cluster GKE.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
Créez le service de backend :
gcloud compute backend-services create grpc-gke-helloworld-service \ --global \ --load-balancing-scheme=INTERNAL_SELF_MANAGED \ --protocol=GRPC \ --health-checks grpc-gke-helloworld-hc
Associez le NEG au service de backend :
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
Créer les ressources Mesh
et GRPCRoute
Cette démarche est semblable à celle que vous suivez pour configurer les ressources Mesh
et GRPCRoute
dans la section Configurer des services gRPC sans proxy.
Créez la spécification
Mesh
et enregistrez-la dans un fichier nommémesh.yaml
.name: grpc-mesh
Importez la ressource
Mesh
à partir de la spécification.gcloud network-services meshes import grpc-mesh \ --source=mesh.yaml \ --location=global
Créez la spécification
GRPCRoute
et enregistrez-la dans un fichier nommégrpc_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
Importez la ressource
GRPCRoute
à partir de la spécificationgrpc_route.yaml
.gcloud network-services grpc-routes import helloworld-grpc-route \ --source=grpc_route.yaml \ --location=global
Configurer Cloud Service Mesh avec la sécurité gRPC sans proxy
Cet exemple montre comment configurer mTLS côté client et côté serveur.
Format des références aux règles
Le format suivant est requis pour faire référence aux règles TLS des serveurs et des clients :
projects/PROJECT_ID/locations/global/[serverTlsPolicies|clientTlsPolicies]/[server-tls-policy|client-mtls-policy]
Exemple :
projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
Configurer mTLS côté serveur
Commencez par créer une règle TLS de serveur. La règle demande au serveur gRPC d'utiliser la configuration de plug-in certificateProvicerInstance
identifiée par le nom google_cloud_private_spiffe
pour le certificat d'identité, qui fait partie de serverCertificate
. La section mtlsPolicy
indique la sécurité mTLS et utilise le même google_cloud_private_spiffe
que la configuration de plug-in pour clientValidationCa
, qui est la spécification du certificat racine (de validation).
Ensuite, vous créez une règle de point de terminaison. Cela indique qu'un backend, par exemple un serveur gRPC, utilisant le port 50051
avec n'importe quel (ou aucun) libellé de métadonnées, reçoit la règle TLS du serveur associé nommée server-mtls-policy
. Vous spécifiez des métadonnées
étiquettes à l'aide de MATCH_ALL
ou d'une valeur compatible. Les libellés de métadonnées compatibles se trouvent dans le champ endpointMatcher.metadataLabelMatcher.metadataLabelMatchCriteria
du document NetworkServicesEndpointPolicy. Vous créez la stratégie de point de terminaison à l'aide d'un fichier temporaire
ep-mtls-psms.yaml
, qui contient les valeurs de la ressource de stratégie de point de terminaison
à l'aide de la stratégie que vous avez déjà définie.
Créez un fichier temporaire
server-mtls-policy.yaml
dans le répertoire actuel, avec les valeurs de la ressource de règle TLS du serveur :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
Créez une ressource de règle TLS de serveur appelée
server-mtls-policy
en important le fichier temporaireserver-mtls-policy.yaml
:gcloud network-security server-tls-policies import server-mtls-policy \ --source=server-mtls-policy.yaml --location=global
Créez la règle de point de terminaison en créant le fichier temporaire
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
Créez la règle de point de terminaison en important le fichier
ep-mtls-psms.yaml
:gcloud beta network-services endpoint-policies import ep-mtls-psms \ --source=ep-mtls-psms.yaml --location=global
Configurer mTLS côté client
La règle de sécurité côté client est associée au service de backend. Lorsqu'un client accède à un backend (le serveur gRPC) via le service de backend, la règle de sécurité associée côté client est envoyée au client.
Créez le contenu de la ressource de la règle TLS du client dans un fichier temporaire appelé
client-mtls-policy.yaml
dans le répertoire actuel:name: "client-mtls-policy" clientCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe serverValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffe
Créez la ressource de stratégie TLS client appelée
client-mtls-policy
en important le fichier temporaireclient-mtls-policy.yaml
:gcloud network-security client-tls-policies import client-mtls-policy \ --source=client-mtls-policy.yaml --location=global
Créez un extrait dans un fichier temporaire pour référencer cette règle et ajouter les détails pour
subjectAltNames
dans le messageSecuritySettings
, comme dans l'exemple suivant. Remplacez${PROJECT_ID}
par l'ID de votre projet, qui correspond à la valeur de la variable d'environnement${PROJECT_ID}
décrite précédemment. Notez queexample-grpc-server
danssubjectAltNames
est le nom du compte de service Kubernetes utilisé pour le pod du serveur gRPC dans la spécification de déploiement.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
Ajoutez le message
securitySettings
au service de backend que vous avez déjà créé. Ces étapes permettent d'exporter le contenu du service de backend actuel, d'ajouter le message clientsecuritySetting
et de réimporter le nouveau contenu pour mettre à jour le service de backend.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
Vérifier la configuration
La configuration de Cloud Service Mesh est à présent terminée, y compris la sécurité côté client. Vous allez ensuite préparer et exécuter les charges de travail du serveur et du client. Ceci conclut l'exemple.
Créer un client gRPC sans proxy
Cette étape est semblable à l'étape précédente Créer un service gRPC sans proxy.
Vous utilisez le client helloworld
compatible xDS provenant du répertoire d'exemples xDS du dépôt grpc-java
. Vous créez et exécutez le client dans un conteneur créé à partir d'une image openjdk:8-jdk
. La spécification Kubernetes du client gRPC effectue les opérations suivantes.
- Elle crée un compte de service Kubernetes
example-grpc-client
utilisé par le pod du client gRPC. ${PROJNUM}
représente le numéro de votre projet et doit être remplacé par le numéro réel.
Ajoutez l'annotation suivante à votre spécification de pod :
annotations: security.cloud.google.com/use-workload-certificates: ""
Lors de la création, chaque pod reçoit un volume à /var/run/secrets/workload-spiffe-credentials
.
Ce volume contient les éléments suivants :
private_key.pem
est une clé privée générée automatiquement.certificates.pem
est un bundle de certificats au format PEM qui peuvent être présentés à un autre pod sous la forme d'une chaîne de certificats client, ou utilisés comme chaîne de certificats de serveur.ca_certificates.pem
est un bundle de certificats au format PEM à utiliser en tant qu'ancres de confiance pour valider la chaîne de certificats client présentée par un autre pod, ou la chaîne de certificats du serveur reçue lors de la connexion à un autre pod.
Notez que ca_certificates.pem
contient les certificats racine du domaine de confiance local pour les charges de travail, qui correspond au pool de charges de travail du cluster.
Le certificat feuille dans certificates.pem
contient l'assertion d'identité SPIFFE en texte brut suivante :
spiffe://WORKLOAD_POOL/ns/NAMESPACE/sa/KUBERNETES_SERVICE_ACCOUNT
Dans cette assertion :
- WORKLOAD_POOL est le nom du pool de charges de travail du cluster.
- NAMESPACE est le nom de votre compte de service Kubernetes.
- KUBERNETES_SERVICE_ACCOUNT est l'espace de noms de votre compte de service Kubernetes.
Les instructions suivantes propres à votre langage créent la spécification à utiliser dans cet exemple.
Java
Exécutez la commande suivante pour vous assurer que le numéro de projet est correctement défini :
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Créez la spécification suivante :
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++
Exécutez la commande suivante pour vous assurer que le numéro de projet est correctement défini :
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Créez la spécification suivante :
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
Exécutez la commande suivante pour vous assurer que le numéro de projet est correctement défini :
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Créez la spécification suivante :
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
Exécutez la commande suivante pour vous assurer que le numéro de projet est correctement défini :
if [ -z "$PROJNUM" ] ; then export PROJNUM=$(gcloud projects describe $(gcloud info --format='value(config.project)') --format="value(projectNumber)") ; fi ; echo $PROJNUM
Créez la spécification suivante :
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
Suivez la procédure ci-dessous.
Appliquez la spécification :
kubectl apply -f example-grpc-client.yaml
Attribuez les rôles requis au compte de service :
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
Vérifiez que le pod client est en cours d'exécution :
kubectl get pods
La commande renvoie du texte semblable à ce qui suit :
NAMESPACE NAME READY STATUS RESTARTS AGE default example-grpc-client-7c969bb997-9fzjv 1/1 Running 0 104s [..skip..]
Exécuter le serveur
Créez et exécutez le serveur helloworld
compatible xDS dans le pod de serveur que vous avez créé précédemment.
Java
Obtenez le nom du pod créé pour le service
example-grpc-server
:kubectl get pods | grep example-grpc-server
Vous obtenez un résultat semblable à celui-ci :
default example-grpc-server-77548868d-l9hmf 1/1 Running 0 105s
Ouvrez une interface système sur le pod de serveur :
kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/bash
Dans le shell, vérifiez que le fichier d'amorçage
/tmp/grpc-xds/td-grpc-bootstrap.json
correspond au schéma décrit dans la section Fichier d'amorçage.Téléchargez la version 1.42.1 de Java gRPC, puis créez l'application de serveur
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
Exécutez le serveur avec l'option
--xds-creds
pour indiquer qu'il est compatible avec xDS, en utilisant50051
comme port d'écoute etxds-server
comme nom d'identification du serveur :./build/install/example-xds/bin/xds-hello-world-server --xds-creds 50051 xds-server
Une fois que le serveur a obtenu la configuration nécessaire Cloud Service Mesh, vous obtenez le résultat suivant:
Listening on port 50051 plain text health service listening on port 50052
C++
Obtenez le nom du pod créé pour le service
example-grpc-server
:kubectl get pods | grep example-grpc-server
Vous obtenez un résultat semblable à celui-ci :
default example-grpc-server-77548868d-l9hmf 1/1 Running 0 105s
Ouvrez une interface système sur le pod de serveur :
kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/bash
Dans l'interface système, vérifiez que le fichier d'amorçage
/tmp/grpc-xds/td-grpc-bootstrap.json
correspond au schéma décrit dans la section Fichier d'amorçage.Téléchargez C++ gRPC et créez l'application serveur
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
Exécutez le serveur en utilisant
50051
comme port d'écoute etxds_greeter_server
comme nom d'identification du serveur :bazel-bin/examples/cpp/helloworld/xds_greeter_server --port=50051 --maintenance_port=50052 --secure
Pour exécuter le serveur sans identifiants, vous pouvez spécifier les éléments suivants :
bazel-bin/examples/cpp/helloworld/xds_greeter_server --nosecure
Une fois que le serveur a obtenu la configuration nécessaire Cloud Service Mesh, vous obtenez le résultat suivant:
Listening on port 50051 plain text health service listening on port 50052
Python
Obtenez le nom du pod créé pour le service
example-grpc-server
:kubectl get pods | grep example-grpc-server
Vous obtenez un résultat semblable à celui-ci :
default example-grpc-server-77548868d-l9hmf 1/1 Running 0 105s
Ouvrez une interface système sur le pod de serveur :
kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/bash
Dans l'interface système, vérifiez que le fichier d'amorçage
/tmp/grpc-xds/td-grpc-bootstrap.json
correspond au schéma décrit dans la section Fichier d'amorçage.Téléchargez la version 1.41.0 de Python gRPC et créez l'exemple d'application.
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
Exécutez le serveur avec l'option
--xds-creds
pour indiquer la sécurité compatible avec xDS en utilisant50051
comme port d'écoute.python3 server.py 50051 --xds-creds
Une fois que le serveur a obtenu la configuration nécessaire Cloud Service Mesh, vous obtenez le résultat suivant:
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
Obtenez le nom du pod créé pour le service
example-grpc-server
:kubectl get pods | grep example-grpc-server
Vous obtenez un résultat semblable à celui-ci :
default example-grpc-server-77548868d-l9hmf 1/1 Running 0 105s
Ouvrez une interface système sur le pod de serveur :
kubectl exec -it example-grpc-server-77548868d-l9hmf -- /bin/sh
Dans l'interface système, vérifiez que le fichier d'amorçage
/tmp/grpc-xds/td-grpc-bootstrap.json
correspond au schéma décrit dans la section Fichier d'amorçage.Téléchargez la version 1.41.0 de Go gRPC et accédez au répertoire contenant l'application de serveur
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
Créez et exécutez le serveur avec l'option
--xds_creds
pour indiquer d'utiliser la sécurité compatible xDS, avec comme port d'écoute50051
:GRPC_GO_LOG_VERBOSITY_LEVEL=2 GRPC_GO_LOG_SEVERITY_LEVEL="info" \ go run main.go \ -xds_creds \ -port 50051
Une fois que le serveur a obtenu la configuration nécessaire Cloud Service Mesh, vous obtenez le résultat suivant:
Using xDS credentials... Serving GreeterService on 0.0.0.0:50051 and HealthService on 0.0.0.0:50052
Le processus de vérification d'état prend entre trois et cinq minutes pour indiquer que votre service est opérationnel après le démarrage du serveur.
Exécuter le client et vérifier la configuration
Créez et exécutez le client helloworld
compatible xDS dans le pod client que vous avez créé précédemment.
Java
Obtenez le nom du pod client :
kubectl get pods | grep example-grpc-client
Vous obtenez un résultat semblable à celui-ci :
default example-grpc-client-7c969bb997-9fzjv 1/1 Running 0 105s
Ouvrez un shell sur le pod client :
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
Dans le shell de commande, téléchargez la version 1.42.1 de Java gRPC, puis créez l'application cliente
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
Exécutez le client avec l'option
--xds-creds
pour indiquer la sécurité compatible avec xDS, le nom du client et la chaîne de connexion cible :./build/install/example-xds/bin/xds-hello-world-client --xds-creds xds-client \ xds:///helloworld-gke:8000
Le résultat doit ressembler à ce qui suit :
Greeting: Hello xds-client, from xds-server
C++
Obtenez le nom du pod client :
kubectl get pods | grep example-grpc-client
Vous obtenez un résultat semblable à celui-ci :
default example-grpc-client-7c969bb997-9fzjv 1/1 Running 0 105s
Ouvrez une interface système sur le pod client :
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
Une fois dans l'interface système, téléchargez C++ gRPC et créez l'application cliente
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
Exécutez le client avec l'option
--xds-creds
pour indiquer la sécurité compatible avec xDS, le nom du client et la chaîne de connexion cible :bazel-bin/examples/cpp/helloworld/xds_greeter_client --target=xds:///helloworld-gke:8000
Pour exécuter le client sans identifiants, procédez comme suit :
bazel-bin/examples/cpp/helloworld/xds_greeter_client --target=xds:///helloworld-gke:8000 --nosecure
Le résultat doit ressembler à ce qui suit :
Greeter received: Hello world
Python
Obtenez le nom du pod client :
kubectl get pods | grep example-grpc-client
Vous obtenez un résultat semblable à celui-ci :
default example-grpc-client-7c969bb997-9fzjv 1/1 Running 0 105s
Ouvrez une interface système sur le pod client :
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
Une fois dans l'interface système, téléchargez la version 1.41.0 de Python gRPC et créez l'exemple d'application cliente.
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
Exécutez le client avec l'option
--xds-creds
pour indiquer la sécurité compatible avec xDS, le nom du client et la chaîne de connexion cible :python3 client.py xds:///helloworld-gke:8000 --xds-creds
Le résultat doit ressembler à ce qui suit :
Greeter client received: Hello you from example-host!
Go
Obtenez le nom du pod client :
kubectl get pods | grep example-grpc-client
Vous obtenez un résultat semblable à celui-ci :
default example-grpc-client-7c969bb997-9fzjv 1/1 Running 0 105s
Ouvrez un shell sur le pod client :
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/sh
Une fois dans le shell, téléchargez la version 1.42.0 de Go gRPC et accédez au répertoire contenant l'application cliente
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
Créez et exécutez le client avec l'option
--xds_creds
pour indiquer Sécurité compatible xDS, nom du client et chaîne de connexion cible: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
Le résultat doit ressembler à ce qui suit :
Greeting: Hello xds-client, from example-grpc-server-77548868d-l9hmf
Configurer l'accès au niveau du service avec une règle d'autorisation
La compatibilité avec la règle gRFC A41 est requise pour la stratégie d'autorisation. Vous trouverez les versions de langages requises sur GitHub.
Suivez ces instructions pour configurer l'accès au niveau du service avec des règles d'autorisation. Avant de créer des règles d'autorisation, lisez la précaution de restreindre l'accès à l'aide d'une autorisation.
Pour faciliter la vérification de la configuration, créez un nom d'hôte supplémentaire que le client peut utiliser pour faire référence au service helloworld-gke
.
Mettre à jour la spécification
GRPCRoute
précédemment stockée dansgrpc_route.yaml
name: helloworld-grpc-route hostnames: - helloworld-gke:8000 - helloworld-gke-noaccess:8000 meshes: - projects/PROJECT_NUMBER/locations/global/meshes/grpc-mesh rules: - action: destinations: - serviceName: projects/PROJECT_NUMBER/locations/global/backendServices/grpc-gke-helloworld-service
Importez à nouveau la ressource
GRPCRoute
à partir de la spécificationgrpc_route.yaml
.gcloud network-services grpc-routes import helloworld-grpc-route \ --source=grpc_route.yaml \ --location=global
Les instructions suivantes créent une règle d'autorisation qui autorise les requêtes envoyées par le compte example-grpc-client
dans lequel le nom d'hôte est helloworld-gke:8000
et le port est 50051
.
gcloud
Créez une règle d'autorisation en créant un fichier nommé
helloworld-gke-authz-policy.yaml
.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
Importez la stratégie.
gcloud network-security authorization-policies import \ helloworld-gke-authz-policy \ --source=helloworld-gke-authz-policy.yaml \ --location=global
Mettez à jour la règle de point de terminaison pour référencer la nouvelle règle d'autorisation en ajoutant les éléments suivants au fichier
ep-mtls-psms.yaml
.authorizationPolicy: projects/${PROJECT_ID}/locations/global/authorizationPolicies/helloworld-gke-authz-policy
La règle de point de terminaison spécifie maintenant que mTLS et la règle d'autorisation doivent être appliqués aux requêtes entrantes vers les pods dont les fichiers d'amorçage gRPC contiennent le libellé
app:helloworld
.Importez la stratégie :
gcloud network-services endpoint-policies import ep-mtls-psms \ --source=ep-mtls-psms.yaml --location=global
Valider la règle d'autorisation
Suivez ces instructions pour vérifier que la règle d'autorisation fonctionne correctement.
Java
Ouvrez un shell sur le pod client que vous avez utilisé précédemment.
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
Dans le shell, exécutez les commandes suivantes pour valider la configuration.
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
Le résultat doit ressembler à ce qui suit :
Greeting: Hello xds-client, from xds-server
Exécutez à nouveau le client avec le nom de serveur alternatif. Notez qu'il s'agit d'un cas d'échec. La requête n'est pas valide car la règle d'autorisation n'autorise l'accès qu'au nom d'hôte
helloworld-gke:8000
../build/install/example-xds/bin/xds-hello-world-client --xds-creds xds-client \ xds:///helloworld-gke-noaccess:8000
Le résultat doit ressembler à ce qui suit :
WARNING: RPC failed: Status{code=PERMISSION_DENIED}
Si vous n'obtenez pas ce résultat, il est possible que la règle d'autorisation ne soit pas encore utilisée. Attendez quelques minutes et relancez le processus de vérification.
Go
Ouvrez un shell sur le pod client que vous avez utilisé précédemment.
kubectl exec -it example-grpc-client-7c969bb997-9fzjv -- /bin/bash
Dans le shell, exécutez les commandes suivantes pour valider la configuration.
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
Le résultat doit ressembler à ce qui suit :
Greeting: Hello xds-client, from example-grpc-server-77548868d-l9hmf
Exécutez à nouveau le client avec le nom de serveur alternatif. Notez qu'il s'agit d'un cas d'échec. La requête n'est pas valide car la règle d'autorisation n'autorise l'accès qu'au nom d'hôte
helloworld-gke:8000
.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
Le résultat doit ressembler à ce qui suit :
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
Si vous n'obtenez pas ce résultat, il est possible que la règle d'autorisation ne soit pas encore utilisée. Attendez quelques minutes et relancez le processus de vérification.
Utiliser TLS au lieu de mTLS
Dans cet exemple, utiliser TLS ne nécessite qu'une légère modification.
Dans
ServerTlsPolicy
, supprimezmtlsPolicy
:cat << EOF > server-tls-policy.yaml name: "server-tls-policy" serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe EOF
Utilisez plutôt cette règle dans
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
La règle
ClientTlsPolicy
pour mTLS fonctionne également dans le cas du protocole TLS, mais la sectionclientCertificate
de la règle peut être supprimée car elle n'est pas requise pour TLS :cat << EOF > client-tls-policy.yaml name: "client-tls-policy" serverValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffe EOF
Utiliser la sécurité du service avec l'exemple de portefeuille
Cette section explique sans entrer dans les détails comment activer l'exemple de portefeuille avec la sécurité du service pour Java, C++ et Go.
Java
Vous trouverez l'exemple de code source pour Java sur GitHub.
Le code utilise déjà les identifiants XdsChannel
et XdsServer
lorsque vous configurez la sécurité sans proxy.
Ces instructions décrivent comment configurer l'exemple de portefeuille avec Go. Le processus est le même pour Java. Les instructions utilisent une image Docker préexistante que vous obtenez dans le dépôt de conteneurs Google Cloud.
Pour créer l'exemple, procédez comme suit :
- Clonez le dépôt et déplacez les fichiers dans le répertoire d'exemples gRPC.
- Modifiez le fichier
00-common-env.sh
. Mettez en commentaire la ligne existante qui définit la valeur deWALLET_DOCKER_IMAGE
sur l'image Docker Go et annulez la mise en commentaire de la ligne qui définit la valeur deWALLET_DOCKER_IMAGE
sur l'image Docker Java. - Créez et configurez des instances Cloud Router en suivant les instructions de la section Créer et configurer des instances Cloud Router ou en utilisant la fonction
create_cloud_router_instances
du script10.apis.sh
. - Créez un cluster en suivant les instructions de l'exemple
hello world
ou en utilisant la fonctioncreate_cluster
du script20-cluster.sh
. - Créez des autorités de certification privées en suivant les instructions de CA Service ou en utilisant le script
30-private-ca-setup.sh
. - Créez des ressources Kubernetes, y compris des comptes de service, des espaces de noms, des services Kubernetes, des NEG et un déploiement côté serveur pour tous les services :
account
,stats
,stats_premium
,wallet_v1
etwallet_v2
à l'aide du script40-k8s-resources.sh
. - Pour chacun des services que vous avez créés, créez une vérification d'état et un service de backend en utilisant
create_health_check
etcreate_backend_service
dans le script50-td-components.sh
. - Créez les composants de routage Cloud Service Mesh à l'aide de
create_routing_components
dans le script60-routing-components.sh
. - Créez les composants de sécurité Cloud Service Mesh pour chaque service de backend à l'aide de
create_security_components
dans le script70-security-components.sh
. - Créez le déploiement du portefeuille client à l'aide de
create_client_deployment
dans le script75-client-deployment.sh
. - Vérifiez la configuration en lançant le client, comme décrit dans la section Vérifier avec les clients grpc-wallet.
C++
Vous trouverez l'exemple de code source pour C++ sur GitHub. Le code utilise déjà les identifiants XdsChannel
et XdsServer
lorsque vous configurez la sécurité sans proxy.
Ces instructions décrivent comment configurer l'exemple de portefeuille avec Go. Le processus est semblable pour C++. Les instructions utilisent une image Docker préexistante que vous obtenez dans le dépôt de conteneurs Google Cloud.
Pour créer l'exemple, procédez comme suit :
- Clonez le dépôt et déplacez les fichiers dans le répertoire d'exemples gRPC.
- Modifiez le fichier
00-common-env.sh
. Mettez en commentaire la ligne existante qui définit la valeur deWALLET_DOCKER_IMAGE
sur l'image Docker Go et annulez la mise en commentaire de la ligne qui définit la valeur deWALLET_DOCKER_IMAGE
sur l'image Docker C++. - Créez et configurez des instances Cloud Router en suivant les instructions de la section Créer et configurer des instances Cloud Router ou en utilisant la fonction
create_cloud_router_instances
du script10.apis.sh
. - Créez un cluster en suivant les instructions de l'exemple
hello world
ou en utilisant la fonctioncreate_cluster
du script20-cluster.sh
. - Créez des autorités de certification privées en suivant les instructions de Certificate Authority Service.
ou à l'aide du script
30-private-ca-setup.sh
. - Créez des ressources Kubernetes, y compris des comptes de service, des espaces de noms, des services Kubernetes, des NEG et un déploiement côté serveur pour tous les services :
account
,stats
,stats_premium
,wallet_v1
etwallet_v2
à l'aide du script40-k8s-resources.sh
. - Pour chacun des services que vous avez créés, créez une vérification d'état et un service de backend en utilisant
create_health_check
etcreate_backend_service
dans le script50-td-components.sh
. - Créez les composants de routage Cloud Service Mesh à l'aide de
create_routing_components
dans le script60-routing-components.sh
. - Créez les composants de sécurité Cloud Service Mesh pour chaque service de backend à l'aide de
create_security_components
dans le script70-security-components.sh
. - Créez le déploiement du portefeuille client à l'aide de
create_client_deployment
dans le script75-client-deployment.sh
. - Vérifiez la configuration en lançant le client, comme décrit dans la section Vérifier avec les clients grpc-wallet.
Go
Vous trouverez un exemple de code source pour Go sur GitHub. Le code utilise déjà les identifiants XdsChannel
et XdsServer
lorsque vous configurez la sécurité sans proxy.
Les instructions utilisent une image Docker préexistante que vous obtenez dans le dépôt de conteneurs Google Cloud.
Pour créer l'exemple, procédez comme suit :
- Clonez le dépôt et déplacez les fichiers dans le répertoire d'exemples gRPC.
- Modifiez le fichier
00-common-env.sh
afin de définir les valeurs appropriées pour les variables d'environnement. - Créez et configurez des instances Cloud Router en suivant les instructions de la section Créer et configurer des instances Cloud Router ou en utilisant la fonction
create_cloud_router_instances
du script10.apis.sh
. - Créez un cluster en suivant les instructions de l'exemple
hello world
ou en utilisant la fonctioncreate_cluster
du script20-cluster.sh
. - Créez des autorités de certification privées en suivant les instructions de CA Service ou en utilisant le script
30-private-ca-setup.sh
. - Créez des ressources Kubernetes, y compris des comptes de service, des espaces de noms, des services Kubernetes, des NEG et un déploiement côté serveur pour tous les services :
account
,stats
,stats_premium
,wallet_v1
etwallet_v2
à l'aide du script40-k8s-resources.sh
. - Pour chacun des services que vous avez créés, créez une vérification d'état et un service de backend en utilisant
create_health_check
etcreate_backend_service
dans le script50-td-components.sh
. - Créez les composants de routage Cloud Service Mesh à l'aide de
create_routing_components
dans le script60-routing-components.sh
. - Créez les composants de sécurité Cloud Service Mesh pour chaque service de backend à l'aide de
create_security_components
dans le script70-security-components.sh
. - Créez le déploiement du portefeuille client à l'aide de
create_client_deployment
dans le script75-client-deployment.sh
. - Vérifiez la configuration en lançant le client, comme décrit dans la section Vérifier avec les clients grpc-wallet.
Fichier d'amorçage
Le processus de configuration de ce guide utilise un générateur d'amorçage pour créer le fichier d'amorçage requis. Cette section fournit des informations de référence sur le fichier d'amorçage lui-même.
Le fichier d'amorçage contient les informations de configuration requises par le code gRPC sans proxy, y compris les informations de connexion pour le serveur xDS. Le fichier d'amorçage contient la configuration de sécurité requise par la fonctionnalité de sécurité gRPC sans proxy. Le serveur gRPC nécessite un champ supplémentaire. Voici un exemple de fichier d'amorçage :
{ "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" }
Mises à jour du fichier d'amorçage pour le service de sécurité
Les champs suivants reflètent les modifications liées à la sécurité et à l'utilisation de xDS v3 :
Le champ id
dans node
fournit une identité unique au client gRPC
Cloud Service Mesh. Vous devez fournir le numéro de projet Google Cloud et le nom du réseau à l'aide de l'ID de nœud au format suivant :
projects/{project number}/networks/{network name}/nodes/[UNIQUE_ID]
Par exemple, pour le projet numéro 1234, le réseau par défaut est :
projects/1234/networks/default/nodes/client1
Le champ INSTANCE_IP
correspond à l'adresse IP du pod, ou bien 0.0.0.0
correspond à INADDR_ANY
. Ce champ est utilisé par le serveur gRPC pour récupérer l'écouteur
Cloud Service Mesh pour la sécurité côté serveur.
Champs de configuration de la sécurité dans le fichier d'amorçage
Clé JSON | Type | Valeur | Remarques |
---|---|---|---|
server_listener_resource_name_template |
Chaîne | grpc/server?xds.resource.listening_address=%s |
Obligatoire pour les serveurs gRPC. gRPC utilise cette valeur pour composer le nom de la ressource permettant de récupérer la ressource "Écouteur" depuis Cloud Service Mesh pour la sécurité côté serveur et d'autres configurations. gRPC l'utilise pour former la chaîne de nom de ressource |
certificate_providers |
Structure JSON | google_cloud_private_spiffe |
Obligatoire. La valeur est une structure JSON représentant un mappage de noms à des instances de fournisseur de certificats. Une instance de fournisseur de certificats est utilisée pour récupérer les certificats d'identité et racine. L'exemple de fichier d'amorçage contient un nom : google_cloud_private_spiffe ayant comme valeur la structure JSON de l'instance du fournisseur de certificat. La structure JSON de chaque instance de fournisseur de certificats comporte deux champs :
|
La structure JSON config
du plug-in file_watcher
est la suivante :
certificate_file
: chaîne obligatoire. Cette valeur correspond à l'emplacement du certificat d'identité.private_key_file
: chaîne obligatoire. La valeur correspond à l'emplacement du fichier de clé privée, qui doit correspondre au certificat d'identité.ca_certificate_file
: chaîne obligatoire. La valeur correspond à l'emplacement du certificat racine, également appelé bundle d'approbations.refresh_interval
: chaîne facultative. La valeur indique l'intervalle d'actualisation, spécifié à l'aide de la représentation sous forme de chaîne du mappage JSON d'une durée. La valeur par défaut est "600s", soit une durée de 10 minutes.
Générateur d'amorçage
L'image de conteneur du générateur d'amorçage est disponible sur gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0
. Son code source est disponible à l'adresse https://github.com/GoogleCloudPlatform/traffic-director-grpc-bootstrap
.
Les options de ligne de commande les plus couramment utilisées sont les suivantes :
--output
: utilisez cette option pour spécifier l'emplacement où le fichier d'amorçage de sortie est écrit. Par exemple, la commande--output /tmp/bootstrap/td-grpc-bootstrap.json
génère le fichier d'amorçage pour/tmp/bootstrap/td-grpc-bootstrap.json
dans le système de fichiers du pod.--config-mesh-experimental
: utilisez cette option pour spécifier le nom du réseau maillé. correspondant à la ressourceMesh
.--node-metadata
: utilisez cette option pour renseigner les métadonnées du nœud dans le fichier d'amorçage. Cela est nécessaire lorsque vous utilisez des outils de mise en correspondance de libellés de métadonnées dansEndpointPolicy
, où Cloud Service Mesh utilise les données de libellés fournies dans la section des métadonnées de nœud du fichier d'amorçage. L'argument est fourni au format clé=valeur, par exemple :--node-metadata version=prod --node-metadata type=grpc
Les informations précédentes ajoutent les éléments suivants dans la section des métadonnées de nœud du d'amorçage:
{ "node": { ... "metadata": { "version": "prod", "type": "grpc", ... }, ... }, ... }
Supprimer le déploiement
Vous pouvez éventuellement exécuter ces commandes pour supprimer le déploiement que vous avez créé à l'aide de ce guide.
Pour supprimer le cluster, exécutez la commande suivante :
gcloud container clusters delete CLUSTER_NAME --zone ZONE --quiet
Pour supprimer les ressources que vous avez créées, exécutez les commandes suivantes :
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
Dépannage
Utilisez ces instructions pour vous aider à résoudre les problèmes de déploiement de sécurité.
Les charges de travail ne parviennent pas à obtenir la configuration à partir de Cloud Service Mesh
Si vous voyez une erreur semblable à celle-ci :
PERMISSION_DENIED: Request had insufficient authentication scopes.
Assurez-vous que :
- Vous avez créé votre cluster GKE avec l'argument
--scopes=cloud-platform
. - Vous avez attribué
roles/trafficdirector.client
à vos comptes de service Kubernetes. - Vous avez attribué
roles/trafficdirector.client
à votre service Google Cloud par défaut (${GSA_EMAIL} ci-dessus). - Vous avez activé le service
trafficdirector.googleapis.com
(API).
Votre serveur gRPC n'utilise pas le protocole TLS/mTLS, même avec la configuration Cloud Service Mesh appropriée
Assurez-vous de spécifier GRPC_SERVER
dans la configuration de vos règles de point de terminaison. Si vous avez spécifié SIDECAR_PROXY
, gRPC ignore la configuration.
Vous ne pouvez pas créer le cluster GKE avec la version de cluster demandée
La commande de création du cluster GKE peut échouer et renvoyer une erreur semblable à celle-ci :
Node version "1.20.5-gke.2000" is unsupported.
Assurez-vous d'utiliser l'argument --release-channel rapid
dans votre commande de création de cluster. Vous devez utiliser la version précoce pour obtenir la version appropriée.
Une erreur No usable endpoint
s'affiche.
Si un client ne peut pas communiquer avec le serveur en raison d'une erreur No usable endpoint
, il est possible que le vérificateur d'état ait signalé les backends du serveur comme non opérationnels.
Pour vérifier l'état des backends, exécutez la commande gcloud
suivante :
gcloud compute backend-services get-health grpc-gke-helloworld-service --global
Si la commande renvoie l'état du backend non opérationnel, cela peut être dû à l'une des raisons suivantes :
- Le pare-feu n'a pas été créé ou ne contient pas la plage d'adresses IP source appropriée.
- Les tags cibles de votre pare-feu ne correspondent pas aux tags du cluster que vous avez créé.
Les charges de travail ne parviennent pas à communiquer dans la configuration de sécurité
Si vos charges de travail ne parviennent pas à communiquer après que vous avez configuré la sécurité de votre maillage de services sans proxy, suivez ces instructions pour en déterminer la cause.
- Désactivez la sécurité sans proxy et éliminez les problèmes dans les cas d'utilisation de l'équilibrage de charge du maillage de services sans proxy. Pour désactiver la sécurité dans le maillage, effectuez l'une des opérations suivantes :
- Utilisez des identifiants en texte brut côté client et serveur, OU
- Ne configurez pas la sécurité du service de backend et de la règle de point de terminaison dans la configuration de Cloud Service Mesh.
Suivez les étapes décrites dans la section Résoudre les problèmes de déploiement sans proxy de Cloud Service Mesh, car votre déploiement ne comporte aucune configuration de sécurité.
Modifiez vos charges de travail pour utiliser des identifiants xDS en texte brut ou non sécurisés comme identifiants de remplacement. Gardez la sécurité désactivée dans la configuration de Cloud Service Mesh comme indiqué précédemment. Dans ce cas, bien que gRPC permette à Cloud Service Mesh de configurer la sécurité, Cloud Service Mesh n'envoie pas d'informations de sécurité, auquel cas gRPC doit revenir à des identifiants en texte brut (ou non sécurisés), ce qui devrait fonctionner semblable au premier cas précédent. Si ce cas ne fonctionne pas, procédez comme suit :
- Augmentez le niveau de journalisation côté client et côté serveur peuvent voir les messages xDS échangés entre gRPC et Cloud Service Mesh.
- Assurez-vous que Cloud Service Mesh n'a pas la sécurité activée dans les réponses CDS et LDS envoyées aux charges de travail.
- Assurez-vous que les charges de travail n'utilisent pas les modes TLS ou mTLS dans leurs canaux. Si des messages de journal liés aux handshakes TLS s'affichent, vérifiez le code source de votre application et assurez-vous d'utiliser des identifiants de remplacement non sécurisés ou en texte brut. Si le code source de l'application est correct, il peut s'agir d'un bug dans la bibliothèque gRPC.
Vérifiez que l'intégration du service CA avec GKE fonctionne correctement pour votre cluster GKE en suivant les étapes de dépannage décrites dans ce guide de l'utilisateur. Assurez-vous que les certificats et les clés fournis par cette fonctionnalité sont disponibles dans le répertoire spécifié,
/var/run/secrets/workload-spiffe-credentials/
.Activez TLS (au lieu de mTLS) dans votre réseau maillé, comme décrit précédemment, puis redémarrez. les charges de travail de vos clients et serveurs.
- Augmentez le niveau de journalisation côté client et côté serveur pour voir les messages xDS échangés entre gRPC et Cloud Service Mesh.
- Assurez-vous que Cloud Service Mesh a bien activé la sécurité dans les réponses CDS et LDS envoyées aux charges de travail.
Le client échoue avec une erreur CertificateException
et affiche un message Peer certificate SAN check failed
Cela indique un problème avec les valeurs subjectAltNames
du message SecuritySettings
. Notez que ces valeurs sont basées sur les services Kubernetes que vous avez créés pour votre service de backend. Chaque service Kubernetes que vous avez créé est associé à un ID SPIFFE, au format suivant :
spiffe://${WORKLOAD_POOL}/ns/${K8S_NAMESPACE}/sa/${SERVICE_ACCOUNT}
Ces valeurs sont les suivantes :
WORKLOAD_POOL
: pool de charges de travail du cluster, lui-même${PROJECT_ID}.svc.id.goog
K8S_NAMESPACE
: espace de noms Kubernetes que vous avez utilisé dans le déploiement du serviceSERVICE_ACCOUNT
: compte de service Kubernetes que vous avez utilisé dans le déploiement du service
Pour chaque service Kubernetes que vous avez associé à votre service de backend en tant que groupe de points de terminaison du réseau, assurez-vous que vous avez correctement calculé l'ID SPIFFE et que vous l'avez ajouté au champ subjectAltNames
dans le message SecuritySettings
.
Les applications ne peuvent pas utiliser les certificats mTLS avec votre bibliothèque gRPC
Si vos applications ne peuvent pas utiliser les certificats mTLS avec votre bibliothèque gRPC, procédez comme suit :
Vérifiez que la spécification de pod contient l'annotation
security.cloud.google.com/use-workload-certificates
décrite dans la section Créer un service gRPC sans proxy avec des NEG.Vérifiez que les fichiers contenant la chaîne de certificats ainsi que le certificat feuille, la clé privée et les certificats CA approuvés sont accessibles depuis les chemins d'accès suivants à partir du pod :
- Chaîne de certificats avec le certificat feuille : "/var/run/secrets/workload-spiffe-credentials/certificates.pem"
- Clé privée : "/var/run/secrets/workload-spiffe-credentials/private_key.pem"
- Bundle CA : "/var/run/secrets/workload-spiffe-credentials/ca_certificates.pem"
Si les certificats de l'étape précédente ne sont pas disponibles, procédez comme suit :
gcloud privateca subordinates describe SUBORDINATE_CA_POOL_NAME
--location=LOCATIONVérifiez que le plan de contrôle de GKE dispose de la liaison de rôle IAM correcte, en lui accordant l'accès au service CA :
# 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.
Vérifiez que le certificat n'a pas expiré. Il s'agit de la chaîne de certificats et du certificat feuille à l'emplacement
/var/run/secrets/workload-spiffe-credentials/certificates.pem
. Pour vérifier cela, exécutez la commande suivante :cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
Vérifiez que le type de clé est compatible avec votre application en exécutant la commande suivante :
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3
Vérifiez que votre application Java gRPC dispose de la propriété
keyAlgorithm
suivante dans le fichier YAMLWorkloadCertificateConfig
:
keyAlgorithm: rsa: modulusSize: 4096
Vérifiez que l'autorité de certification utilise la même famille de clés que la clé de certificat.
Le certificat d'une application est refusé par le client, le serveur ou le pair
- Vérifiez que l'application similaire utilise le même bundle d'approbations pour valider le certificat.
- Vérifiez que le certificat utilisé n'a pas expiré (chaîne de certificats avec le certificat feuille : "/var/run/secrets/workload-spiffe-credentials/certificates.pem").
Les pods restent à l'état "En attente"
Si les pods restent en attente pendant l'installation, augmentez les ressources de processeur et de mémoire des pods dans la spécification de votre déploiement.
Impossible de créer un cluster avec l'option --enable-mesh-certificates
Vérifiez que vous exécutez la dernière version de gcloud CLI :
gcloud components update
Notez que l'option --enable-mesh-certificates
ne fonctionne qu'avec gcloud beta
.
Les pods ne démarrent pas
Les pods qui utilisent des certificats de maillage GKE peuvent ne pas démarrer en cas d'échec du provisionnement de certificats. Cela peut se produire dans les situations suivantes :
- La configuration
WorkloadCertificateConfig
ouTrustConfig
est mal configurée ou est manquante. - Les CSR (Certificats Signing Request, demande de signature de certificat) ne sont pas approuvés.
Vous pouvez vérifier si le provisionnement du certificat échoue en vérifiant les événements du pod.
Vérifiez l'état de votre pod :
kubectl get pod -n POD_NAMESPACE POD_NAME
Remplacez l'élément suivant :
POD_NAMESPACE
: espace de noms de votre pod.POD_NAME
: nom de votre pod.
Vérifiez les événements récents pour votre pod :
kubectl describe pod -n POD_NAMESPACE POD_NAME
Si le provisionnement du certificat échoue, vous verrez un événement avec
Type=Warning
,Reason=FailedMount
,From=kubelet
et un champMessage
commençant parMountVolume.SetUp failed for volume "gke-workload-certificates"
. Le champMessage
contient des informations de dépannage.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)
Suivez les étapes de dépannage suivantes si vos pods ne démarrent pas en raison d'objets mal configurés ou de requêtes de signature de certificat refusées.
WorkloadCertificateConfig
ou TrustConfig
est mal configuré
Assurez-vous que vous avez correctement créé les objets WorkloadCertificateConfig
et TrustConfig
. Vous pouvez diagnostiquer les erreurs de configuration de ces objets à l'aide de kubectl
.
Récupérer l'état actuel
Pour
WorkloadCertificateConfig
:kubectl get WorkloadCertificateConfig default -o yaml
Pour
TrustConfig
:kubectl get TrustConfig default -o yaml
Inspectez le résultat de l'état. Un objet valide sera associé à une condition avec
type: Ready
etstatus: "True"
.status: conditions: - lastTransitionTime: "2021-03-04T22:24:11Z" message: WorkloadCertificateConfig is ready observedGeneration: 1 reason: ConfigReady status: "True" type: Ready
Pour les objets non valides,
status: "False"
apparaît à la place. Le champreason
etmessage
contiennent des informations de dépannage supplémentaires.
Les demandes de signature de certificat ne sont pas approuvées
Si une erreur se produit lors du processus d'approbation CSR, vous pouvez vérifier les détails de l'erreur dans les conditions type: Approved
et type: Issued
de la requête de signature de certificat.
Répertoriez les requêtes de signature de certificat pertinentes à l'aide de
kubectl
:kubectl get csr \ --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'
Choisissez une requête de signature de certificat qui soit
Approved
, et pasIssued
, ou qui n'est pasApproved
.Obtenez les détails de la requête de signature de certificat sélectionnée via kubectl :
kubectl get csr CSR_NAME -o yaml
Remplacez
CSR_NAME
par le nom de la requête de signature de certificat que vous avez choisie.
Une requête de signature de certificat valide comporte une condition avec type: Approved
et status: "True"
, ainsi qu'un certificat valide dans le champ 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
Les informations de dépannage pour les requête de signature de certificat non valides apparaissent dans les champs message
et reason
.
Il manque des certificats dans les pods.
Obtenez la spécification de pod de votre pod :
kubectl get pod -n POD_NAMESPACE POD_NAME -o yaml
Remplacez l'élément suivant :
POD_NAMESPACE
: espace de noms de votre pod.POD_NAME
: nom de votre pod.
Vérifiez que la spécification de pod contient l'annotation
security.cloud.google.com/use-workload-certificates
décrite dans la section Configurer les pods pour recevoir les identifiants mTLS.Vérifiez que le contrôleur d'admission des certificats de maillage GKE a injecté un volume de pilote CSI de type
workloadcertificates.security.cloud.google.com
dans la spécification de votre pod :volumes: ... -csi: driver: workloadcertificates.security.cloud.google.com name: gke-workload-certificates ...
Vérifiez la présence d'un montage de volume dans chacun des conteneurs :
containers: - name: ... ... volumeMounts: - mountPath: /var/run/secrets/workload-spiffe-credentials name: gke-workload-certificates readOnly: true ...
Vérifiez que les groupes de certificats et la clé privée suivants sont disponibles aux emplacements suivants dans le pod :
- Bundle de chaînes de certificats :
/var/run/secrets/workload-spiffe-credentials/certificates.pem
- Clé privée :
/var/run/secrets/workload-spiffe-credentials/private_key.pem
- Bundle d'ancrages de confiance CA :
/var/run/secrets/workload-spiffe-credentials/ca_certificates.pem
- Bundle de chaînes de certificats :
Si les fichiers ne sont pas disponibles, procédez comme suit :
Récupérez l'instance de service CA (Preview) du cluster :
kubectl get workloadcertificateconfigs default -o jsonpath '{.spec.certificateAuthorityConfig.certificateAuthorityServiceConfig.endpointURI}'
Récupérez l'état de l'instance du service CA (Preview) :
gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \ --location ISSUING_CA_LOCATION
Remplacez l'élément suivant :
ISSUING_CA_TYPE
: type d'autorité de certification émettrice, qui doit êtresubordinates
ouroots
.ISSUING_CA_NAME
: nom de l'autorité de certification émettrice.ISSUING_CA_LOCATION
: région de l'autorité de certification émettrice.
Obtenez la stratégie IAM pour l'autorité de certification racine :
gcloud privateca roots get-iam-policy ROOT_CA_NAME
Remplacez
ROOT_CA_NAME
par le nom de votre autorité de certification racine.Dans la stratégie IAM, vérifiez que la liaison de stratégie
privateca.auditor
existe bien :... - members: - serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com role: roles/privateca.auditor ...
Dans cet exemple,
PROJECT_NUMBER
est le numéro de projet de votre cluster.Obtenez la stratégie IAM pour l'autorité de certification subordonnée :
gcloud privateca subordinates get-iam-policy SUBORDINATE_CA_NAME
Remplacez
SUBORDINATE_CA_NAME
par le nom de l'autorité de certification subordonnée.Dans la stratégie IAM, vérifiez que la liaison de stratégie
privateca.certificateManager
existe :... - members: - serviceAccount: service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com role: roles/privateca.certificateManager ...
Dans cet exemple,
PROJECT_NUMBER
est le numéro de projet de votre cluster.
Les applications ne peuvent pas utiliser les identifiants mTLS émis
Vérifiez que le certificat n'a pas expiré :
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
Vérifiez que le type de clé que vous avez utilisé est compatible avec votre application.
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3
Vérifiez que l'autorité de certification émettrice utilise la même famille de clés que la clé de certificat.
Obtenez l'état de l'instance du service CA (Preview) :
gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \ --location ISSUING_CA_LOCATION
Remplacez l'élément suivant :
ISSUING_CA_TYPE
: type d'autorité de certification émettrice, qui doit êtresubordinates
ouroots
.ISSUING_CA_NAME
: nom de l'autorité de certification émettrice.ISSUING_CA_LOCATION
: région de l'autorité de certification émettrice.
Vérifiez que
keySpec.algorithm
dans le résultat est le même algorithme de clé que vous avez défini dans leWorkloadCertificateConfig
Fichier manifeste YAML. Le résultat ressemble à ceci :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 ...
Les certificats sont refusés
- Vérifiez que l'application similaire utilise le même bundle d'approbations pour valider le certificat.
Vérifiez que le certificat n'a pas expiré :
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
Vérifiez que le code client, si vous n'utilisez pas l'API d'actualisation des identifiants gRPC Go, actualise régulièrement les identifiants depuis le système de fichiers.
Vérifiez que vos charges de travail appartiennent au même domaine de confiance que votre autorité de certification. Les certificats de maillage GKE acceptent la communication entre les charges de travail d'un même domaine de confiance.
Limites
La sécurité des services Cloud Service Mesh n'est compatible qu'avec GKE. Vous ne pouvez pas déployer la sécurité du service avec Compute Engine.
Cloud Service Mesh n'est pas compatible avec les scénarios dans lesquels deux ressources de règles de point de terminaison ou plus correspondent à un même point de terminaison (par exemple, deux règles ayant les mêmes libellés et ports, ou bien deux règles ou plus ayant des libellés différents qui correspondent de manière identique aux libellés d'un point de terminaison). Pour en savoir plus sur la façon dont les stratégies des points de terminaison sont mises en correspondance avec les étiquettes d'un point de terminaison, consultez les API pour EndpointPolicy.EndpointMatcher.MetadataLabelMatcher. Dans ce cas, Cloud Service Mesh ne génère pas de configuration de sécurité de n'importe quelle règle en conflit.