GKE Workload Identity and Artifact Registry Setup Guide#

This guide explains how to set up Workload Identity in GKE and configure access to Google Artifact Registry.

Prerequisites#

  • Google Cloud SDK installed

  • Access to a GKE cluster

  • Required permissions to create and manage service accounts

Project Setup#

Set your project:

export NAMESPACE=your-k8s-namespace
export RELEASE=your-helm-release-name

export PROJECT=$(gcloud config get-value project)
# set the cluster related info (you can list cluster using gcloud container clusters list)
export CLUSTER_NAME=your-cluster-name
export CLUSTER_REGION=$(gcloud container clusters list --filter="name=${CLUSTER_NAME}" --format="get(location)")
gcloud config set project ${PROJECT}
# Retrieve the Workload Identifier Namespace associated with your cluster:
export CLUSTER_WIN=$(gcloud container clusters describe ${CLUSTER_NAME} \
  --region=${CLUSTER_REGION} \
  --format="value(workloadIdentityConfig.workloadPool)")

Important

Make sure Workload Identity is enabled in your cluster!

Service Account Creation and Configuration#

  1. Create a service account for Workload Identity:

Go to the GCP console and create a new service account (or reuse an existing one)

gcloud iam service-accounts create workload-identity-sa\
    --display-name="workload identity service account" \
    --description="Service account to use for Workload Identity in GKE"
export SA=workload-identity-sa@${PROJECT}.iam.gserviceaccount.com
  1. Configure Workload Identity bindings for Kubernetes service accounts:

gcloud iam service-accounts add-iam-policy-binding \
    ${SA} \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:${CLUSTER_WIN}[${NAMESPACE}/${RELEASE}-dynamo-operator-controller-manager]"

gcloud iam service-accounts add-iam-policy-binding \
    ${SA} \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:${CLUSTER_WIN}[${NAMESPACE}/${RELEASE}-dynamo-operator-image-builder]"

gcloud iam service-accounts add-iam-policy-binding \
    ${SA} \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:${CLUSTER_WIN}[${NAMESPACE}/${RELEASE}-dynamo-operator-component]"

Artifact Registry Access#

Option 1: Project-Level Access#

Grant read and write access at the project level:

# Grant reader role
gcloud projects add-iam-policy-binding ${PROJECT} \
  --member="serviceAccount:${SA}" \
  --role="roles/artifactregistry.reader"

# Grant writer role
gcloud projects add-iam-policy-binding ${PROJECT} \
  --member="serviceAccount:${SA}" \
  --role="roles/artifactregistry.writer"

Option 2: Repository-Level Access#

Grant access to specific repository:

gcloud artifacts repositories add-iam-policy-binding your-artifact-repository \
  --location=${CLUSTER_REGION} \
  --project=${PROJECT} \
  --member="serviceAccount:${SA}" \
  --role="roles/artifactregistry.reader"

GKE Node Access to Artifact Registry#

This is needed to make sure pods can pull images from Artifact Registry without needing to specify an imagePullSecret

For GKE Autopilot#

# Get project number
export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT} --format='value(projectNumber)')

# Grant access to the default compute service account
gcloud projects add-iam-policy-binding ${PROJECT} \
  --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
  --role="roles/artifactregistry.reader"

For Standard GKE#

# Get node service account
export NODE_SERVICE_ACCOUNT=$(gcloud container clusters describe ${CLUSTER_NAME} \
  --region ${CLUSTER_REGION} \
  --format="get(nodeConfig.serviceAccount)")

# Grant access to node service account
gcloud projects add-iam-policy-binding ${PROJECT} \
  --member="serviceAccount:${NODE_SERVICE_ACCOUNT}" \
  --role="roles/artifactregistry.reader"

Adding annotations to enable Workload Identity#

This is an example of values.yaml used to deploy Dynamo Cloud using custom GCP annotations to enable Workload Identity.

dynamo-operator:
  ...
  controllerManager:
    serviceAccount:
      create: true
      annotations:
        iam.gke.io/gcp-service-account: your-sa@your-gcp-project.iam.gserviceaccount.com
  ...
  dynamo:
    dockerRegistry:
      useKubernetesSecret: false
      server: us-central1-docker.pkg.dev/your-project/your-registry
    components:
      serviceAccount:
        annotations:
          iam.gke.io/gcp-service-account: your-sa@your-gcp-project.iam.gserviceaccount.com
    imageBuilder:
      serviceAccount:
        annotations:
          iam.gke.io/gcp-service-account: your-sa@your-gcp-project.iam.gserviceaccount.com
    ...

....

You can use it during helm installation (last step of deploy.sh)

helm upgrade --install ${RELEASE} platform/ -f values.yaml --namespace ${NAMESPACE}

Important Notes#

  1. Prerequisites for Image Pulling:

    • Workload Identity must be enabled on your GKE cluster

    • GKE nodes’ service account must have the artifactregistry.reader role

  2. Troubleshooting:

    • If pods can’t pull images, verify both Workload Identity and node service account configurations

    • Check service account annotations on Kubernetes service accounts

    • Verify IAM bindings are correctly set up

References#