Como usar o agente de serviços do Google Cloud Platform (versão beta, obsoleta) para acessar o Cloud Pub/Sub

Neste tutorial, você verá como usar o catálogo de serviços do Kubernetes e o agente de serviços do Google Cloud Platform (GCP) para conectar um aplicativo em execução no GKE ao Cloud Pub/Sub.

Por que usar o catálogo de serviços?

O catálogo de serviços permite que aplicativos em execução em um cluster detectem e se conectem facilmente a serviços externos sem precisar importar manualmente informações, como credenciais ou terminais. As dependências de serviço externo são modeladas como recursos do Kubernetes, que podem ser facilmente integrados ao seu processo de implantação existente.

Neste tutorial, usaremos os seguintes recursos do catálogo de serviços:

  • Como descobrir os serviços do Google Cloud Platform no agente de serviços por meio do catálogo relacionado.
  • Como provisionar uma instância de serviço para criar o recurso do Cloud.
  • Como vincular a instância de serviço provisionada no aplicativo do Kubernetes para injetar credenciais no cluster.
  • Como usar a vinculação de serviço no aplicativo para acessar a instância de serviço, que aponta para o recurso do Cloud.

Para mais informações, consulte a documentação do catálogo de serviços do Kubernetes.

Objetivos

Este tutorial inclui as etapas a seguir:

  1. Criar um namespace
  2. Criar uma conta de serviço do IAM
  3. Criar um tópico do Pub/Sub
  4. Criar uma assinatura do Pub/Sub para o tópico
  5. Testar o serviço do Pub/Sub com um aplicativo de demonstração
  6. Limpar

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 ativar o faturamento

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]

Configurar o catálogo de serviços

  • Instale o catálogo de serviços e o agente de serviços no cluster do GKE.
  • Verifique se o catálogo de serviços está em execução usando kubectl na linha de comando para listar todos os processos do catálogo de serviços:

    kubectl get deployment -n service-catalog

    Todas as implantações precisam aparecer como AVAILABLE.

  • (Opcional) Instale a ferramenta CLI do svcat, que melhora a experiência do usuário em relação ao trabalho com os recursos do catálogo de serviços.

Etapa 1: criar um namespace

Um namespace é opcional, porém recomendável facilitar a limpeza deste tutorial.

Mude o nome do namespace como uma variável de ambiente:

NAMESPACE=pubsub-app

Crie o namespace para o aplicativo usando o Cloud Pub/Sub. Execute o seguinte comando:

kubectl create namespace [NAMESPACE]

Produzirá a seguinte mensagem:

namespace "pubsub-app" created

Etapa 2: criar uma conta de serviço do IAM

Você precisa de uma conta de serviço do IAM para usar os serviços do GCP no seu aplicativo. Neste tutorial, criaremos um com o ID pubsub-sa.

Caso contrário, crie uma conta de serviço do IAM usando o catálogo de serviços. Isso pode ser feito provisionando e vinculando a uma instância de serviço da classe de serviço cloud-iam-service-account.

Provisionar uma instância da conta de serviço do IAM

Use o seguinte comando para armazenar o nome da conta de serviço em uma variável de ambiente:

SERVICE_ACCOUNT_ID=pubsub-sa

svcat

Use o comando svcat para provisionar uma instância de conta de serviço:

svcat provision gcp-iam \
    --class cloud-iam-service-account \
    --plan beta \
    --namespace [NAMESPACE] \
    --param accountId=$SERVICE_ACCOUNT_ID

O comando gera a seguinte mensagem:

  Name:        gcp-iam
  Namespace:   pubsub-app
  Status:
  Class:       cloud-iam-service-account
  Plan:        beta

Parameters: accountId: pubsub-sa

Verifique o status da instância de serviço com o seguinte comando:

svcat get instance gcp-iam --namespace [NAMESPACE]

A saída será semelhante a:

   NAME     NAMESPACE              CLASS             PLAN   STATUS
+---------+------------+---------------------------+------+--------+
  gcp-iam   pubsub-app   cloud-iam-service-account   beta   Ready

A instância de serviço é provisionada com êxito quando o STATUS dela é Ready.

kubectl

Crie um arquivo YAML ServiceInstance chamado iam_instance.yaml com a especificação a seguir. Verifique se o valor do campo serviceAccount é igual a echo $SERVICE_ACCOUNT_ID:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
  name: gcp-iam
  namespace: pubsub-app
