GKE in production: identity and hardening

Google Cloud · Expert · 16 min

Default clusters run fine; secure, upgrade-safe clusters need deliberate identity, network and supply-chain controls.

Workload Identity Federation for GKE gives each Kubernetes service account (KSA) its own IAM identity, so Pods call Google APIs without node service accounts or keys. You grant roles directly to a principal of the form principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/KSA. The GKE metadata server intercepts token requests from the Pod and exchanges them. It is enabled by default on Autopilot. Older setups instead bind a KSA to a Google service account via the iam.gke.io/gcp-service-account annotation.

Network hardening:

  • Private nodes (no external IPs) with Cloud NAT for egress.
  • Restrict the control plane endpoint: authorized networks, or the DNS-based endpoint protected by IAM.
  • Network policies (enforced by GKE Dataplane V2) to default-deny traffic between namespaces.

Supply chain: Binary Authorization admits only images signed or attested by your pipeline, and Artifact Analysis scans for vulnerabilities. Keep node images on Container-Optimized OS with Shielded GKE Nodes.

Upgrade safety: GKE upgrades nodes by draining them, so give every workload replicas, a PodDisruptionBudget, readiness probes and graceful shutdown. Use maintenance windows and exclusions around critical periods, and watch deprecation insights before minor version upgrades.

Example

PROJECT=shop-dev-4821; NUM=987654321098
kubectl create namespace shop
kubectl create serviceaccount orders -n shop

# Grant the Kubernetes service account itself publish rights on one topic
gcloud pubsub topics add-iam-policy-binding orders --role=roles/pubsub.publisher \
  --member="principal://iam.googleapis.com/projects/$NUM/locations/global/workloadIdentityPools/$PROJECT.svc.id.goog/subject/ns/shop/sa/orders"

# Pod spec: just run as that KSA; client libraries pick up the identity via ADC
kubectl -n shop patch deployment orders \
  -p '{"spec":{"template":{"spec":{"serviceAccountName":"orders"}}}}'

kubectl -n shop create poddisruptionbudget orders-pdb --selector=app=orders --min-available=1

Remember

  • Grant IAM roles to Kubernetes service accounts via Workload Identity Federation
  • Private nodes, restricted control plane and network policies
  • PDBs, probes and replicas make automatic upgrades safe

Watch out for

  • Giving the node service account broad roles so every Pod on the node inherits them.

Check yourself

  1. Why prefer Workload Identity Federation over granting roles to the node service account?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: cloud.google.com/kubernetes-engine/docs/concepts/workload-identity