Workload Identity GKE — Service account k8s com permissões na GCP

Thiago Crespo
4 min readJun 27, 2023

--

O Workload Identity é um recurso do GKE (Google Kubernetes Engine) que nos permite linkar uma service account do Kubernetes com uma service account da GCP, fazendo assim, com que os Pods que utilizem esta service account, possam fazer ações permitidas na service account da GCP.

Por exemplo, temos um microserviço que faz operações em um Bucket. Então podemos criar uma service account na GCP com permissões para fazer ações em buckets, criar uma service account no Kubernetes, linkar as duas através do Workload Identity e a aplicação será automaticamente autenticada como a service account da GCP que definirmos.

Habilitando Workload Identity

Antes de começarmos a utilizar, precisamos habilitar esta funcionalidade no cluster:

workload identity no control plane do GKE

Depois, precisamos habilitar o GKE Metadata Server nos node pools que possuem os worker nodes que queremos alocar os pods que irão usar a funcionalidade de Workload Identity.

GKE Metadata server habilitado nos worker nodes

Criando service account’s

Criamos uma service account na GCP, que terá as permissões que o nosso Pod irá utilizar. Então criamos a service account do Kubernetes que será linkada com esta criada na GCP:

kubectl create sa -n <namespace> workload-identity-test

Então rodamos comandos com gcloud no terminal, primeiro conectamos ao project na GCP que a service account que criamos está, e depois adicionamos a role de workloadIdentityUser na service da GCP para conseguirmos linkar as duas:

gcloud config set project <nome_projeto>
gcloud iam service-accounts add-iam-policy-binding \
<email_da_service_account_GCP> \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:production-261711.svc.id.goog[<namespace>/workload-identity-test]"

Possíveis erros:

Falta de permissão: Precisa mudar o project default do gcloud para o que você está tentando mexer: gcloud config set project <id_do_project>

gcloud crashed: Rodar gcloud components update para atualizar as dependências.

Linkar service accounts

Agora para linkar as duas service accounts, adicionamos uma annotation na do Kubernetes (k edit sa -n <namespace> workload-identity-test):

apiVersion: v1
kind: ServiceAccount
metadata:
# Adiciona esta annotation
annotations:
iam.gke.io/gcp-service-account: <email_service_account_GCP>
name: workload-identity-test
namespace: <namespace>

Para pegar achar o email da service account criada na GCP, basta ir até a service account:

email da service account criada no IAM da GCP

Hands on

Criei um código de exemplo em NodeJS que é uma API com apenas uma rota que lista os buckets quando chamada. Para isto, eu uso a SDK da Google Cloud e a autenticação é esperada através de variáveis de ambiente.

O código está no meu Github:
https://github.com/ThiagoFelippi/workload-identity-example

Para subir no kubernetes, usei o private registry do Gitlab, e os seguintes manifestos:

apiVersion: apps/v1
kind: Deployment
metadata:
name: workload-identity-example
namespace: pocs
spec:
selector:
matchLabels:
app: workload-identity-example
template:
metadata:
labels:
app: workload-identity-example
spec:
imagePullSecrets:
- name: workload-identity-example
containers:
- name: workload-identity-example
image: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
imagePullPolicy: IfNotPresent
envFrom:
- configMapRef:
name: workload-identity-example
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: workload-identity-example
namespace: pocs
spec:
type: ClusterIP
selector:
app: workload-identity-example
ports:
- port: 80
targetPort: 3000

Ao subir, podemos rodar um port-forward para não precisar expor a poc através de um ingress: k port-forward svc/workload-identity-example -n pocs 3001:80

Ao acessar a rota /buckets, temos o seguinte resultado:

mensagem de erro por não conseguir listar buckets

E podemos ver os logs do container apontando que não estamos autenticados:

erro no terminal mostrando que não conseguiu listar buckets por falta de autenticação na GCP

Agora vamos colocar a service account que criamos para gerenciar o Deployment e ver qual o resultado. Para isto, a única coisa que muda no deployment é adicionarmos o campo serviceAccoutName dentro de spec:

...
spec:
selector:
matchLabels:
app: workload-identity-example
template:
metadata:
labels:
app: workload-identity-example
spec:
serviceAccountName: workload-identity-test
...

E ao rodar a aplicação e entrar na rota /buckets de novo, conseguimos ver os buckets sendo listados:

mostrando os buckets listados depois de implantar o workload identity na service account do cluster

Conclusões

Desta forma, aumentamos a segurança das nossas aplicações, não precisando expor dados sensíveis com a aplicação. Ensinarei em outros posts como usar isto na prática, com Helm Charts, por exemplo, com Vault, ArgoCD, etc.

Caso tenha alguma dúvida, deixe um comentário ou me chame no Linkedin: https://www.linkedin.com/in/thiago-crespo-felippi/

--

--

Thiago Crespo
Thiago Crespo

Written by Thiago Crespo

DevSecOps / Platform Engineer @NtConsult

No responses yet