Primeiros passos com o Endpoints para GKE com ESPv2


Neste tutorial, você aprende a implantar um exemplo simples do serviço gRPC com o Extensible Service Proxy V2 (ESPv2) no Google Kubernetes Engine (GKE). Este tutorial usa a versão Python da amostra bookstore-grpc. Consulte as amostras de gRPC em outras linguagens na seção A seguir.

Neste tutorial, são usadas imagens de contêiner predefinidas do código de amostra e do ESPv2, que são armazenadas no Artifact Registry. Se você não está familiarizado com os contêineres, consulte as páginas a seguir para saber mais:

Para uma visão geral do Cloud Endpoints, consulte Sobre o Endpoints e Arquitetura do Endpoints.

Objetivos

Ao seguir o tutorial, use a lista detalhada de tarefas abaixo. Em todas elas, é necessário que as solicitações para a API sejam enviadas com sucesso.

  1. Configure um projeto do Google Cloud e faça o download do software necessário. Consulte Antes de começar.
  2. Copie e configure arquivos da amostra bookstore-grpc. Consulte Como configurar o Endpoints.
  3. Implante a configuração do Endpoints para criar um serviço dele. Consulte Como implantar a configuração do Endpoints.
  4. Crie um back-end para exibir a API e implante-a. Consulte Como implantar o back-end da API.
  5. Consiga o endereço IP externo do serviço. Consulte Como conseguir o endereço IP externo do serviço.
  6. Envie uma solicitação para a API. Consulte Como enviar uma solicitação para a API.
  7. Evite cobranças na sua conta do Google Cloud. Consulte Limpeza.

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Saiba mais em Limpeza.

Antes de começar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Anote o ID do projeto do Google Cloud porque ele será necessário posteriormente.
  7. Instale e inicialize a Google Cloud CLI.
  8. Atualize a CLI gcloud e instale os componentes do Endpoints.
    gcloud components update
  9. Verifique se a Google Cloud CLI (gcloud) está autorizada a acessar seus dados e serviços no Google Cloud:
    gcloud auth login
    Uma nova guia do navegador será aberta e você precisará escolher uma conta.
  10. Defina o projeto padrão como o ID do projeto.
    gcloud config set project YOUR_PROJECT_ID

    Substitua YOUR_PROJECT_ID pela ID do seu projeto.

    Se você tiver outros projetos do Google Cloud e quiser usar gcloud para gerenciá-los, consulte Como gerenciar configurações da CLI gcloud.

  11. Instale kubectl:
    gcloud components install kubectl
  12. Consiga novas credenciais de usuário a serem usadas como credenciais padrão do aplicativo. As credenciais do usuário são necessárias para autorizar kubectl.
    gcloud auth application-default login
    Na nova guia aberta do navegador, escolha uma conta.
  13. Siga as etapas no Guia de início rápido do gRPC para Python (em inglês) para instalar o gRPC e as ferramentas dele.

Como configurar o Endpoints

