GKE Workload Identity
2 solutions sont adéquates pour s'identifier sur les services Google : Les Services Account (SA) et le Workload Identity
Les SA contiennent des secrets et doivent être rotate en cas de compromission...
Workload Identity règle ça : on lie un service account K8s (KSA) à un service account GCP (GSA), et les SDK GCP récupèrent automatiquement un token depuis la metadata API du nœud.
Avec Terraform
Deux points à activer : le cluster (workload_pool) et chaque node pool (GKE_METADATA).
Node pool obligatoire
Sans workload_metadata_config { mode = "GKE_METADATA" } sur le node pool, Workload Identity ne fonctionne pas même si le cluster est configuré.
# Cluster — activer le workload pool
resource "google_container_cluster" "main" {
# ...
workload_identity_config {
workload_pool = "${var.project_id}.svc.id.goog"
}
}
# Node pool — activer GKE_METADATA (déclenche un rolling update si existant)
resource "google_container_node_pool" "default" {
# ...
node_config {
workload_metadata_config {
mode = "GKE_METADATA"
}
}
}
# GSA et ses permissions
resource "google_service_account" "app" {
account_id = "my-app-sa"
display_name = "my-app service account"
}
resource "google_project_iam_member" "app_storage" {
project = var.project_id
role = "roles/storage.objectViewer"
member = "serviceAccount:${google_service_account.app.email}"
}
# Liaison KSA → GSA
# Le format du member est strict : PROJECT.svc.id.goog[NAMESPACE/KSA_NAME]
resource "google_service_account_iam_member" "workload_identity" {
service_account_id = google_service_account.app.name
role = "roles/iam.workloadIdentityUser"
member = "serviceAccount:${var.project_id}.svc.id.goog[${var.namespace}/${var.ksa_name}]"
}
# KSA annoté
resource "kubernetes_service_account" "app" {
metadata {
name = "my-app"
namespace = var.namespace
annotations = {
"iam.gke.io/gcp-service-account" = google_service_account.app.email
}
}
}
Utiliser dans le pod
spec:
serviceAccountName: my-app
containers:
- name: my-app
image: my-app:latest
# Les SDK GCP utilisent ADC automatiquement, rien d'autre à faire
Vérifier que ça fonctionne
kubectl run -it --rm workload-identity-test \
--image=google/cloud-sdk:slim \
--namespace=${K8S_NAMESPACE} \
--overrides='{"spec":{"serviceAccountName":"'${KSA_NAME}'"}}' \
-- bash
Dans le pod :
gcloud auth list
# ou via la metadata API directement
curl -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email"
Troubleshooting
| Symptôme | Cause probable |
|---|---|
could not find default credentials | Annotation KSA manquante ou mauvais SA dans le pod |
403 Permission denied | IAM binding manquant ou mauvais rôle sur le GSA |
| Token GSA incorrect | Node pool sans GKE_METADATA |
svc.id.goog absent de la metadata | Workload Identity non activé sur le cluster |