How do you attach a service account to a gke deployment/servic like you can an ECS service?

12/2/2018

Im coming from AWS not sure how to do this with gcp. Previously I asked a more general question about service accounts, this is specific to gke.

In AWS I can create an ECS service role. I attach policies to that role to give it the access it needs. Then I attach the role to an ECS service. So I can deploy multiple services to the same ECS cluster and give them different access with No static keys being used, no secrets being passed around.

How do I do this with gke? How do I attach a gcp iam service account to a gke deployment/service, etc? Can you used annotations in the deployment yaml to attach a service account?

I want to have multiple deployments and services on the same gke cluster using different service accounts implicitly (no keys being used)

-- red888
amazon-ecs
google-cloud-iam
google-cloud-platform
google-kubernetes-engine
kubernetes

1 Answer

12/3/2018

Introduction:

A Google Cloud Kubernetes Cluster consists of Compute Engine VM instances. When you create a cluster a default service account is attached to each VM instance. These credentials are stored in the instance metadata and can be accessed by using a default application Client() instantiation (Application Default Credentials) or by specifying the credential location.

ADC Credentials Search:

from google.cloud import storage
client = storage.Client()

OR only from metadata:

from google.auth import compute_engine
from google.cloud import storage
credentials = compute_engine.Credentials()
client = storage.Client(credentials=credentials, project=project)

[Update]

I do not want to promote poor security practices. The above techniques should be blocked on secure production Kubernetes clusters.

  1. Use a minimally privileged service account for the Kubernetes cluster.
  2. Disable legacy metadata server APIs and use metadata concealment.
  3. Use a Pod Security Policy.
  4. Use separate service accounts for node pools.
  5. Restrict traffic between pods with a Network Policy.

[End Update]

The Google Kubernetes Method:

The recommended technique for Kubernetes is to create a separate service account for each application that runs in the cluster and reduce the scopes applied to the default service account. The roles assigned to each service account vary based upon the permissions that the applications require.

Service account credentials are downloaded as a Json file and then stored in Kubernetes as a Secret. You would then mount the volume with the secret (the credentials). The application running in the container will then need to load the credentials when creating Google Application Clients such as to access Cloud Storage.

This command will store the downloaded credentials file into a Kubernetes secret volume as the secret named service-account-credentials. The credentials file inside Kubernetes is named key.json. The credentials are loaded from the file that was downloaded from Google Cloud named `/secrets/credentials.json

kubectl create secret generic service-account-credentials --from-file=key.json=/secrets/credentials.json

In your deployment file add the following to mount the volume.

spec:
  volumes:
  - name: google-cloud-key
    secret:
      secretName: service-account-credentials
...
  containers:
    volumeMounts:
    - name: google-cloud-key
      mountPath: /var/secrets/google

Inside the container, the credentials are loaded from /var/secrets/google/key.json

Python Example:

from google.cloud import storage
client = storage.Client.from_service_account_json('/var/secrets/google/key.json')

This document provides step-by-step details on service account credentials with Kubernetes.

Authenticating to Cloud Platform with Service Accounts

-- John Hanley
Source: StackOverflow