A amostra bookstore-grpc contém os arquivos necessários para fazer cópias locais e configurações.

  1. Crie um arquivo descritor protobuf autocontido a partir do seu arquivo de serviço .proto:
    1. Salve uma cópia de bookstore.proto do repositório de exemplo. Esse arquivo define a API do serviço Bookstore.
    2. Crie o seguinte diretório: mkdir generated_pb2
    3. Crie o arquivo de descritor, api_descriptor.pb, usando o compilador de buffers de protocolo protoc. Execute o seguinte comando no diretório onde você salvou bookstore.proto:
      python -m grpc_tools.protoc \
          --include_imports \
          --include_source_info \
          --proto_path=. \
          --descriptor_set_out=api_descriptor.pb \
          --python_out=generated_pb2 \
          --grpc_python_out=generated_pb2 \
          bookstore.proto

      No comando anterior, --proto_path está definido como o diretório de trabalho atual. No ambiente da versão do gRPC, caso você use um diretório diferente para arquivos de entrada .proto, mude --proto_path para que o compilador pesquise o diretório em que salvou bookstore.proto.

  2. Crie um arquivo YAML de configuração da API gRPC:
    1. Salve uma cópia do arquivo api_config.yaml. Esse arquivo define a configuração da API gRPC do serviço Bookstore.
    2. Substitua MY_PROJECT_ID no arquivo api_config.yaml pelo ID do projeto do Google Cloud. Exemplo:
      #
      # Name of the service configuration.
      #
      name: bookstore.endpoints.example-project-12345.cloud.goog
      

      Observe que o valor do campo apis.name neste arquivo corresponde exatamente ao nome da API totalmente qualificado do arquivo .proto; caso contrário, a implantação não funcionará. O serviço Bookstore é definido em bookstore.proto dentro do pacote endpoints.examples.bookstore. O nome da API totalmente qualificado é endpoints.examples.bookstore.Bookstore, assim como aparece no arquivo api_config.yaml.

      apis:
        - name: endpoints.examples.bookstore.Bookstore

Para saber mais, consulte Como configurar o Endpoints.

Como implantar a configuração do Endpoints

Para implantar a configuração do Endpoints, use o comando gcloud endpoints services deploy. Ele utiliza o Service Management para criar um serviço gerenciado.

  1. Verifique se você está no diretório onde os arquivos api_descriptor.pb e api_config.yaml estão localizados.
  2. Confirme se o projeto padrão que a ferramenta de linha de comando gcloud está usando no momento é o projeto do Google Cloud em que você pretende implantar a configuração do Endpoints. Valide o código do projeto retornado do comando a seguir para garantir que o serviço não seja criado no projeto incorreto.
    gcloud config list project
    

    Se você precisar alterar o projeto padrão, execute o comando:

    gcloud config set project YOUR_PROJECT_ID
    
  3. Implante o arquivo proto descriptor e o arquivo de configuração usando a Google Cloud CLI:
    gcloud endpoints services deploy api_descriptor.pb api_config.yaml
    

    Durante a criação e a configuração do serviço, o Service Management envia informações ao terminal. Quando a implantação for concluída, uma mensagem parecida com esta será exibida:

    Service Configuration [CONFIG_ID] uploaded for service [bookstore.endpoints.example-project.cloud.goog]

    CONFIG_ID é o ID exclusivo de configuração de serviço do Endpoints criado pela implantação. Exemplo:

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

    No exemplo anterior, 2017-02-13r0 é o ID de configuração do serviço e bookstore.endpoints.example-project.cloud.goog é o nome do serviço. O código de configuração do serviço consiste em um carimbo de data e um número de revisão. Se você implantar novamente a configuração do Endpoints no mesmo dia, o número de revisão será alterado no código da configuração do serviço.

Como verificar os serviços obrigatórios

No mínimo, o Endpoints e o ESP exigem a ativação dos seguintes serviços do Google:
Nome Título
servicemanagement.googleapis.com API Service Management
servicecontrol.googleapis.com API Service Control

Na maioria dos casos, o comando gcloud endpoints services deploy ativa os serviços necessários. No entanto, o comando gcloud é concluído com êxito, mas não ativa os serviços necessários nas seguintes circunstâncias:

  • Você usou um aplicativo de terceiros, como o Terraform, e não incluiu esses serviços.

  • Você implantou a configuração do Endpoints em um projeto do Google Cloud existente, em que esses serviços foram desativados explicitamente.

Use o seguinte comando para confirmar se os serviços necessários estão ativados:

gcloud services list

Se você não encontrar os serviços necessários listados, ative-os:

gcloud services enable servicemanagement.googleapis.com
gcloud services enable servicecontrol.googleapis.com

Ative também seu serviço do Endpoints:

gcloud services enable ENDPOINTS_SERVICE_NAME

