Rotear o tráfego dos serviços do Cloud Run para as cargas de trabalho do Cloud Service Mesh no GKE

Ao conectar os serviços do Cloud Run ao Cloud Service Mesh, é possível rotear o tráfego com segurança para cargas de trabalho no GKE. Essa configuração usa APIs do Istio e um arquivo secundário do Envoy totalmente gerenciado para processar a comunicação de serviço em todos os ambientes.

Antes de começar

As seções a seguir consideram que você tem um cluster do GKE com o Cloud Service Mesh ativado.

Se você não tiver um serviço do GKE implantado, use o seguinte comando para implantar um serviço de amostra:

cat <<EOF > /tmp/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: ads
spec:
  ports:
  - port: 9999
    targetPort: 8000
  selector:
    run: ads
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ads
spec:
  replicas: 1
  selector:
    matchLabels:
      run: ads
  template:
    metadata:
      labels:
        run: ads
    spec:
      containers:
      - image: docker.io/waip/simple-http:v1.0.1
        name: my-http2-svc
        ports:
        - protocol: TCP
          containerPort: 8000
      securityContext:
        fsGroup: 1337
EOF
kubectl apply -f /tmp/service.yaml

Configurar um domínio personalizado para hosts do VirtualService

Um serviço virtual define regras de roteamento de tráfego. Qualquer tráfego correspondente é enviado para um serviço de destino nomeado

  1. Para criar uma nova zona gerenciada, faça o seguinte:

    gcloud dns managed-zones create ZONE_NAME \
      --description="zone for service mesh routes" \
      --dns-name=DNS_SUFFIX. \
      --networks=default \
      --visibility=private
    

    em que:

    • ZONE_NAME é um nome para sua zona (exemplo: "prod").
    • DNS_SUFFIX é qualquer host DNS válido (exemplo: "mesh.private").
  2. Crie um conjunto de registros de recursos:

    IP=10.0.0.1
    gcloud dns record-sets create '*.'"DNS_SUFFIX." --type=A --zone="ZONE_NAME" \
      --rrdatas=10.0.0.1 --ttl 3600
    

    Verifique se o IP (RFC 1918 obrigatório) não está em uso. Como alternativa, reserve um IP interno estático.

  3. Exporte um VirtualService para clientes externos do Cloud Run:

    cat <<EOF > virtual-service.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: VIRTUAL_SERVICE_NAME
      namespace: NAMESPACE
    spec:
      hosts:
      - GKE_SERVICE_NAME.DNS_SUFFIX
      gateways:
      - external-mesh
      http:
      - route:
        - destination:
            host: GKE_SERVICE_NAME
    EOF
    kubectl apply -f virtual-service.yaml
    

    em que:

    • VIRTUAL_SERVICE_NAME é um nome para seu VirtualService.
    • NAMESPACE será default se você estiver usando o serviço de exemplo fornecido. Caso contrário, substitua NAMESPACE pelo nome do namespace.
    • GKE_SERVICE_NAME será ads se você estiver usando o serviço de exemplo fornecido. Caso contrário, substitua GKE_SERVICE_NAME por um nome para o serviço do GKE.

Embora seja possível adicionar um gateway do external-mesh como destino a um VirtualService preexistente, é necessário estabelecer um VirtualService distinto para exportar um serviço do Kubernetes para clientes externos do Cloud Run. Ter um VirtualService separado facilita o gerenciamento de serviços exportados e das configurações deles sem afetar os clientes atuais do GKE. Além disso, alguns campos em VirtualServices são desconsiderados para VirtualServices externo de malha, mas continuam funcionando conforme o esperado para serviços do GKE. Portanto, gerenciar e solucionar problemas de VirtualServices separadamente pode ser vantajoso.

Para que os clientes do GKE também recebam a configuração VirtualService, o gateway mesh ou mesh/default precisa ser adicionado.

O VirtualService externo da malha precisa ser definido no mesmo namespace que o serviço do Kubernetes no destino VirtualService.

Configurar um serviço do Cloud Run para participar de uma malha de serviço

Para mesclar um serviço do Cloud Run a uma malha de serviço, siga estas etapas:

  1. Determine o ID da malha que apoia o cluster do GKE do Cloud Service Mesh:

    MESH=$(kubectl get controlplanerevision --namespace istio-system -o json | jq -r '.items[0].metadata.annotations["mesh.cloud.google.com/external-mesh"]')
    
  2. Implante um serviço do Cloud Run usando o ID da malha, conectando-se também à rede VPC do cluster:

    gcloud alpha run deploy --mesh "$MESH" --network default \
      mesh-svc --image=fortio/fortio \
      --region=REGION --project=PROJECT_ID --no-allow-unauthenticated
    
  3. Verifique se o serviço do Cloud Run pode enviar uma solicitação para a carga de trabalho do GKE:

    TEST_SERVICE_URL=$(gcloud run services describe mesh-svc --region REGION --format="value(status.url)" --project=PROJECT_ID)
    
    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" "$TEST_SERVICE_URL/fortio/fetch/GKE_SERVICE_NAME.DNS_SUFFIX"
    

    A saída precisa ser uma resposta HTTP 200 válida.

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