Como autenticar no Cloud Platform usando contas de serviço

Neste tutorial, demonstramos como criar uma conta de serviço do Google Cloud, atribuir papéis para autenticação nos serviços do Cloud Platform e usar as credenciais dessa conta em aplicativos em execução no GKE.

Neste exemplo, usaremos o Cloud Pub/Sub, mas as instruções são aplicáveis a qualquer serviço do Cloud Platform. No aplicativo de amostra deste tutorial, uma conta de serviço é usada para fazer autenticação no Cloud Pub/Sub e assinar as mensagens publicadas em um tópico do Pub/Sub de um aplicativo baseado em Python.

Objetivos

Este tutorial inclui as etapas a seguir:

  • Como criar uma conta de serviço.
  • Como atribuir os papéis necessários para a conta de serviço trabalhar com o Cloud Pub/Sub.
  • Como salvar a chave da conta como um secret do Kubernetes (em inglês).
  • Como usar a conta de serviço para configurar e implantar um aplicativo.

No aplicativo de amostra usado neste tutorial, você assina um tópico do Pub/Sub e imprime as mensagens publicadas na saída padrão. Para configurar o aplicativo com as permissões corretas, use o gcloud para publicar as mensagens e inspecione o stream de saída do contêiner para observar se as mensagens são recebidas corretamente.

Por que usar as contas de serviço?

Cada nó em um cluster de contêiner é uma instância do Compute Engine. Isso significa que os aplicativos executados em um cluster de contêiner por padrão herdam os escopos das instâncias do Compute Engine em que são implantados.

O Google Cloud Platform cria automaticamente uma conta de serviço chamada "Conta de serviço padrão do Compute Engine" e o GKE a associa aos nós criados por ela. Dependendo de como o projeto estiver configurado, a conta de serviço padrão poderá ou não ter permissões para usar outras APIs do Cloud Platform. O GKE também atribui alguns escopos de acesso limitados para computar instâncias. A atualização das permissões da conta de serviço padrão ou a atribuição de mais escopos de acesso para calcular instâncias não é a maneira recomendada de autenticação em outros serviços do Cloud Platform a partir de pods em execução no GKE.

Recomendamos que você crie suas próprias contas de serviço para se autenticar nos serviços do Google Cloud Platform a partir de aplicativos em execução no GKE. O ideal é criar uma nova conta de serviço para cada aplicativo que faz solicitações às APIs do Cloud Platform.

Os benefícios de ter contas de serviço separadas para aplicativos diferentes são:

  • melhor visibilidade e auditoria das solicitações de API feitas no aplicativo

  • capacidade de revogar chaves para aplicativos específicos, em vez de compartilhar uma conta de serviço e precisar revogar o acesso à API de todos os aplicativos

  • exposição reduzida, no caso de um possível incidente de segurança em que as credenciais da conta de serviço sejam comprometidas

Antes de começar

Siga estas etapas para ativar a API Kubernetes Engine:
  1. Acesse a página do Kubernetes Engine no Console do Google Cloud Platform.
  2. Crie ou selecione um projeto.
  3. Aguarde a ativação da API e dos serviços relacionados. Isso pode levar alguns minutos.
  4. Verifique se o faturamento foi ativado no projeto do Google Cloud Platform. Saiba como confirmar que o faturamento está ativado para seu projeto.

Instale as ferramentas de linha de comando a seguir usadas neste tutorial:

  • gcloud é usado para criar e excluir clusters do Kubernetes Engine. gcloud está incluído no SDK do Google Cloud.
  • O kubectl é usado para gerenciar o Kubernetes, o sistema de orquestração de cluster usado pelo Kubernetes Engine. É possível instalar kubectl usando gcloud:
    gcloud components install kubectl

Definir padrões para a ferramenta de linha de comando gcloud

Para poupar tempo, em vez de digitar o ID do projeto e as opções de zona do Compute Engine na ferramenta de linha de comando gcloud, defina os padrões:
gcloud config set project [PROJECT_ID]
gcloud config set compute/zone [COMPUTE_ENGINE_ZONE]

Ativar a API Pub/Sub

Neste tutorial, você precisa ativar a API Cloud Pub/Sub no projeto, uma vez que ela é usada no aplicativo de amostra para receber as mensagens do tópico do Pub/Sub:

Ativar a(s) API

Criar um cluster de contêiner

Crie um cluster de contêiner chamado pubsub-test para implantar o aplicativo de assinante do Pub/Sub:

gcloud container clusters create pubsub-test

Etapa 1: criar um tópico do Pub/Sub