spec:
  # This should match with a SERVICE EXTERNAL NAME
  # in the list of available services.
  clusterServiceClassExternalName: cloud-iam-service-account
  # This should match with a PLAN EXTERNAL NAME
  # in the list of available service plans.
  clusterServicePlanExternalName: beta
  parameters:
    accountId: pubsub-sa

Use o comando kubectl para provisionar a instância da conta de serviço usando o arquivo YAML:

kubectl apply -f iam_instance.yaml

O comando gera a seguinte mensagem:

serviceinstance "gcp-iam" created

Verifique o status da instância de serviço com o seguinte comando:

kubectl get serviceinstances gcp-iam -n [NAMESPACE] -o 'custom-columns=INSTANCE-NAME:.metadata.name,SERVICE:.spec.clusterServiceClassExternalName,PLAN:.spec.clusterServicePlanExternalName,STATUS:.status.conditions[0].reason'

A saída será semelhante a:

INSTANCE-NAME   SERVICE                     PLAN      STATUS
gcp-iam         cloud-iam-service-account   beta      ProvisionedSuccessfully

Depois que a instância de serviço for provisionada, você também poderá verificar a conta de serviço pubsub-sa@[PROJECT_ID].iam.gserviceaccount.com do IAM correspondente no Console do Cloud.

Vincular à instância da conta de serviço do IAM

A vinculação à instância da conta de serviço criará uma chave secreta no mesmo namespace. A chave secreta conterá o nome da conta de serviço e uma chave privada, que pode ser facilmente referenciada pelo seu aplicativo.

Use o seguinte comando para armazenar o nome da chave secreta em uma variável de ambiente:

SA_SECRET_NAME=pubsub-credentials

svcat

Use o comando svcat para vincular à instância da conta de serviço:

svcat bind gcp-iam --namespace [NAMESPACE] --secret-name $SA_SECRET_NAME

O comando gera a seguinte mensagem:

  Name:        gcp-iam
  Namespace:   pubsub-app
  Status:
  Instance:    gcp-iam

Parameters: {}

Verifique o status da vinculação de serviço com o seguinte comando:

svcat get binding gcp-iam --namespace [NAMESPACE]

A saída será semelhante a:

   NAME     NAMESPACE    INSTANCE   STATUS
+---------+------------+----------+--------+
  gcp-iam   pubsub-app   gcp-iam    Ready

Aguarde até que o status da vinculação de serviço seja Ready antes de continuar. Isso pode demorar um minuto.

kubectl

Crie um arquivo YAML ServiceBinding chamado iam_binding.yaml com a seguinte especificação:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
  name: gcp-iam
  namespace: pubsub-app
spec:
  instanceRef:
    name: gcp-iam
  secretName: pubsub-credentials

Execute o seguinte comando para criar a vinculação de serviço:

kubectl apply -f iam_binding.yaml

Verifique o status da vinculação de serviço executando o seguinte comando:

kubectl get servicebindings gcp-iam -n [NAMESPACE] -o 'custom-columns=BINDING-NAME:.metadata.name,SERVICE-INSTANCE:.spec.instanceRef.name,STATUS:.status.conditions[0].reason,OUTPUT-SECRET:.spec.secretName'

A saída será semelhante a esta:

BINDING-NAME      SERVICE-INSTANCE   STATUS               OUTPUT-SECRET
gcp-iam           gcp-iam            InjectedBindResult   gcp-iam

Após a criação da vinculação de serviço, confirme se o secret existe com o seguinte comando kubectl:

kubectl get secrets $SA_SECRET_NAME --namespace [NAMESPACE]

A saída será semelhante a:

NAME                 TYPE      DATA      AGE
pubsub-credentials   Opaque    2         1m

Você também pode ver a chave secreta que contém as credenciais da conta de serviço:

kubectl get secrets $SA_SECRET_NAME --namespace [NAMESPACE] -o yaml

Observe que o valor privateKeyData é codificado em Base64 e contém a chave privada da conta de serviço.

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

Provisionar uma instância de serviço do Pub/Sub

Agora vamos usar o catálogo de serviços para provisionar uma instância de serviço do Pub/Sub. Ao fazer isso, criaremos um tópico do Pub/Sub em que o nosso aplicativo possa publicar e ler.

svcat

Use o comando svcat para provisionar uma instância de serviço do Pub/Sub:

svcat provision gcp-pubsub \
    --class cloud-pubsub \
    --plan beta \
    --namespace [NAMESPACE] \
    --param topicId=pubsub-app

O comando gera a seguinte mensagem:

  Name:        gcp-pubsub
  Namespace:   pubsub-app
  Status:
  Class:       cloud-pubsub
  Plan:        beta

Parameters: topicId: pubsub-app

