Executar o proxy de serviço extensível localmente ou noutra plataforma

Esta página explica como configurar e executar uma instância do Extensible Service Proxy (ESP) numa máquina local, noutro fornecedor de serviços na nuvem, como os Amazon Web Services (AWS), ou num cluster do Kubernetes que não esteja no Google Cloud.

Pode executar o ESP num computador Linux ou macOS, ou numa máquina virtual (VM). O Microsoft Windows não é suportado. Pode implementar a sua aplicação e o ESP no mesmo anfitrião ou em anfitriões diferentes. A alojamento de uma instância local do ESP permite-lhe:

  • Experimente o ESP antes de o implementar numa plataforma de produção.
  • Verifique se as definições de segurança estão configuradas e a funcionar corretamente e se as métricas e os registos aparecem na página Endpoints > Serviços conforme esperado.

Pré-requisitos

Como ponto de partida, esta página pressupõe que:

Se precisar de uma API para testes com o ESP, pode configurar e implementar o código de exemplo na secção Opcional: usar uma API de exemplo. Se já configurou e implementou a sua API, avance para a secção Criar uma conta de serviço.

Opcional: usar uma API de exemplo

Esta secção explica como configurar e implementar a versão Python do exemplo getting-started para Endpoints localmente. Execute os passos nesta secção apenas se não tiver uma API para testar com o ESP.

O exemplo do Cloud Endpoints getting-started está disponível noutros idiomas. Consulte a página Samples para ver a localização do exemplo getting-started no GitHub no seu idioma preferido. Siga as instruções no ficheiro README.md do exemplo para execução local e, de seguida, siga as instruções nesta secção para configurar os Endpoints e implementar a configuração dos Endpoints.

Obtenha o software necessário

Se ainda não tiver configurado um ambiente de desenvolvimento Python, consulte o artigo Configurar um ambiente de desenvolvimento Python para obter orientações. Certifique-se de que tem o seguinte instalado:

Obtenha o exemplo de código

  1. Clone o repositório da app de exemplo para a sua máquina local:

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples
    
  2. Altere para o diretório que contém o código de exemplo:

    cd python-docs-samples/endpoints/getting-started
    

Configure pontos finais

  1. No diretório de código de exemplo, abra o ficheiro de configuração openapi.yaml.

    swagger: "2.0"
    info:
      description: "A simple Google Cloud Endpoints API example."
      title: "Endpoints Example"
      version: "1.0.0"
    host: "echo-api.endpoints.YOUR-PROJECT-ID.cloud.goog"
  2. No campo host, substitua YOUR-PROJECT-ID pelo seu Google Cloud ID do projeto.

  3. Guarde o ficheiro openapi.yaml.

Implementar a configuração dos pontos finais

Para implementar a configuração do Endpoints, use o comando gcloud endpoints services deploy. Este comando usa a gestão de serviços para criar um serviço gerido.

  1. Atualize a CLI gcloud:

    gcloud components update
  2. Certifique-se de que a CLI gcloud (gcloud) está autorizada a aceder aos seus dados e serviços em Google Cloud:

    gcloud auth login

    No novo separador do navegador apresentado, selecione uma conta.

  3. Defina o projeto predefinido para o ID do seu projeto:

    gcloud config set project YOUR-PROJECT-ID
    

    Substitua YOUR-PROJECT-ID pelo ID do projeto do projeto que especificou no ficheiroGoogle Cloud .openapi.yaml

  4. Implemente a sua configuração:

    gcloud endpoints services deploy openapi.yaml

A gestão de serviços usa o texto que especificou no campo host no ficheiro openapi.yaml para criar um novo serviço Endpoints com o nome echo-api.endpoints.YOUR-PROJECT-ID.cloud.goog (se não existir) e, em seguida, configura o serviço de acordo com o seu ficheiro de configuração OpenAPI.

À medida que cria e configura o serviço, a gestão de serviços envia informações para o terminal. Pode ignorar com segurança os avisos sobre os caminhos no ficheiro openapi.yaml que não requerem uma chave da API. Após a conclusão bem-sucedida, é apresentada uma linha semelhante à seguinte com o ID de configuração do serviço e o nome do serviço entre parênteses retos:

Service Configuration [2017-02-13r0] uploaded for service [echo-api.endpoints.example-project-12345.cloud.goog]

No exemplo anterior, 2017-02-13r0 é o ID de configuração do serviço e echo-api.endpoints.example-project-12345.cloud.goog é o nome do serviço.

Iniciar o servidor local

  1. Crie um virtualenv, ative-o e instale as dependências da aplicação.

    virtualenv env
    source env/bin/activate
    pip install -r requirements.txt
  2. Inicie o servidor:

    python main.py
    
  3. Abra outra janela de terminal e use curl para enviar um pedido:

    curl --request POST \
      --header "content-type:application/json" \
      --data '{"message":"hello world"}' \
      http://localhost:8080/echo
    

    A API devolve a mensagem que lhe envia e responde com o seguinte:

    {
    "message": "hello world"
    }