Para determinar o ENDPOINTS_SERVICE_NAME, é possível:

  • Após implantar a configuração de Endpoints, acesse a página Endpoints no Console do Cloud. A lista de ENDPOINTS_SERVICE_NAME possíveis é mostrada na coluna Nome do serviço.

  • Para a OpenAPI, o ENDPOINTS_SERVICE_NAME é o que você especificou no campo host da especificação do OpenAPI. Para gRPC, o ENDPOINTS_SERVICE_NAME é o que você especificou no campo name da configuração do gRPC Endpoints.

Para mais informações sobre os comandos gcloud, consulte serviços gcloud.

Se você receber uma mensagem de erro, consulte Como solucionar problemas de implantação na configuração do Endpoints.

Para mais informações, consulte Como implantar a configuração do Endpoints.

Como implantar o back-end da API

Até agora, você implantou a configuração do serviço no Service Management, mas não o código que exibe o back-end da API. Nesta seção, você aprenderá a criar um cluster do GKE para hospedar o back-end da API e implantá-la.

Criar um cluster de contêiner

O cluster precisa de um alias de IP para usar o balanceamento de carga nativo de contêiner. Para criar um cluster de contêiner com um alias de IP para nosso exemplo:

gcloud container clusters create espv2-demo-cluster \
    --enable-ip-alias \
    --create-subnetwork="" \
    --network=default \
    --zone=us-central1-a

O comando acima cria um cluster, espv2-demo-cluster, com uma sub-rede provisionada automaticamente na zona us-central1-a.

Como autenticar kubectl no cluster de contêiner

Para criar e gerenciar recursos do cluster com kubectl, é preciso ter credenciais do cluster disponíveis para kubectl. Para isso, execute o comando a seguir, substituindo NAME pelo nome do novo cluster e ZONE pela zona do cluster.

gcloud container clusters get-credentials NAME --zone ZONE

Como verificar as permissões necessárias

O ESP e o ESPv2 chamam os serviços do Google que usam o IAM para verificar se a identidade da chamada tem permissões suficientes para acessar os recursos do IAM usados. A identidade de chamada é a conta de serviço anexada que implanta o ESP e o ESPv2.

Quando implantada no pod do GKE, a conta de serviço anexada é a conta de serviço do nó. Ela costuma ser a conta de serviço padrão do Compute Engine. Siga esta recomendação de permissão para escolher uma conta de serviço de nó adequada.

Se a Identidade da carga de trabalho for usada, uma conta de serviço separada diferente da conta de serviço do nó poderá ser usada para falar com os serviços do Google. É possível criar uma conta de serviço do Kubernetes para o pod executar o ESP e o ESPv2. Além disso, você pode criar uma conta de serviço do Google e associá-la à do Kubernetes.

Siga estas etapas para associar uma conta de serviço do Kubernetes a uma conta de serviço do Google. Esta conta de serviço do Google é a conta de serviço anexada.

Se a conta de serviço anexada for a conta de serviço padrão do Compute Engine do projeto e a configuração do serviço do endpoint for implantada no mesmo projeto, a conta de serviço já deve ter permissões suficientes para acessar os recursos do IAM, então a etapa a seguir pode ser pulada. Caso contrário, adicione os papéis do IAM à conta de serviço anexada.

Adicione os papéis necessários do IAM:

Nesta seção, descrevemos os recursos do IAM que o ESP e o ESPv2 usam, além dos papéis do IAM necessários para que a conta de serviço anexada acesse esses recursos.

Configuração do serviço de endpoint

O ESP e o ESPv2 chamam o Service Control, que usa a configuração do serviço do endpoint. A configuração do serviço do endpoint é um recurso do IAM, e o ESP e o ESPv2 precisam do papel Controlador de serviço para acessá-lo.

O papel do IAM está na configuração do serviço do endpoint, não no projeto. Os projetos podem ter várias configurações de serviço de endpoint.

Use o comando gcloud a seguir para adicionar o papel à conta de serviço anexada na configuração do serviço do endpoint.

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

