11.3 Managing GKE Clusters: Node Pools, Workloads & Artifact Registry Access
Key Takeaways
- A node pool is a group of nodes within a cluster sharing identical configuration (machine type, image, disk, taints); every node in a pool carries the `cloud.google.com/gke-nodepool` label.
- A Standard cluster's default node pool uses 3 nodes per zone with general-purpose machine types on the `cos_containerd` image; specialized workloads (GPU, Spot, high-memory) get their own dedicated node pool.
- Node pools can be resized, upgraded, and deleted independently of one another — an upgrade to one pool does not force-upgrade any other pool in the same cluster.
- For GKE nodes to pull images from Artifact Registry in the same project, the node's service account needs `roles/artifactregistry.reader`; cross-project pulls require the same role granted explicitly in the target project.
- `kubectl` manages Kubernetes-level objects (Pods, Deployments, Services, StatefulSets); `gcloud container` manages GKE/cluster-level infrastructure (clusters, node pools) — the exam tests knowing which tool owns which layer.
Why This Topic Matters
Exam Domain 4's Google Kubernetes Engine (GKE) bullets — viewing running cluster inventory, working with node pools, working with Kubernetes resources, and configuring GKE access to Artifact Registry — are some of the densest in the whole ACE guide, and they cut across three distinct layers of the platform: cluster infrastructure, Kubernetes workload objects, and IAM. ACE scenario questions routinely combine all three in a single stem ("a Pod in a new node pool can't pull its image — why?"), so this section builds the mental model that keeps them straight.
Node Pools: The Infrastructure Layer
A node pool is a group of nodes within a cluster that all share the same configuration — machine type, boot disk, image, and any taints/labels. Every node is automatically tagged with the Kubernetes label cloud.google.com/gke-nodepool identifying which pool it belongs to, which lets you target scheduling decisions at a pool.
When you create a Standard cluster, GKE provisions a default node pool — 3 nodes per zone, general-purpose machine type, running the cos_containerd (Container-Optimized OS) image. Almost every real-world cluster grows beyond that default by adding purpose-built node pools:
| Node pool use case | What you customize |
|---|---|
| GPU/ML training workloads | Accelerator-attached machine types, taints so only GPU-tolerant Pods land there |
| Cost-optimized batch jobs | Spot VMs as the underlying node type |
| Compute-intensive workloads | A specific minimum CPU platform |
| Storage-heavy workloads | Local SSDs attached to each node |
| Isolated tenants or workload classes | Custom network interfaces, dedicated node images |
Key gcloud Commands
| Task | Command |
|---|---|
| Create a node pool | gcloud container node-pools create POOL_NAME --cluster=CLUSTER_NAME --machine-type=e2-standard-4 |
| List node pools in a cluster | gcloud container node-pools list --cluster=CLUSTER_NAME |
| Resize a node pool | gcloud container clusters resize CLUSTER_NAME --node-pool=POOL_NAME --num-nodes=N |
| Upgrade a specific pool | gcloud container clusters upgrade CLUSTER_NAME --node-pool=POOL_NAME |
| Delete a node pool | gcloud container node-pools delete POOL_NAME --cluster=CLUSTER_NAME |
Node pools upgrade and resize independently: upgrading one pool's Kubernetes version does not touch any other pool in the cluster, which is exactly how teams stage a rolling GKE version upgrade one pool at a time. Deleting a pool triggers a graceful node drain (capped at a one-hour termination period, and it can be configured to honor PodDisruptionBudgets). One rule the exam likes to test directly: at least one node pool must remain without restrictive taints, because core system Pods (like kube-dns) need somewhere untainted to schedule, or the cluster becomes unstable.
GKE Autopilot clusters remove this layer almost entirely — Google manages node provisioning and sizing for you, and billing is per-Pod-resource-request rather than per-node, trading node-pool control for zero node management overhead. On the exam, if a scenario says "we don't want to manage nodes at all," that's an Autopilot signal, not a node-pool-tuning signal.
Working with Kubernetes Resources (the Workload Layer)
Once nodes exist, kubectl — not gcloud — is the tool for the Kubernetes objects that actually run your application:
- Pods — the smallest deployable unit;
kubectl get pods,kubectl describe pod POD_NAME. - Deployments — declarative management of replica sets of stateless Pods;
kubectl get deployments,kubectl rollout status deployment/NAME. - Services — stable network endpoints (ClusterIP, NodePort, LoadBalancer) in front of a set of Pods;
kubectl get services. - StatefulSets — like Deployments but for workloads needing stable network identity and persistent storage per replica (databases, brokers);
kubectl get statefulsets.
A recurring exam distinction: gcloud container commands operate on the cluster/node-pool infrastructure, while kubectl commands operate on the Kubernetes API objects running inside that infrastructure. A question describing "view all running Pods across the cluster" wants kubectl get pods --all-namespaces, not a gcloud command — there is no gcloud equivalent for Kubernetes-object-level inventory.
Configuring GKE Access to Artifact Registry
This is the IAM layer, and it's where ACE candidates most often go wrong because the node, not the developer running kubectl apply, is what authenticates the image pull.
- Same-project pulls: if nodes run under the Compute Engine default service account, GKE provisions them with default access scopes that typically include read-only storage access, which is often sufficient. The robust, explicit answer the exam wants is granting the node's service account
roles/artifactregistry.readeron the Artifact Registry repository (or project). - Cross-project pulls: when the cluster lives in Project A but the image sits in an Artifact Registry repository in Project B, you must explicitly grant the node service account
roles/artifactregistry.readerin Project B — same-project default scopes do nothing across a project boundary. - Workload Identity does not change this: even when Pods use Workload Identity to assume a Kubernetes-service-account-mapped IAM identity for application API calls, the underlying image pull itself still authenticates as the node pool's own service account, not the Pod's Workload Identity. This is a frequently-tested nuance — don't assume Workload Identity automatically fixes an image-pull permission error.
- Local development/build auth:
gcloud auth configure-docker LOCATION-docker.pkg.devconfigures Docker's credential helper so a developer's own gcloud credentials can push/pull manually, but this is unrelated to how the cluster authenticates at runtime.
Realistic Exam Scenario
An ML team adds a new GPU node pool to an existing GKE Standard cluster to run training jobs, tainting the pool so only GPU-tolerant Pods schedule there. The training image lives in an Artifact Registry repository in a separate, centralized "images" project. Pods on the new node pool fail with ImagePullBackOff. The ACE-correct diagnosis: this is a cross-project Artifact Registry access gap — grant the GPU node pool's service account roles/artifactregistry.reader on the images project's repository (not the developer's own IAM identity, and not a Workload Identity binding, since image pulls use the node's identity).
A GKE Standard cluster in Project A needs to pull container images from an Artifact Registry repository located in Project B. What must be configured for the pulls to succeed?
Which statement correctly distinguishes gcloud container node-pools commands from kubectl commands in GKE administration?
A platform team wants to add a dedicated node pool for cost-optimized batch jobs while keeping existing production node pools completely unaffected by any changes. What GKE property makes this possible?