Criar uma conta de serviço

Para fornecer gestão para a sua API, o ESP e o ESPv2 requerem os serviços na infraestrutura de serviços. Para chamar estes serviços, o ESP e o ESPv2 têm de usar tokens de acesso. Quando implementa o ESP ou o ESPv2 em Google Cloud ambientes, como o GKE ou o Compute Engine, o ESP e o ESPv2 obtêm tokens de acesso para si através do Google Cloud serviço de metadados.

Quando implementa o ESP ou o ESPv2 num ambiente que não seja oGoogle Cloud , como o seu computador local, um cluster do Kubernetes no local ou outro fornecedor de nuvem, tem de fornecer um ficheiro JSON de conta de serviço que contenha uma chave privada. O ESP e o ESPv2 usam a conta de serviço para gerar tokens de acesso para chamar os serviços de que precisa para gerir a sua API.

Pode usar a Google Cloud consola ou a CLI Google Cloud para criar a conta de serviço e o ficheiro de chave privada:

Consola

  1. Na Google Cloud consola, abra a página Contas de serviço .

    Aceda à página Contas de serviço

  2. Clique em Selecionar um projeto.
  3. Selecione o projeto no qual a API foi criada e clique em Abrir.
  4. Clique em + Criar conta de serviço.
  5. No campo Nome da conta de serviço, introduza o nome da conta de serviço.
  6. Clique em Criar.
  7. Clique em Continuar.
  8. Clique em Concluído.
  9. Clique no endereço de email da conta de serviço recém-criada.
  10. Clique em Chaves.
  11. Clique em Adicionar chave e, de seguida, em Criar nova chave.
  12. Clique em Criar. É transferido um ficheiro de chave JSON para o seu computador.

    Certifique-se de que armazena o ficheiro de chave em segurança, uma vez que pode ser usado para autenticar como a sua conta de serviço. Pode mover e mudar o nome deste ficheiro como quiser.

  13. Clique em Fechar.

gcloud

  1. Introduza o seguinte para apresentar os IDs dos seus Google Cloud projetos:

    gcloud projects list
  2. Substitua PROJECT_ID no seguinte comando para definir o projeto predefinido para o projeto em que a sua API se encontra:

    gcloud config set project PROJECT_ID
  3. Certifique-se de que a CLI do Google Cloud (gcloud) está autorizada a aceder aos seus dados e serviços em Google Cloud:

    gcloud auth login

    Se tiver mais do que uma conta, certifique-se de que escolhe a conta que está no Google Cloud projeto em que a API se encontra. Se executar o comando gcloud auth list, a conta que selecionou é apresentada como a conta ativa para o projeto.

  4. Para criar uma conta de serviço, execute o seguinte comando e substitua SERVICE_ACCOUNT_NAME e My Service Account pelo nome e nome a apresentar que quer usar:

    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
       --display-name "My Service Account"

    O comando atribui um endereço de email à conta de serviço no seguinte formato:

    SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com

    Este endereço de email é necessário nos comandos subsequentes.

  5. Crie um ficheiro de chave de conta de serviço:

    gcloud iam service-accounts keys create ~/service-account-creds.json \
       --iam-account SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com

Adicione as funções IAM necessárias:

Esta secção descreve os recursos do IAM usados pelo ESP e pelo ESPv2, bem como as funções do IAM necessárias para que a conta de serviço anexada aceda a estes recursos.

Configuração do serviço de ponto final

O ESP e o ESPv2 chamam o Service Control, que usa a configuração do serviço de endpoint. A configuração do serviço de ponto final é um recurso do IAM, e o ESP e o ESPv2 precisam da função Service Controller para aceder a ele.

A função IAM está na configuração do serviço de ponto final e não no projeto. Um projeto pode ter várias configurações de serviços de pontos finais.

Use o seguinte comando gcloud para adicionar a função à conta de serviço anexada para a configuração do serviço de ponto final.

gcloud endpoints services add-iam-policy-binding SERVICE_NAME \
  --member serviceAccount:SERVICE_ACCOUNT_NAME@DEPLOY_PROJECT_ID.iam.gserviceaccount.com \
  --role roles/servicemanagement.serviceController

Onde
* SERVICE_NAME é o nome do serviço de ponto final
* SERVICE_ACCOUNT_NAME@DEPLOY_PROJECT_ID.iam.gserviceaccount.com é a conta de serviço anexada.

Cloud Trace

