Encaminhar o tráfego de cargas de trabalho do Cloud Service Mesh para os serviços do Cloud Run

A integração do Cloud Run com o Cloud Service Mesh permite rotear com segurança o tráfego de cargas de trabalho do GKE para back-ends sem servidor. Os serviços do Cloud Run não precisam se juntar à malha de serviço para receber tráfego.

Essa integração é compatível com o Cloud Service Mesh com APIs do Istio e não é compatível com APIs doGoogle Cloud . Enquanto esse recurso estiver em pré-lançamento público, o serviço do Cloud Run precisará residir no mesmo projeto do Google Cloud que o cluster do GKE.

Antes de começar

As seções a seguir consideram que você tem:

  1. Um cluster do GKE com o Cloud Service Mesh ativado.
  2. Implantou um serviço do Cloud Run.

Como alternativa, execute os comandos a seguir para implantar um serviço de amostra do Cloud Run.

  1. Gere um contexto kubeconfig para o cluster:

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

    Em que:

    • CLUSTER_NAME é o nome do cluster.
    • PROJECT_ID é o ID do projeto.
    • CLUSTER_LOCATION é a região ou zona do cluster.
  2. Implante um serviço de amostra do 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
    

    Em que:

    • PROJECT_NUMBER é o número do projeto.
    • PROJECT_ID é o ID do projeto.

Configurar o IAM

Para invocar serviços do Cloud Run, as verificações do Identity and Access Management (IAM) do Cloud Run precisam ser aprovadas. É preciso conceder o papel de invocador do Cloud Run à conta de serviço do Google. Também é necessário configurar a conta de serviço do Kubernetes (KSA) do GKE para personificar a conta de serviço do Google.

Siga as etapas abaixo para permitir que uma conta de serviço do Kubernetes represente uma conta de serviço do Google.

  1. Adicione uma vinculação de política do IAM a uma conta de serviço do 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]"
    

    Em que:

    • NAMESPACE é o nome do namespace. Para os fins deste guia, use o namespace default.
    • KSA é o nome da conta de serviço do Kubernetes. Para os fins deste guia, use a KSA default.
  2. Anote a conta de serviço:

    kubectl annotate serviceaccount KSA \
      --namespace NAMESPACE \
      iam.gke.io/gcp-service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com
    
  3. Conceda o papel de invocador do Cloud Run à conta de serviço do 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"
    

Configurar um serviço do Cloud Run como um GCPBackend

Nesta seção, você vai expor o serviço do Cloud Run às cargas de trabalho do GKE usando o GCPBackend. O GCPBackend consiste em:

  1. Informações de front-end, especificamente o nome do host e a porta que as cargas de trabalho do GKE usariam para chamar esse GCPBackend.
  2. Informações de back-end: os detalhes do serviço do Cloud Run, como nome, local e número do projeto.

O GCPBackend contém os detalhes do nome do host e da porta, bem como os detalhes do serviço do Cloud (nome do serviço, local e número do projeto). As cargas de trabalho do GKE precisam usar o nome do host e a porta do GCPBackend nas solicitações HTTP para acessar o serviço do Cloud Run.

Para tornar o nome do host DNS resolvível no cluster (por padrão, ele não é resolvível), configure o DNS do Google Cloud para resolver todos os hosts em um nome do host escolhido para um endereço IP arbitrário. Até que você configure essa entrada de DNS, a solicitação vai falhar. A configuração de DNS do Google Cloud é uma configuração única por domínio personalizado.

  1. Crie uma zona gerenciada:

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

    Neste exemplo, o nome DNS é gcpbackend e a rede VPC é default.

  2. Configure o registro para que o domínio possa ser resolvido:

    gcloud beta dns record-sets create *.gcpbackend \
      --ttl=3600 --type=A --zone=prod \
      --rrdatas=10.0.0.1
    
  3. Crie o GCPBackend com um nome de host no domínio anterior:

    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
    

    Neste exemplo, GCP_BACKEND_NAME é cr-gcp-backend.

  4. Crie um pod de teste para verificar a conectividade do GKE com o 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
    

    Agora, as cargas de trabalho do GKE podem acessar o serviço do Cloud Run enviando solicitações HTTP para hello-world.gcpbackend/hello.

Use nomes distintos para o GCPBackend para evitar conflitos com os serviços do Kubernetes ou as entradas de serviço do Istio. Se houver conflito, a ordem de precedência (da mais alta para a mais baixa) será Serviço do Kubernetes, ServiceEntry do Istio e GCPBackend.

O serviço virtual e o GCPBackend precisam estar no mesmo namespace, e o serviço do Cloud Run precisa estar no mesmo projeto que o cluster do GKE do Cloud Service Mesh.

(Opcional) Usar o nome do host do Cloud Run em vez do Cloud DNS

Cada serviço do Cloud Run recebe um nome de host (por exemplo, hello-world.us-central1.run.app) e é resolvível por DNS globalmente. É possível usar esse nome do host diretamente no nome do host do GCPBackend e pular a configuração do 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

Agora, as cargas de trabalho do GKE podem acessar o serviço do Cloud Run enviando solicitações HTTP para hello-world.us-central1.run.app.

(Opcional) Configurar o serviço virtual do Istio e/ou a regra de destino

É possível configurar o serviço virtual do Istio ou a regra de destino do Istio para o nome do host do GCPBackend para definir políticas de consumidor ou cliente para solicitações ao GCPBackend.

O exemplo a seguir injeta um atraso de 5s em 50% das solicitações e cancela (status HTTP 503) 10% das solicitações que vão para o 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

Neste exemplo, VIRTUAL_SERVICE_NAME é cr-virtual-service.

Solução de problemas

Nesta seção, mostramos como resolver problemas comuns com o Cloud Service Mesh e o Cloud Run.

Registros de sidecar do Cloud Run

Os erros do Envoy são registrados no Cloud Logging.

Por exemplo, um erro como o seguinte será registrado se a conta de serviço do Cloud Run não receber o papel de cliente do Traffic Director no projeto de malha:

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

O estado do cliente do Traffic Director pode ser recuperado usando o CSDS:

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

A seguir