Em que
* SERVICE_NAME é o nome do serviço do endpoint
* 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 Trace para um projeto. Esse projeto é chamado de projeto de rastreamento. No ESP, o projeto de rastreamento e o projeto que tem a configuração do serviço de endpoint são os mesmos. No ESPv2, o projeto de rastreamento pode ser especificado pela sinalização --tracing_project_id e assume como padrão o projeto de implantação.

O ESP e o ESPv2 exigem o papel Agente do Cloud Trace para ativar o Cloud Trace.

Use o seguinte comando gcloud para adicionar o papel à 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

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

Como configurar chaves e certificados SSL

O balanceamento de carga nativo do contêiner usa o HTTP2 LB, que precisa ser criptografado por TLS. Isso exigiu a implantação de um certificado TLS na entrada do GKE e no ESPv2. É possível trazer seu próprio certificado ou usar um certificado autoassinado.

  1. Crie um certificado e uma chave autoassinados usando openssl. Verifique se você inseriu o mesmo FQDN bookstore.endpoints.MY_PROJECT_ID.cloud.goog quando solicitado por "Nome comum(CN)". Esse nome é usado pelos clientes para verificar o certificado do servidor.

    openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout ./server.key -out ./server.crt
  2. Crie um segredo do Kubernetes com o certificado e a chave SSL. O certificado é copiado para dois lugares, server.crt e tls.crt, já que o segredo é fornecido para a entrada do GKE e o ESPv2. A entrada do GKE procura o caminho de certificado tls.crt e o ESPv2 procura o caminho do certificado server.crt.

    kubectl create secret generic esp-ssl \
    --from-file=server.crt=./server.crt --from-file=server.key=./server.key \
    --from-file=tls.crt=./server.crt --from-file=tls.key=./server.key

Como implantar a API de amostra e o ESPv2 no cluster

Veja como implantar o exemplo do serviço do gRPC no cluster a ser usado pelos clientes:

  1. git clone este repo e abra para editar o arquivo de manifesto de implantação grpc-bookstore.yaml.
  2. Substitua SERVICE_NAME pelo nome do serviço do Endpoints para o contêiner Ingress e o ESPv2. Este é o mesmo nome configurado no campo name do arquivo api_config.yaml.
    # Copyright 2016 Google Inc.
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License
    
    # Use this file to deploy the container for the grpc-bookstore sample
    # and the container for the Extensible Service Proxy (ESP) to
    # Google Kubernetes Engine (GKE).
    
    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: esp-grpc-bookstore
      annotations:
        kubernetes.io/ingress.class: "gce"
        kubernetes.io/ingress.allow-http: "false"
    spec:
      tls:
      - hosts:
        - SERVICE_NAME
        secretName: esp-ssl
      backend:
        serviceName: esp-grpc-bookstore
        servicePort: 443
    ---
    apiVersion: cloud.google.com/v1
    kind: BackendConfig
    metadata:
      name: esp-grpc-bookstore
    spec:
      healthCheck:
        type: HTTP2
        requestPath: /healthz
        port: 9000
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: esp-grpc-bookstore
      annotations:
        service.alpha.kubernetes.io/app-protocols: '{"esp-grpc-bookstore":"HTTP2"}'
        cloud.google.com/neg: '{"ingress": true, "exposed_ports": {"443":{}}}'
        cloud.google.com/backend-config: '{"default": "esp-grpc-bookstore"}'
    spec:
      ports:
      # Port that accepts gRPC and JSON/HTTP2 requests over TLS.
      - port: 443
        targetPort: 9000
        protocol: TCP
        name: esp-grpc-bookstore
      selector:
        app: esp-grpc-bookstore
      type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: esp-grpc-bookstore
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: esp-grpc-bookstore
      template:
        metadata:
          labels:
            app: esp-grpc-bookstore
        spec:
          volumes:
          - name: esp-ssl
            secret:
              secretName: esp-ssl
          containers:
          - name: esp
            image: gcr.io/endpoints-release/endpoints-runtime:2
            args: [
              "--listener_port=9000",
              "--service=SERVICE_NAME",
              "--rollout_strategy=managed",
              "--backend=grpc://127.0.0.1:8000",
              "--healthz=/healthz",
              "--ssl_server_cert_path=/etc/esp/ssl",
            ]
            ports:
              - containerPort: 9000
            volumeMounts:
            - mountPath: /etc/esp/ssl
              name:  esp-ssl
              readOnly: true
          - name: bookstore
            image: gcr.io/endpointsv2/python-grpc-bookstore-server:1
            ports:
              - containerPort: 8000
    

    A opção --rollout_strategy=managed configura o ESPv2 para usar a implantação mais recente da configuração do serviço. Ao especificar essa opção, a alteração é detectada pelo ESPv2 em até um minuto após a implantação de uma nova configuração do serviço e começa a ser usada automaticamente. Recomendamos especificar essa opção em vez de fornecer um ID de configuração específico para o ESPv2. Para mais detalhes sobre os argumentos do ESPv2, consulte Opções de inicialização do ESPv2.

    Exemplo:

        spec:
          containers:
          - name: esp
            image: gcr.io/endpoints-release/endpoints-runtime:2
            args: [
              "--listener_port=9000",
              "--service=bookstore.endpoints.example-project-12345.cloud.goog",
              "--rollout_strategy=managed",
              "--backend=grpc://127.0.0.1:8000"
            ]
  3. Inicie o serviço:
    kubectl create -f grpc-bookstore.yaml
    