Verifique o status da instância de serviço com o seguinte comando:

svcat get instance gcp-pubsub --namespace [NAMESPACE]

A saída será semelhante a:

     NAME      NAMESPACE       CLASS       PLAN   STATUS
+------------+------------+--------------+------+--------+
  gcp-pubsub   pubsub-app   cloud-pubsub   beta   Ready

A instância de serviço é provisionada com êxito quando o STATUS dela é Ready.

kubectl

Crie um arquivo YAML ServiceInstance chamado pubsub_instance.yaml com a seguinte especificação:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
  name: gcp-pubsub
  namespace: pubsub-app
spec:
  clusterServiceClassExternalName: cloud-pubsub
  # This should match with a PLAN EXTERNAL NAME
  # in the list of available service plans for Pub/Sub.
  clusterServicePlanExternalName: beta
  parameters:
    topicId: pubsub-app

Provisione uma instância de serviço Pub/Sub com o seguinte comando:

kubectl create -f pubsub_instance.yaml

Produzirá a seguinte mensagem:

serviceinstance "gcp-pubsub" created

Verifique o status da instância de serviço do Pub/Sub com o seguinte comando:

kubectl get serviceinstances gcp-pubsub -n [NAMESPACE] -o 'custom-columns=INSTANCE-NAME:.metadata.name,SERVICE:.spec.clusterServiceClassExternalName,PLAN:.spec.clusterServicePlanExternalName,STATUS:.status.conditions[0].reason'

Produzirá uma mensagem de status semelhante à seguinte:

INSTANCE-NAME   SERVICE        PLAN      STATUS
gcp-pubsub      cloud-pubsub   beta      ProvisionedSuccessfully

Após o provisionamento da instância do serviço Pub/Sub, também será possível verificar o tópico Pub/Sub projects/[PROJECT_ID]/topics/pubsub-app correspondente no Console do Cloud.

Vincular à instância de serviço do Pub/Sub

A vinculação a uma instância de serviço Pub/Sub faz o seguinte:

  • Concede à conta de serviço do IAM especificada as devidas permissões para acessar o serviço Pub/Sub.
  • Disponibiliza as informações necessárias para acessar a instância de serviço disponível para o aplicativo do Kubernetes na forma de chave secreta do Kubernetes.
  • Opcionalmente, cria uma inscrição para o tópico Pub/Sub.

Isso é necessário para o aplicativo de demonstração, que precisará ter permissão de acesso ao serviço para executar a identidade presumida da conta de serviço visando publicar mensagens em um tópico do Pub/Sub.

A classe de serviço do Pub/Sub tem vários tipos de vinculações de serviço. Primeiro, criaremos uma vinculação de serviço do tipo publisher, que contém dois papéis: roles/pubsub.publisher e roles/pubsub.viewer. A vinculação permitirá que nossa conta de serviço publique nesse tópico e veja as mensagens.

Dica: para mais informações sobre papéis e permissões de IAM do Cloud Pub/Sub, consulte a documentação de controle de acesso do Cloud Pub/Sub (/pubsub/docs/access-control#tbl_roles).

svcat

Use o comando svcat para vincular ao tópico Pub/Sub como um publisher:

svcat bind gcp-pubsub --namespace [NAMESPACE] --params-json '{
  "serviceAccount": "'${SERVICE_ACCOUNT_ID}'",
  "roles": [
    "roles/pubsub.publisher",
    "roles/pubsub.viewer"
  ]
}'

O comando deve gerar a mensagem a seguir, em que o valor serviceAccount pode ser o nome da conta de serviço que você criou anteriormente:

  Name:        gcp-pubsub
  Namespace:   pubsub-app
  Status:
  Instance:    gcp-pubsub

Parameters: roles:

  • roles/pubsub.publisher
  • roles/pubsub.viewer serviceAccount: pubsub-sa

Verifique o status da vinculação de serviço com o seguinte comando:

svcat get binding gcp-pubsub --namespace [NAMESPACE]

A saída será semelhante a:

     NAME      NAMESPACE     INSTANCE    STATUS
+------------+------------+------------+--------+
  gcp-pubsub   pubsub-app   gcp-pubsub   Ready

Aguarde até que o status da vinculação de serviço seja Ready antes de continuar. Isso pode demorar um minuto.

kubectl

Crie um arquivo YAML ServiceBinding chamado pubsub_binding.yaml com a especificação a seguir para vincular ao tópico Pub/Sub como um publisher. Certifique-se de que o valor do campo serviceAccount seja igual a echo $SERVICE_ACCOUNT_ID:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
  name: gcp-pubsub
  namespace: pubsub-app
