This example uses Pub/Sub, although the instructions can be applied to any Google Cloud service. The example application in this tutorial authenticates to Pub/Sub using a service account and subscribes to messages published to a Pub/Sub topic from a Python-based application.
Objectives
This tutorial covers the following steps:
- How to create a service account
- How to assign necessary roles for your service account to work with Pub/Sub
- How to save the account key as a Kubernetes Secret
- How to use the service account to configure and deploy an application
The sample application used in this tutorial subscribes to a Pub/Sub topic and
prints the messages published to the standard output. You must configure the
application with correct permissions, use
to publish messages,
and inspect the container's output stream to observe that the messages are
received correctly.gcloud
command-line tool
Authenticating with service accounts
You can authenticate to Google Cloud services with service accounts from within GKE using Workload Identity, the default Compute Engine service account, or Secrets.
Use Workload Identity
Workload Identity is the recommended way to authenticate to Google Cloud services from GKE. Workload Identity allows you to configure Google Cloud service accounts using Kubernetes resources. If this method of authentication fits your use case, it should be your first option. This example is meant to cover use cases where Workload Identity is not a good fit.
Use the default Compute Engine service account
Each node in a GKE cluster is a Compute Engine instance. Therefore, applications running on a GKE cluster by default attempt to authenticate using the "Compute Engine default service account", and inherit the associated scopes.
This default service account might not have permissions to use the Google Cloud services you need. It is possible to expand the scopes for the default service account, but that can create security risks and is not recommended.
Manage service account credentials using Secrets
You can create a service account for your application, and inject the authentication key as a Kubernetes secret. This option is the focus of this tutorial.
Why use Service Accounts?
Using separate service accounts for different applications provides the following benefits:
Better visibility into, and auditing of, the API requests that your application makes.
The ability to revoke keys for particular applications, instead of sharing a service account and having to revoke API access of all applications at the same time.
Reduced exposure in case of a potential security incident where the credentials of the service account are compromised.
Before you begin
Take the following steps to enable the Kubernetes Engine API:- Visit the Kubernetes Engine page in the Google Cloud Console.
- Create or select a project.
- Wait for the API and related services to be enabled. This can take several minutes.
-
Make sure that billing is enabled for your Cloud project. Learn how to confirm that billing is enabled for your project.
Install the following command-line tools used in this tutorial:
-
gcloud
is used to create and delete Kubernetes Engine clusters.gcloud
is included in the Google Cloud SDK. -
kubectl
is used to manage Kubernetes, the cluster orchestration system used by Kubernetes Engine. You can installkubectl
usinggcloud
:gcloud components install kubectl
Clone the sample code from GitHub:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples cd kubernetes-engine-samples/cloud-pubsub/deployment
Set defaults for the gcloud
command-line tool
To save time typing your project ID
and Compute Engine zone options in the gcloud
command-line tool, you can set the defaults:
gcloud config set project project-id gcloud config set compute/zone compute-zone
Enable APIs
For this tutorial, enable the Pub/Sub API and Resource Manager API on your project:
gcloud services enable cloudresourcemanager.googleapis.com pubsub.googleapis.com
Create a container cluster
Create a container cluster named pubsub-test
to deploy the Pub/Sub subscriber
application:
gcloud container clusters create pubsub-test
Creating a Pub/Sub topic
The Pub/Sub subscriber application uses a subscription named
echo-read
on a Pub/Sub topic called echo
. Create these resources before
deploying the application.
First, create a Pub/Sub topic:
gcloud
gcloud pubsub topics create echo
Config Connector
Note: This step requires Config Connector. Follow the installation instructions to install Config Connector on your cluster.
To deploy this manifest, download it to your machine as topic.yaml, and run:kubectl apply -f topic.yaml
Then, create a subscription:
gcloud
gcloud pubsub subscriptions create echo-read --topic=echo
Config Connector
To deploy this manifest, download it to your machine as subscription.yaml, and run:
kubectl apply -f subscription.yaml
Deploying Pub/Sub subscriber application
Next, deploy the application container to retrieve the messages published to the Pub/Sub topic. This application is written in Python using Google Cloud Pub/Sub client libraries. You can find the source code on GitHub.
The following manifest file describes a Deployment that runs a single instance of this application's Docker image:
To deploy this manifest, run:
kubectl apply -f pubsub.yaml
After the application is deployed, query the Pods by running:
kubectl get pods -l app=pubsubOutput:
NAME READY STATUS RESTARTS AGE pubsub-2009462906-1l6bh 0/1 CrashLoopBackOff 1 30s
You can see that the container fails to start and is in a
CrashLoopBackOff
state. Inspect the logs from the Pod by running:
kubectl logs -l app=pubsub
Output:
... google.gax.errors.RetryError: RetryError(Exception occurred in retry method that was not classified as transient, caused by <_Rendezvous of RPC that terminated with (StatusCode.PERMISSION_DENIED, Request had insufficient authentication scopes.)>)
The stack trace and the error message indicates that the application does not have permissions to query the Pub/Sub service.
Creating service account credentials
To give your application running on GKE access to Google Cloud services, use service accounts. Service accounts let you define a set of Identity and Access Management (IAM) permissions associated with your application.
Console
To create a service account, go to Service Accounts on Cloud Console and click Create Service Account:
- Specify a Service Account Name (for example,
pubsub-app
). - In the Role dropdown, select "Pub/Sub → Subscriber".
- Click Create key and choose key type as JSON.
- Click Create.
After the service account is created, a JSON key file containing the credentials of the service account is downloaded to your computer. You use this key file to configure the application to authenticate to the Pub/Sub API.
Config Connector
First, download the following resource as service-account.yaml.
Then, run:
kubectl apply -f service-account.yaml
Next, apply the "Pub/Sub Subscriber" Role to the service account. Download the following resource as service-account-policy.yaml. Replace [PROJECT_ID]
with your Project ID.
Then, run:
kubectl apply -f service-account-policy.yaml
Importing credentials as a Secret
Now that you have the service account key, you need a way to load it into your
container. Your first thought might be to add a step in your Dockerfile
, but
service account keys are security-sensitive files that should not be saved into
container images.
Instead, Kubernetes offers the Secret resource type to securely mount private files inside Pods at runtime.
kubectl
To save the JSON key file as a Secret named pubsub-key
, run the following
command with the path to the downloaded service account credentials file:
kubectl create secret generic pubsub-key --from-file=key.json=PATH-TO-KEY-FILE.json
This command creates a Secret named pubsub-key
that has a key.json
file with
the contents of the private key you downloaded from Cloud Console. After
you create the Secret, remove the key file from your computer.
Config Connector
Download the following resource as service-account-key.yaml.
Then, run:
kubectl apply -f service-account-key.yaml
Configuring the application with the Secret
To use the pubsub-key
Secret in your application, modify the
Deployment specification to:
- Define a volume with the secret.
- Mount the secret volume to the application container.
- Set the
GOOGLE_APPLICATION_CREDENTIALS
environment variable to point to the key file in the secret volume mount.
The updated manifest file looks like the following:
This manifest file defines the following fields to make the credentials available to the application:
A volume named
google-cloud-key
which uses the Secret namedpubsub-key
.A volume-mount that makes the
google-cloud-key
available at the/var/secrets/google
directory inside the container.A
GOOGLE_APPLICATION_CREDENTIALS
environment variable set as/var/secrets/google/key.json
, which contains the credentials file after the secret is mounted to the container as a volume.
Note that the GOOGLE_APPLICATION_CREDENTIALS
environment variable is
automatically recognized by Google Cloud client libraries, in this case
the Pub/Sub client for Python.
To deploy this manifest, run:
kubectl apply -f pubsub-with-secret.yaml
Verify that the Pod status is Running
:
kubectl get pods -l app=pubsubOutput:
NAME READY STATUS RESTARTS AGE pubsub-652482369-2d6h2 1/1 Running 0 29m
Testing receiving Pub/Sub messages
Now that you configured the application, publish a message to the Pub/Sub
topic named echo
:
gcloud pubsub topics publish echo --message="Hello, world!"
Within a few seconds, the message is picked up by the application and printed to the output stream. To inspect the logs from the deployed Pod, run:
kubectl logs -l app=pubsubOutput:
Pulling messages from Pub/Sub subscription... [2017-06-19 12:31:42.501123] ID=130941112144812 Data=Hello, world!
You have successfully configured an application on GKE to authenticate to Pub/Sub API using service account credentials!
Cleaning up
To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, either delete the project that contains the resources, or keep the project and delete the individual resources.
Clean up the Pub/Sub subscription and topic:
gcloud pubsub subscriptions delete echo-read gcloud pubsub topics delete echo
Delete the container cluster:
gcloud container clusters delete pubsub-test
What's next
Explore other Kubernetes Engine tutorials.
Try out other Google Cloud features for yourself. Have a look at our tutorials.