Se você receber uma mensagem de erro, consulte Como solucionar problemas de Endpoints no GKE.

Como conseguir o endereço IP externo do serviço

É necessário o endereço IP externo do serviço para enviar solicitações à API de amostra. Pode demorar alguns minutos depois de iniciar o serviço no contêiner antes que o endereço IP externo esteja pronto.

  1. Veja o endereço IP externo:

    kubectl get ingress

  2. Anote o valor de EXTERNAL-IP e salve-o em uma variável de ambiente SERVER_IP. O endereço IP externo é usado para enviar solicitações à API de amostra.

    export SERVER_IP=YOUR_EXTERNAL_IP
    

Como enviar uma solicitação à API

Para enviar solicitações à API de amostra, use um cliente gRPC de amostra escrito em Python.

  1. Clone o repositório do Git onde o código do cliente gRPC está hospedado:

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
       

  2. Altere o diretório de trabalho:

    cd python-docs-samples/endpoints/bookstore-grpc/
      

  3. Instale as dependências:

    pip install virtualenv
    virtualenv env
    source env/bin/activate
    python -m pip install -r requirements.txt

  4. Criar uma CA raiz para o certificado autoassinado

    openssl x509 -in server.crt -out client.pem -outform PEM
      

  5. Envie uma solicitação à API de amostra:

    python bookstore_client.py --host SERVER_IP --port 443 \
    --servername bookstore.endpoints.MY_PROJECT_ID.cloud.goog --use_tls true --ca_path=client.pem
    

Se não receber uma resposta bem-sucedida, consulte Como solucionar problemas em erros de resposta.

Você acaba de implantar e testar uma API no Endpoints.

Limpar

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

  1. Exclua a API:

    gcloud endpoints services delete SERVICE_NAME
    

    Substitua SERVICE_NAME pelo nome da API.

  2. Exclua o cluster do GKE:

    gcloud container clusters delete NAME --zone ZONE
    

A seguir

  • Descubra como configurar a API do gRPC do Cloud Endpoints.
  • Consulte a amostra do Bookstore no GitHub para saber mais. Tanto o cliente quanto o servidor estão disponíveis em Python e em Java (links em inglês).
  • A amostra getting-started-grpc está disponível no GitHub nos seguintes idiomas: