Router le trafic des charges de travail Cloud Service Mesh vers les services Cloud Run

Cette page vous explique comment router de manière sécurisée le trafic réseau des charges de travail Cloud Service Mesh sur GKE vers les services Cloud Run.

Notez que lorsque vous routez le trafic de GKE vers Cloud Run, il n'est pas nécessaire que le service Cloud Run rejoigne Cloud Service Mesh. Toutefois, le service Cloud Run doit se trouver dans le même projet que le cluster GKE Cloud Service Mesh. Cette limitation existe tant que cette fonctionnalité est disponible en version Preview publique.

Avant de commencer

Les sections suivantes supposent que vous disposez des éléments suivants :

  1. Un cluster GKE avec Cloud Service Mesh activé.
  2. Un service Cloud Run déployé.

Vous pouvez également exécuter les commandes suivantes pour déployer un exemple de service Cloud Run.

  1. Générez un contexte kubeconfig pour votre cluster :

    gcloud container clusters get-credentials CLUSTER_NAME --project=PROJECT_ID  --location=CLUSTER_LOCATION
    

    Où :

    • CLUSTER_NAME correspond au nom de votre cluster.
    • PROJECT_ID correspond à l'ID de votre projet.
    • CLUSTER_LOCATION correspond à la région ou à la zone de votre cluster.
  2. Déployez un exemple de service Cloud Run :

    gcloud run deploy hello-world \
      --image=us-docker.pkg.dev/cloudrun/container/hello \
      --no-allow-unauthenticated \
      --port=8080 \
      --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com \
      --region=us-central1 \
      --project=PROJECT_ID
    

    Où :

    • PROJECT_NUMBER correspond au numéro de votre projet.
    • PROJECT_ID correspond à l'ID de votre projet.

Configurer IAM

Pour appeler des services Cloud Run, les vérifications Cloud Run Identity and Access Management (IAM) doivent être réussies. Vous devez accorder le rôle Demandeur Cloud Run au compte de service Google. Vous devez également configurer le compte de service Kubernetes (KSA) GKE pour qu'il emprunte l'identité du compte de service Google.

Procédez comme suit pour autoriser un compte de service Kubernetes à emprunter l'identité d'un compte de service Google.

  1. Ajoutez une liaison de stratégie IAM à un compte de service IAM :

    gcloud iam service-accounts add-iam-policy-binding PROJECT_NUMBER-compute@developer.gserviceaccount.com \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA]"
    

    Où :

    • NAMESPACE correspond au nom de l'espace de noms. Pour les besoins de ce guide, vous pouvez utiliser l'espace de noms default.
    • KSA correspond au nom du compte de service Kubernetes. Pour les besoins de ce guide, vous pouvez utiliser le KSA default.
  2. Annotez le compte de service :

    kubectl annotate serviceaccount KSA \
      --namespace NAMESPACE \
      iam.gke.io/gcp-service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com
    
  3. Accordez le rôle Demandeur Cloud Run au compte de service Google :

    gcloud run services add-iam-policy-binding hello-world \
      --region=us-central1 \
      --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
      --role="roles/run.invoker"
    

Configurer un service Cloud Run en tant que GCPBackend

Dans cette section, vous exposez le service Cloud Run aux charges de travail GKE à l'aide de GCPBackend. Le GCPBackend comprend les éléments suivants :

  1. Informations de frontend, en particulier le nom d'hôte et le port que les charges de travail GKE utiliseraient pour appeler ce GCPBackend.
  2. Informations de backend : détails du service Cloud Run, tels que le nom du service, l'emplacement et le numéro de projet.

Le GCPBackend contient les détails du nom d'hôte et du port, ainsi que les détails du service Cloud (nom du service, emplacement et numéro de projet). Les charges de travail GKE doivent utiliser le nom d'hôte et le port GCPBackend dans leurs requêtes HTTP pour accéder au service Cloud Run.

