Como usar o agente de serviços do Google Cloud Platform (Beta, obsoleto) para acessar o Pub/Sub

Este tutorial demonstra como usar o catálogo de serviços do Kubernetes e o agente de serviços do Google Cloud para conectar um aplicativo em execução no GKE com o 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 serviços do Google Cloud no agente de serviços por meio do catálogo de serviços.
  • 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 Cloud Identity and Access Management
  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 do Kubernetes Engine:
  1. Acesse a página do Kubernetes Engine no Console do Google Cloud.
  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]

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, mas recomendável para 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 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 Cloud IAM

É necessário ter uma conta de serviço do Cloud Identity and Access Management para usar os serviços do Google Cloud no seu aplicativo. Neste tutorial, criaremos um com o ID pubsub-sa.

Caso contrário, crie uma conta de serviço do Cloud 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 Cloud 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 Cloud IAM correspondente no Console do Cloud.

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

A vinculação à instância da conta de serviço criará um secret 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:

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 Cloud 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 secret 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 considerada 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 as funções e permissões do Cloud IAM do Pub/Sub, consulte a [documentação de controle de acesso] (/pubsub/docs/access-control#tbl_roles) do Pub/Sub.

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

Vincular à instância de serviço do 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 {{pubsub_name_short} 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:

<pre class="devsite-click-to-copy" translate="no">svcat bind gcp-pubsub \
    --name gcp-pubsub-subscription \
    --namespace <var>[NAMESPACE]</var> \
    --params-json '{
      "serviceAccount": "'${SERVICE_ACCOUNT_ID}'",
      "roles": [
        "roles/pubsub.subscriber",
        "roles/pubsub.viewer"
      ],
      "subscription": {
        "subscriptionId": "pubsub-app"
      }
    }'</pre>

The command should output the following message (`serviceAccount` value may
be the name of the service account you created before):
<pre><span class="no-select">  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
</span></pre>

Check the status of the service binding with the following command:

<pre class="devsite-click-to-copy" translate="no">svcat get binding gcp-pubsub-subscription --namespace <var>[NAMESPACE]</var></pre>

The output should appear similar to the following:

<pre><span class="no-select">           NAME             NAMESPACE     INSTANCE    STATUS
+-------------------------+------------+------------+--------+
  gcp-pubsub-subscription   pubsub-app   gcp-pubsub   Ready
</span></pre>

Wait until the service binding's status is `Ready` before continuing. This
could take a minute.

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

Vincular à instância de serviço do 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 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 Cloud IAM), gcp-pubsub e gcp-pubsub-subscription, que foram criados por meio de vinculações à conta de serviço do Cloud 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.

Como fazer a limpeza

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