O aplicativo de assinante Pub/Sub que você implantará usa uma assinatura chamada echo-read em um tópico do Pub/Sub chamado echo. Crie estes recursos antes de implantar o aplicativo:

Primeiro, crie um tópico do Pub/Sub:

gcloud

gcloud pubsub topics create echo

Config Connector

Observação: esta etapa requer o Config Connector. Siga as instruções de instalação para instalar o Config Connector no cluster.

Ver no GitHub (em inglês)
apiVersion: pubsub.cnrm.cloud.google.com/v1alpha2
kind: PubSubTopic
metadata:
  name: echo
Para implantar esse manifesto, faça o download para sua máquina como topic.yaml e execute:
kubectl apply -f topic.yaml

Em seguida, crie uma inscrição:

gcloud

gcloud pubsub subscriptions create echo-read --topic=echo

Config Connector

Ver no GitHub (em inglês)
apiVersion: pubsub.cnrm.cloud.google.com/v1alpha2
kind: PubSubSubscription
metadata:
  name: echo-read
spec:
  topicRef:
    name: echo
Para implantar esse manifesto, faça o download para sua máquina como subscription.yaml e execute:
kubectl apply -f subscription.yaml

Etapa 2: implantar o aplicativo assinante do Pub/Sub

A próxima etapa é implantar o contêiner do aplicativo que recebe as mensagens publicadas para o tópico do Pub/Sub. Esse aplicativo foi escrito em Python com as bibliotecas de cliente do Google Cloud Pub/Sub. Veja o código-fonte no GitHub (em inglês).

No arquivo de manifesto a seguir, você encontra a descrição de uma implantação (em inglês) que execute uma única instância da imagem do Docker desse aplicativo:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pubsub
spec:
  selector:
    matchLabels:
      app: pubsub
  template:
    metadata:
      labels:
        app: pubsub
    spec:
      containers:
      - name: subscriber
        image: gcr.io/google-samples/pubsub-sample:v1

Para implantar esse manifesto, faça o download dele para sua máquina como pubsub.yaml e execute:

kubectl apply -f pubsub.yaml

Depois que o aplicativo for implantado, consulte os pods executando:

kubectl get pods -l app=pubsub
Saída:
NAME                      READY     STATUS             RESTARTS   AGE
pubsub-2009462906-1l6bh   0/1       CrashLoopBackOff   1          30s

Observe que o contêiner não está iniciando e entrou em um estado CrashLoopBackOff. Para inspecionar os registros do pod, execute:

kubectl logs -l app=pubsub
Saída:
...
google.gax.errors.RetryError: GaxError(Exception occurred in retry method
that was not classified as transient, caused by <_Rendezvous (StatusCode.PERMISSION_DENIED, scopes.) of RPC that terminated with Request had insufficient authentication>)

O rastreamento de pilha e a mensagem de erro indicam que o aplicativo não tem permissão para consultar o serviço do Cloud Pub/Sub.

Etapa 3: criar credenciais de conta de serviço

Para fornecer acesso aos serviços do Google Cloud Platform para aplicativos em execução no GKE, é preciso usar contas de serviço.

Console

Para criar uma conta de serviço, acesse Contas de serviço no Console do Cloud e clique em Criar conta de serviço:

  1. Especifique o Nome da conta de serviço. Por exemplo, pubsub-app.
  2. Na lista suspensa Papel, selecione "Pub/Sub → Assinante".
  3. Clique em Criar chave e escolha o tipo de chave como JSON.
  4. Clique em Criar.

Depois que a conta de serviço é criada, será feito o download de um arquivo de chave JSON contendo as credenciais da conta de serviço para seu computador. Use esse arquivo de chave para configurar o aplicativo para autenticação na API Cloud Pub/Sub.

Config Connector

Primeiro, faça o download do seguinte recurso como service-account.yaml.

Ver no GitHub (em inglês)
apiVersion: iam.cnrm.cloud.google.com/v1alpha1
kind: IAMServiceAccount
metadata:
  name: pubsub-app
spec:
  displayName: Service account for PubSub example

Depois, execute:

kubectl apply -f service-account.yaml

Em seguida, aplique o Papel "Assinante do Pub/Sub" à conta de serviço. Faça o download do recurso a seguir como service-account-policy.yaml. Substitua [PROJECT_ID] pelo ID do seu projeto.

Ver no GitHub (em inglês)
apiVersion: iam.cnrm.cloud.google.com/v1alpha1
kind: IAMPolicyMember
metadata:
  name: policy-member-binding
spec:
  member: serviceAccount:pubsub-app@[PROJECT_ID].iam.gserviceaccount.com
  role: roles/pubsub.subscriber
  resourceRef:
    kind: Project
    name: [PROJECT_ID]