spec:
  instanceRef:
    name: gcp-pubsub
  parameters:
    serviceAccount: pubsub-sa
    roles:
    - roles/pubsub.publisher
    - roles/pubsub.viewer

Vincule à instância de serviço Cloud Pub/Sub:

kubectl create -f pubsub_binding.yaml

Verifique o status da vinculação de serviço executando o seguinte comando:

kubectl get servicebindings gcp-pubsub -n [NAMESPACE] -o 'custom-columns=BINDING-NAME:.metadata.name,SERVICE-INSTANCE:.spec.instanceRef.name,STATUS:.status.conditions[0].reason,OUTPUT-SECRET:.spec.secretName'

Ela deve exibir um status InjectedBindResult.

O secret gcp-pubsub criado como resultado da vinculação contém o projeto (projectId), conta de serviço (serviceAccount) e ID do tópico (topicId). Para verificar o secret, execute este comando:

kubectl get secrets gcp-pubsub --namespace [NAMESPACE] -o yaml

Etapa 4: criar uma assinatura do Pub/Sub para o tópico

Como a vinculação à instância de serviço do Pub/Sub para publicação no tópico, o aplicativo de demonstração também precisa de uma vinculação de serviço para assinar o tópico e ler mensagens dele.

Agora, criaremos outra vinculação de serviço para a instância de serviço Pub/Sub, desta vez do tipo subscriber, que contém uma assinatura e dois papéis: roles/pubsub.subscriber e roles/pubsub.viewer. Isso criará uma assinatura do Pub/Sub para este tópico e permitirá que nossa conta de serviço extraia e visualize mensagens dessa assinatura.

svcat

Use o comando svcat para vincular ao tópico Pub/Sub como um subscriber:

svcat bind gcp-pubsub \
    --name gcp-pubsub-subscription \
    --namespace [NAMESPACE] \
    --params-json '{
      "serviceAccount": "'${SERVICE_ACCOUNT_ID}'",
      "roles": [
        "roles/pubsub.subscriber",
        "roles/pubsub.viewer"
      ],
      "subscription": {
        "subscriptionId": "pubsub-app"
      }
    }'

O comando deve gerar a mensagem a seguir, em que o valor serviceAccount pode ser o nome da conta de serviço que você criou anteriormente:

  Name:        gcp-pubsub-subscription
  Namespace:   pubsub-app
  Status:
  Instance:    gcp-pubsub

Parameters: roles:

  • roles/pubsub.subscriber
  • roles/pubsub.viewer serviceAccount: pubsub-sa subscription: subscriptionId: pubsub-app

Verifique o status da vinculação de serviço com o seguinte comando:

svcat get binding gcp-pubsub-subscription --namespace [NAMESPACE]

A saída será semelhante a:

           NAME             NAMESPACE     INSTANCE    STATUS
+-------------------------+------------+------------+--------+
  gcp-pubsub-subscription   pubsub-app   gcp-pubsub   Ready

Aguarde até que o status da vinculação de serviço seja Ready antes de continuar. Isso pode demorar um minuto.

kubectl

Crie um arquivo YAML ServiceBinding chamado pubsub_subscription_binding.yaml que se vincula ao tópico Pub/Sub como um subscriber. Certifique-se de que o valor do campo serviceAccount seja igual a echo $SERVICE_ACCOUNT_ID:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
  name: gcp-pubsub-subscription
  namespace: pubsub-app
spec:
  instanceRef:
    name: gcp-pubsub
  parameters:
    serviceAccount: pubsub-sa
    roles:
    - roles/pubsub.subscriber
    - roles/pubsub.viewer
    subscription:
      subscriptionId: pubsub-app

Vincule à instância de serviço Cloud Pub/Sub:

kubectl create -f pubsub_subscription_binding.yaml

Verifique o status da vinculação de serviço executando o seguinte comando:

kubectl get servicebindings gcp-pubsub-subscription -n [NAMESPACE] -o 'custom-columns=BINDING-NAME:.metadata.name,SERVICE-INSTANCE:.spec.instanceRef.name,STATUS:.status.conditions[0].reason,OUTPUT-SECRET:.spec.secretName'

Ela deve exibir um status InjectedBindResult.

A nova assinatura projects/[PROJECT_ID]/subscriptions/pubsub-app pode ser encontrado no Console do Cloud. O secret gcp-pubsub-subscription criado como resultado da vinculação contém o projeto (projectId), conta de serviço(serviceAccount), ID do tópico (topicId) e ID de inscrição (subscriptionId). Para verificar o segredo, execute este comando:

kubectl get secrets gcp-pubsub-subscription --namespace [NAMESPACE] -o yaml

Etapa 5: testar o serviço Pub/Sub com um aplicativo de demonstração

Execute o aplicativo de demonstração no cluster do GKE para testar a conexão com o serviço Cloud Pub/Sub.

Crie um arquivo de job do Kubernetes chamado hello_pubsub_world.yaml com a especificação a seguir, substituindo o valor de secretName por [SA_SECRET_NAME] se você criou o secret manualmente para armazenar a chave privada da conta de serviço:

apiVersion: batch/v1
kind: Job
metadata:
  name: hello-pubsub-world
  namespace: pubsub-app
spec:
  template:
    spec:
      volumes:
        # Make the 'pubsub-credentials' secret available as volume
        # 'google-cloud-key'.
        - name: google-cloud-key
          secret:
            secretName: pubsub-credentials
      restartPolicy: OnFailure
      containers:
        - name: hello-pubsub-world
          image: gcr.io/gcp-services/samples/hello-pubsub-world
          volumeMounts:
            # Mount the 'google-cloud-key' volume into the container file
            # system.
            - name: google-cloud-key
              mountPath: /var/secrets/google
          env:
            # Pass the path to the private key JSON file from the mounted volume
            # to the environment variable.
            - name: "GOOGLE_APPLICATION_CREDENTIALS"
              value: /var/secrets/google/privateKeyData

            # The two environment variables below come from the 'gcp-pubsub'
            # secret and, together, point at the Cloud Pub/Sub topic to use.
            - name: "GOOGLE_CLOUD_PROJECT_ID"
              valueFrom:
                secretKeyRef:
                  # Use the projectId value from the 'gcp-pubsub' secret created
                  # as a result of binding to the Pub/Sub service instance.
                  name: gcp-pubsub
                  key: projectId
            - name: "GOOGLE_CLOUD_PUBSUB_TOPIC"
              valueFrom:
                secretKeyRef:
                  # Use the topicId value from the 'gcp-pubsub' secret created
                  # as a result of binding to the Pub/Sub service instance.
                  name: gcp-pubsub
                  key: topicId

            # The environment variable below come from the
            # 'gcp-pubsub-subscription' secret and, together with the
            # GOOGLE_CLOUD_PROJECT_ID above, point at the Cloud Pub/Sub
            # subscription to use.
            - name: "GOOGLE_CLOUD_PUBSUB_SUBSCRIPTION"
              valueFrom:
                secretKeyRef:
                  # Use the subscriptionId value from the
                  # 'gcp-pubsub-subscription' secret created as a result of the
                  # subscription binding to the Pub/Sub service instance.
                  name: gcp-pubsub-subscription
                  key: subscriptionId

Observe como ele usa valores dos secrets [SA_SECRET_NAME] (deve ser pubsub-credentials se você criou uma nova conta de serviço do IAM), gcp-pubsub e gcp-pubsub-subscription, que foram criados por meio de vinculações à conta de serviço do IAM e a instâncias de serviço Pub/Sub.

Crie o job:

kubectl apply -f hello_pubsub_world.yaml

O comando gera a seguinte mensagem:

job "hello-pubsub-world" created

Veja a lista de pods:

kubectl get pods --namespace [NAMESPACE] --show-all

Ela exibirá os detalhes do pod em execução nesse namespace, semelhante ao seguinte:

NAME                       READY     STATUS      RESTARTS   AGE
hello-pubsub-world-zh8hm   0/1       Completed   0          1m

Aguarde até que o pod tenha o status Completed e verifique os registros desse conjunto com este comando:

kubectl -n [NAMESPACE] logs [POD_NAME]

Aparecerão linhas contendo entradas semelhantes a estas:

Publishing 10 messages.
Publishing done.
Subscribing 10 messages.
Got message: "hello world #9"
Got message: "hello world #0"
Got message: "hello world #1"
Got message: "hello world #2"
Got message: "hello world #3"
Got message: "hello world #4"
Got message: "hello world #5"
Got message: "hello world #6"
Got message: "hello world #7"
Got message: "hello world #8"
Subscription done.

Limpar

Para evitar cobranças dos recursos usados neste tutorial na conta do Google Cloud Platform:

  1. Exclua o namespace de demonstração, o que excluirá o aplicativo, as vinculações de serviço e as instâncias de serviço:

    kubectl delete namespace [NAMESPACE]
  2. Para ver mais informações sobre como limpar o catálogo de serviços, consulte este guia.

A seguir

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Documentação do Kubernetes Engine