O ESP e o ESPv2 chamam o serviço Cloud Trace para exportar o rastreio para um projeto. Este projeto é denominado projeto de rastreio. No ESP, o projeto de rastreio e o projeto que detém a configuração do serviço de ponto final são os mesmos. No ESPv2, o projeto de rastreio pode ser especificado através da flag --tracing_project_id e é predefinido como o projeto de implementação.

O ESP e o ESPv2 requerem a função Agente do Cloud Trace para ativar o Cloud Trace.

Use o seguinte comando gcloud para adicionar a função à conta de serviço anexada:

gcloud projects add-iam-policy-binding TRACING_PROJECT_ID \
  --member serviceAccount:SERVICE_ACCOUNT_NAME@DEPLOY_PROJECT_ID.iam.gserviceaccount.com \
  --role roles/cloudtrace.agent

Onde
* TRACING_PROJECT_ID é o ID do projeto de rastreio
* SERVICE_ACCOUNT_NAME@DEPLOY_PROJECT_ID.iam.gserviceaccount.com é a conta de serviço anexada. Para mais informações, consulte o artigo O que são funções e autorizações?

Consulte gcloud iam service-accounts para mais informações sobre os comandos.

Executar o ESP num contentor

Esta secção descreve como implementar o contentor da ESP. O procedimento que usa depende do local onde implementa o contentor do ESP:

Nos exemplos seguintes, a opção ESP --http_port só funciona se o serviço gRPC tiver a transcodificação HTTP/JSON configurada. Para mais informações, consulte o artigo Transcodificação de HTTP/JSON para gRPC.

Executar o ESP num contentor Docker localmente ou noutra plataforma

  1. Mude o nome do ficheiro JSON que contém a chave privada da conta de serviço para service-account-creds.json e copie-o para $HOME/Downloads/ se tiver sido transferido para um diretório diferente. Desta forma, o caminho completo corresponde ao valor de --service_account_key no seguinte comando docker run.

  2. No comando docker run seguinte, substitua YOUR_SERVICE_NAME pelo nome do seu serviço.

Linux

sudo docker run \
    --detach \
    --name="esp" \
    --net="host" \
    --volume=$HOME/Downloads:/esp \
    --publish=8082 \
    gcr.io/endpoints-release/endpoints-runtime:1 \
    --service=YOUR_SERVICE_NAME \
    --rollout_strategy=managed \
    --http_port=8082 \
    --http2_port=8083 \
    --backend=grpc://localhost:8080 \
    --service_account_key=/esp/service-account-creds.json
  

mac OS

A opção --net="host" do Docker não funciona no macOS. Em alternativa, tem de fazer o mapeamento de portas explícito do anfitrião para o contentor, substituindo --net="host" por --publish 8082:8082. Também tem de substituir localhost pelo nome DNS especial apenas para macOS docker.for.mac.localhost. Consulte a secção Exemplos de utilização e soluções alternativas na documentação do Docker para mais informações.

sudo docker run \
  --detach \
  --name="esp" \
  --publish=8082:8082 \
  --volume=$HOME/Downloads:/esp \
  gcr.io/endpoints-release/endpoints-runtime:1 \
  --service=YOUR_SERVICE_NAME \
  --rollout_strategy=managed \
  --http_port=8082 \
  --http2_port=8083 \
  --backend=grpc://docker.for.mac.localhost:8080 \
  --service_account_key=/esp/service-account-creds.json
  

Outra plataforma

sudo docker run \
  --detach \
  --name="esp" \
  --net="host" \
  --volume=$HOME/Downloads:/esp \
  --publish=8082 \
  gcr.io/endpoints-release/endpoints-runtime:1 \
  --service=YOUR_SERVICE_NAME \
  --rollout_strategy=managed \
  --http_port=8082 \
  --http2_port=8083 \
  --backend=grpc://IP_Address:PORT \
  --service_account_key=/esp/service-account-creds.json
  

A tabela seguinte descreve as opções do Docker usadas nos comandos anteriores. Para ver informações sobre as opções de ESP usadas no exemplo, consulte as opções de arranque do ESP.

Opção Descrição
--detach Esta opção do Docker inicia o contentor no modo desanexado, pelo que é executado em segundo plano.
--name="esp" Esta opção do Docker fornece um nome de fácil acesso para o contentor. Por exemplo, para ver os registos do contentor, pode executar o comando docker logs esp
--net="host" Esta opção do Docker indica que o contentor do Docker usa a mesma configuração de rede que a máquina anfitriã, o que lhe permite fazer chamadas para localhost na máquina anfitriã. Esta opção não funciona para executar o ESP localmente no macOS.
--publish=8082:8082 Para o macOS, quando quiser executar o ESP localmente, use esta opção do Docker em vez de --net="host" para fazer o mapeamento de portas explícito do anfitrião para o contentor.
--volume=
$HOME/Downloads:/esp
Esta opção do Docker mapeia o diretório $HOME/Downloads local para o diretório /esp no contentor. Esta associação é usada pela opção ESP --service_account_key.