Depois, execute:

kubectl apply -f service-account-policy.yaml

Etapa 4: importar credenciais como um secret

O tipo de recurso secret é oferecido no Kubernetes para armazenar credenciais no cluster de contêiner e usá-las diretamente nos aplicativos implantados no GKE.

kubectl

Para salvar o arquivo de chave JSON como um Secret chamado pubsub-key, execute o seguinte comando com o caminho para o arquivo de credenciais da conta de serviço baixado:

kubectl create secret generic pubsub-key --from-file=key.json=PATH-TO-KEY-FILE.json

Esse comando cria um Secret chamado pubsub-key que tem um arquivo key.json com o conteúdo da chave privada que você fez o download do Console do GCP. Após criar o secret, remova o arquivo do seu computador.

Config Connector

Faça o download do recurso a seguir como service-account-key.yaml.

Ver no GitHub (em inglês)
apiVersion: iam.cnrm.cloud.google.com/v1alpha1
kind: IAMServiceAccountKey
metadata:
  name: pubsub-key
spec:
  publicKeyType: TYPE_X509_PEM_FILE
  keyAlgorithm: KEY_ALG_RSA_2048
  privateKeyType: TYPE_GOOGLE_CREDENTIALS_FILE
  serviceAccountRef:
    name: pubsub-app

Depois, execute:

kubectl apply -f service-account-key.yaml

Etapa 5: configurar o aplicativo com o secret

Para usar o secret pubsub-key no aplicativo, modifique a especificação de implantação para:

  1. Defina um volume com o secret.
  2. Ative o volume do secret para o contêiner de aplicativo.
  3. Defina a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS de modo que ela aponte para o arquivo da chave no volume montado da chave secreta.

O arquivo de manifesto atualizado ficará parecido com este:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pubsub
spec:
  selector:
    matchLabels:
      app: pubsub
  template:
    metadata:
      labels:
        app: pubsub
    spec:
      volumes:
      - name: google-cloud-key
        secret:
          secretName: pubsub-key
      containers:
      - name: subscriber
        image: gcr.io/google-samples/pubsub-sample:v1
        volumeMounts:
        - name: google-cloud-key
          mountPath: /var/secrets/google
        env:
        - name: GOOGLE_APPLICATION_CREDENTIALS
          value: /var/secrets/google/key.json

Neste arquivo de manifesto, os seguintes itens estão definidos para que as credenciais fiquem disponíveis para o aplicativo:

  • Um volume chamado google-cloud-key que usa o secret denominado pubsub-key.

  • Um volume montado, que disponibiliza google-cloud-key no diretório /var/secrets/google dentro do contêiner.

  • A variável de ambiente GOOGLE_APPLICATION_CREDENTIALS definida como /var/secrets/google/key.json, que contém o arquivo de credenciais quando o secret é ativado para o contêiner como um volume.

A variável de ambiente GOOGLE_APPLICATION_CREDENTIALS é reconhecida automaticamente pelas bibliotecas de cliente do Google Cloud. Nesse caso, o cliente do Cloud Pub/Sub para Python.

Para implantar esse manifesto, faça o download dele para sua máquina como pubsub-with-secret.yaml e execute:

kubectl apply -f pubsub-with-secret.yaml

Depois de implantado corretamente, o status do pod será listado como Running:

kubectl get pods -l app=pubsub
Saída:
NAME                     READY     STATUS    RESTARTS   AGE
pubsub-652482369-2d6h2   1/1       Running   0          29m

Etapa 6: testar o recebimento das mensagens do Pub/Sub

Agora que você configurou o aplicativo, publique uma mensagem no tópico do Pub/Sub chamado echo:

gcloud pubsub topics publish echo --message="Hello, world!"

Em alguns segundos, uma mensagem é recebida pelo aplicativo e impressa no stream de saída. Para inspecionar os registros do pod implantado, execute:

kubectl logs -l app=pubsub
Saída:
Pulling messages from Pub/Sub subscription...
[2017-06-19 12:31:42.501123] ID=130941112144812 Data=Hello, world!

Você configurou com sucesso a autenticação de um aplicativo no GKE na API do Pub/Sub usando credenciais de conta de serviço.

Como fazer a limpeza

Para evitar que os recursos usados neste tutorial sejam cobrados na conta do Google Cloud Platform:

  1. Remova a inscrição e o tópico do Pub/Sub:

    gcloud pubsub subscriptions delete echo-read
    gcloud pubsub topics delete echo
  2. Exclua o cluster de contêiner:

    gcloud container clusters delete pubsub-test

A seguir