Pour que le nom d'hôte soit résolvable par DNS dans le cluster (par défaut, il ne l'est pas résolvable), vous devez configurer Google Cloud DNS pour qu'il résolve tous les hôtes sous un nom d'hôte choisi en une adresse IP arbitraire. Tant que vous n'avez pas configuré cette entrée DNS, la requête échoue. La configuration Google Cloud DNS est une configuration unique par domaine personnalisé.

  1. Créez une zone gérée :

    gcloud dns managed-zones create prod \
        --description="zone for gcpbackend" \
        --dns-name=gcpbackend \
        --visibility=private \
        --networks=default
    

    Dans cet exemple, le nom DNS est gcpbackend et le réseau VPC est default.

  2. Configurez l'enregistrement pour rendre le domaine résolvable :

    gcloud beta dns record-sets create *.gcpbackend \
      --ttl=3600 --type=A --zone=prod \
      --rrdatas=10.0.0.1
    
  3. Créez le GCPBackend avec un nom d'hôte sous le domaine précédent :

    cat <<EOF > gcp-backend.yaml
    apiVersion: networking.gke.io/v1
    kind: GCPBackend
    metadata:
      name: cr-gcp-backend
      namespace: NAMESPACE
    spec:
      hostname: hello-world.gcpbackend
      type: CloudRun
      cloudrun:
        service: hello-world
        regions: [us-central1]
    EOF
    kubectl apply -f gcp-backend.yaml
    

    Dans cet exemple, GCP_BACKEND_NAME est cr-gcp-backend.

  4. Créez un pod de test pour vérifier la connectivité entre GKE et Cloud Run :

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: testcurl
      namespace: default
    spec:
      containers:
      - name: curl
        image: curlimages/curl
        command: ["sleep", "3000"]
    EOF
    
    kubectl exec testcurl -c curl -- curl http://hello-world.gcpbackend/hello
    

    Vos charges de travail GKE peuvent désormais accéder au service Cloud Run en envoyant des requêtes HTTP à hello-world.gcpbackend/hello.

Vous devez utiliser des noms distincts pour GCPBackend afin d'éviter tout conflit avec les services Kubernetes existants ou les entrées de service Istio. En cas de conflit, l'ordre de priorité (du plus élevé au plus bas) est le suivant : service Kubernetes, entrée de service Istio et GCPBackend.

Notez que le service virtuel et le GCPBackend doivent se trouver dans le même espace de noms, et que le service Cloud Run doit se trouver dans le même projet que le cluster GKE Cloud Service Mesh.

(Facultatif) Utiliser le nom d'hôte de Cloud Run au lieu de Cloud DNS

Chaque service Cloud Run se voit attribuer un nom d'hôte (par exemple, hello-world.us-central1.run.app) et est résolvable par DNS à l'échelle mondiale. Vous pouvez utiliser ce nom d'hôte directement dans le nom d'hôte GCPBackend et ignorer la configuration Cloud DNS.

cat <<EOF | kubectl apply -f -
apiVersion: networking.gke.io/v1
kind: GCPBackend
metadata:
  name: cr-gcp-backend
  namespace: NAMESPACE
spec:
  hostname: hello-world.us-central1.run.app
  type: CloudRun
  cloudrun:
    service: hello-world
    region: [us-central1]
EOF

Vos charges de travail GKE peuvent désormais accéder au service Cloud Run en envoyant des requêtes HTTP à hello-world.us-central1.run.app.

(Facultatif) Configurer le service virtuel Istio et/ou la règle de destination

Vous pouvez configurer le service virtuel Istio ou la règle de destination Istio pour le nom d'hôte GCPBackend afin de définir des stratégies de consommateur ou de client pour les requêtes adressées au GCPBackend.

L'exemple suivant injecte un délai de 5 secondes dans 50 % des requêtes et abandonne (état HTTP 503) 10 % des requêtes adressées au GCPBackend.

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: cr-virtual-service
  namespace: NAMESPACE
spec:
  hosts:
  - hello-world.us-central1.run.app
  gateways:
  - mesh
  http:
  - fault:
      delay:
        percentage:
          value: 50  # Delay 50% of requests
        fixedDelay: 5s
      abort:
        percentage:
          value: 10  # Abort 10% of requests
        httpStatus: 503
  - route:
    - destination:
        host: hello-world.us-central1.run.app
EOF

Dans cet exemple, VIRTUAL_SERVICE_NAME est cr-virtual-service.

Dépannage

Cette section explique comment résoudre les erreurs courantes liées à Cloud Service Mesh et Cloud Run.

Journaux du side-car Cloud Run

Les erreurs Envoy sont consignées dans Cloud Logging.

Par exemple, une erreur semblable à la suivante sera consignée si le rôle client trafficdirector n'est pas attribué au compte de service Cloud Run dans le projet de maillage :

StreamAggregatedResources gRPC config stream to trafficdirector.googleapis.com:443 closed: 7, Permission 'trafficdirector.networks.getConfigs' denied on resource '//trafficdirector.googleapis.com/projects/525300120045/networks/mesh:test-mesh/nodes/003fb3e0c8927482de85f052444d5e1cd4b3956e82b00f255fbea1e114e1c0208dbd6a19cc41694d2a271d1ab04b63ce7439492672de4499a92bb979853935b03d0ad0' (or it may not exist).

CSDS

L'état du client trafficdirector peut être récupéré à l'aide de CSDS :

gcloud alpha container fleet mesh debug proxy-status --membership=<CLUSTER_MEMBERSHIP> --location=<CLUSTER_LOCATION>
External Clients:
....

Étape suivante