Execute o ESP num contentor num cluster do Kubernetes

Esta secção descreve como implementar o ESP num cluster do Kubernetes que não está no Google Cloud.

Para que a sua API seja gerida pelos Endpoints, implemente o contentor ESP no mesmo pod do Kubernetes que o contentor da API. O conjunto de pods que executam o ESP e a sua API estão agrupados num serviço Kubernetes através de um seletor de etiquetas, como app: my-api. O serviço Kubernetes especifica a política de acesso para equilibrar a carga dos pedidos do cliente para a porta do proxy.

  1. Mude o nome do ficheiro JSON que contém a chave privada da conta de serviço para service-account-creds.json e copie-o para $HOME/Downloads/ se tiver sido transferido para um diretório diferente. Desta forma, o caminho completo corresponde ao comando no passo seguinte.

  2. Execute o seguinte comando para criar um secret do Kubernetes e montar o secret como um volume do Kubernetes.

    kubectl create secret generic service-account-creds \
      --from-file=$HOME/Downloads/service-account-creds.json
    

    Em caso de êxito, é apresentada a seguinte mensagem: secret "service-account-creds" created

  3. No ficheiro de configuração do Kubernetes, adicione o seguinte, substituindo YOUR_APP_NAME pelo nome da sua API e YOUR_SERVICE_NAME pelo nome do seu serviço.

    spec:
    replicas: 1
    template:
      metadata:
        labels:
          app: "YOUR_APP_NAME"
      spec:
        volumes:
          - name: service-account-creds
            secret:
              secretName: service-account-creds
              containers:
          - name: esp
            image: gcr.io/endpoints-release/endpoints-runtime:1
            args: [
              "--http_port=8082",
              "--http2_port=8083",
              "--backend=grpc://127.0.0.1:8081",
              "--service=YOUR_SERVICE_NAME",
              "--rollout_strategy=managed",
              "--service_account_key=/etc/nginx/creds/service-account-creds.json"
            ]
            ports:
              - containerPort: 8080
            volumeMounts:
              - mountPath: /etc/nginx/creds
                name: service-account-creds
                readOnly: true
    

    Para ver informações sobre as opções de ESP usadas no exemplo, consulte as opções de arranque do ESP.

  4. Implemente o ESP no Kubernetes. Substitua YOUR_CONFIGURATION_FILE pelo nome do seu ficheiro de configuração do Kubernetes.

    kubectl apply -f YOUR_CONFIGURATION_FILE

A enviar pedidos

Para confirmar que o ficheiro da conta de serviço está correto e que as portas estão mapeadas corretamente, envie alguns pedidos para a sua API e certifique-se de que os pedidos estão a passar pelo ESP. Pode ver os registos do ESP executando:

sudo docker logs esp

Os exemplos seguintes enviam pedidos para a API de exemplo. Se não estiver a usar a API de exemplo, recomendamos que execute testes semelhantes.

Configurou o contentor do ESP para receber pedidos na porta 8082. Se enviar um pedido diretamente para o servidor em http://localhost:8080, o pedido ignora o ESP. Por exemplo:

curl --request POST \
  --header "content-type:application/json" \
  --data '{"message":"hello world"}' \
  http://localhost:8080/echo

Resposta:

  {
    "message": "hello world"
  }

Quando envia um pedido para http://localhost:8082 que passa pelo ESP e não envia uma chave API, o ESP rejeita o pedido. Por exemplo:

curl --request POST \
  --header "content-type:application/json" \
  --data '{"message":"hello world"}' \
  http://localhost:8082/echo

Resposta:

  {
   "code": 16,
   "message": "Method doesn't allow unregistered callers (callers without
    established identity). Please use API Key or other form of API consumer
    identity to call this API.",
   "details": [
    {
     "@type": "type.googleapis.com/google.rpc.DebugInfo",
     "stackEntries": [],
     "detail": "service_control"
    }
   ]
  }

Para testar a API com uma chave da API:

  1. Crie uma chave da API na página Credenciais da API.

    Aceda à página Credenciais

  2. Clique em Criar credenciais e, de seguida, selecione Chave da API.

  3. Copie a chave e, em seguida, cole-a na seguinte declaração de variável de ambiente:

    export KEY=AIza...
    
  4. Envie um pedido com a chave:

    curl --request POST \
      --header "content-type:application/json" \
      --data '{"message":"hello world"}' \
      http://localhost:8082/echo?key=$KEY

    Vê uma resposta bem-sucedida:

    {
      "message": "hello world"
    }

Limpar

Encerre e remova o contentor esp do Docker com a ferramenta docker:

    sudo docker stop esp
    sudo docker rm esp
Se quiser limpar a configuração do serviço implementado, consulte o artigo Eliminar uma API e instâncias da API.

O que se segue?