Managing Compute Engine, GKE, and Cloud Run: Day-2 Operations
Managing compute resources on Google Cloud means operating three surfaces day to day: Compute Engine instances (connect over SSH, list what is running, protect disks with snapshots and images), GKE clusters (inspect nodes, Pods, and Services with kubectl, size node pools, and tune Horizontal and Vertical Pod Autoscalers), and Cloud Run services (ship new revisions, split traffic between them, and bound autoscaling with instance limits). The exam tests whether you can do each task with the right tool — gcloud for infrastructure, kubectl for Kubernetes objects — and whether you know which autoscaler solves which problem: HPA adds replicas, VPA right-sizes requests, and the cluster autoscaler adds nodes. This lesson walks through remote access with IAP, snapshot schedules, Artifact Registry access from GKE, node pool operations, Autopilot resource requests, Cloud Run traffic management, attaching GPUs and TPUs, deploying agents to Agent Runtime, and managing Workbench notebooks and Cloud Workstations.
On this page8 sections
- Connecting to and viewing Compute Engine instances
- Working with snapshots and images
- Viewing GKE inventory and connecting GKE to Artifact Registry
- Working with GKE node pools
- Working with Kubernetes resources: Pods, Services, StatefulSets
- Horizontal and vertical Pod autoscaling — and Autopilot requests
- Cloud Run: new revisions, traffic splitting, and autoscaling
- GPUs, TPUs, Agent Runtime, notebooks, and Cloud Workstations
- Connect to Compute Engine instances with gcloud compute ssh, including through IAP when no external IP exists
- Create, schedule, and delete snapshots and images, and choose between them for backup versus instance templating
- Inspect GKE clusters with kubectl and manage node pools, including node pool autoscaling
- Configure Horizontal and Vertical Pod Autoscalers and explain when each applies, including on Autopilot
- Deploy new Cloud Run revisions, split traffic between revisions, and configure min and max instances
- Identify how GPUs and TPUs attach to compute, and where Agent Runtime, Workbench notebooks, and Cloud Workstations fit
Connecting to and viewing Compute Engine instances
You connect to a Linux Compute Engine instance with gcloud compute ssh INSTANCE_NAME --zone=ZONE, which generates and propagates an SSH key for you, and you list what is running with gcloud compute instances list. The list command shows every instance in the project across zones, with status, internal IP, and external IP; add --filter= expressions to narrow it (for example --filter=status=RUNNING) and gcloud compute instances describe INSTANCE_NAME --zone=ZONE to see one instance's full configuration.
The exam's favorite twist is an instance with no external IP address. You cannot SSH to it directly from the internet, but you do not need a bastion host: Identity-Aware Proxy (IAP) TCP forwarding tunnels SSH through Google's infrastructure to the instance's internal IP. Run gcloud compute ssh INSTANCE_NAME --zone=ZONE --tunnel-through-iap. Two prerequisites matter: a firewall rule must allow ingress on TCP port 22 from IAP's source range 35.235.240.0/20, and the user needs the roles/iap.tunnelResourceAccessor role. If either is missing, the tunnel fails — that misconfiguration is a classic troubleshooting question.
Two access-management features round this out. OS Login ties SSH access to IAM identities instead of manually managed metadata keys: enable it with the instance or project metadata key enable-oslogin=TRUE, then grant roles/compute.osLogin (or roles/compute.osAdminLogin for sudo). For Windows instances, generate credentials with gcloud compute reset-windows-password and connect over RDP instead of SSH.
Working with snapshots and images
Snapshots back up disks; images create instances. A snapshot is a point-in-time copy of a Persistent Disk or Hyperdisk, and after the first full snapshot, subsequent snapshots are incremental — they store only changed blocks, which keeps cost down. Create one with gcloud compute snapshots create SNAPSHOT_NAME --source-disk=DISK_NAME --source-disk-zone=ZONE (or gcloud compute disks snapshot), list them with gcloud compute snapshots list, and delete with gcloud compute snapshots delete. Snapshots can be taken while the disk is attached and in use, and you can restore by creating a new disk from the snapshot with gcloud compute disks create NEW_DISK --source-snapshot=SNAPSHOT_NAME.
To automate backups, attach a snapshot schedule — a resource policy — to the disk: gcloud compute resource-policies create snapshot-schedule POLICY_NAME --max-retention-days=14 --daily-schedule --start-time=04:00 --region=REGION, then gcloud compute disks add-resource-policies DISK_NAME --resource-policies=POLICY_NAME --zone=ZONE. The retention setting deletes old snapshots automatically, so you never script cleanup by hand.
A custom image, by contrast, is a golden template: build it from a stopped instance's boot disk, a snapshot, or another image with gcloud compute images create IMAGE_NAME --source-disk=DISK_NAME --source-disk-zone=ZONE, then launch identical instances from it. Use image families so instance templates always reference the latest image in the family rather than a pinned name. When a question asks for scheduled disk backups, answer snapshots with a snapshot schedule; when it asks for a repeatable VM build or a template for a managed instance group, answer custom images.
Viewing GKE inventory and connecting GKE to Artifact Registry
You inspect a GKE cluster with gcloud for the infrastructure and kubectl for the workloads. gcloud container clusters list shows clusters, versions, and node counts; gcloud container clusters get-credentials CLUSTER_NAME --region=REGION writes credentials into your kubeconfig so kubectl can talk to the cluster. From there, kubectl get nodes lists nodes, kubectl get pods --all-namespaces lists Pods across namespaces, kubectl get services lists Services with their cluster IPs and external endpoints, and kubectl describe pod POD_NAME surfaces events — the first place to look when a Pod is stuck in Pending or ImagePullBackOff.
GKE pulls container images from Artifact Registry, and access is governed by IAM on the node's service account. Nodes authenticate as their attached service account, so that account needs the roles/artifactregistry.reader role on the repository (or project) hosting the images. Same-project pulls with the default configuration generally work out of the box; the failure mode the exam probes is a cross-project repository — the Pod sits in ImagePullBackOff until you grant the node service account Artifact Registry Reader in the project that owns the repository: gcloud artifacts repositories add-iam-policy-binding REPO --location=LOCATION --member=serviceAccount:NODE_SA_EMAIL --role=roles/artifactregistry.reader.
Reference images by their full Artifact Registry path, for example us-central1-docker.pkg.dev/PROJECT_ID/REPO/IMAGE:TAG. If the image path, tag, and permissions are all correct and pulls still fail, check that the node pool's access scopes were not restricted below the default — scopes and IAM roles must both allow the access.
Working with GKE node pools
A node pool is a group of nodes in a Standard-mode cluster that share one configuration — machine type, disk, image type, labels, and taints. You cannot change a node pool's machine type in place; you add a new pool and migrate workloads. Add one with gcloud container node-pools create POOL_NAME --cluster=CLUSTER_NAME --machine-type=e2-standard-4 --num-nodes=3 --region=REGION, list pools with gcloud container node-pools list --cluster=CLUSTER_NAME, and remove one with gcloud container node-pools delete POOL_NAME --cluster=CLUSTER_NAME — GKE cordons and drains its nodes so Pods reschedule onto remaining pools.
Node pool autoscaling is the cluster autoscaler applied per pool: it adds nodes when Pods are unschedulable for lack of capacity and removes underutilized nodes when their Pods fit elsewhere. Enable it at creation or later with gcloud container clusters update CLUSTER_NAME --enable-autoscaling --node-pool=POOL_NAME --min-nodes=1 --max-nodes=10 --region=REGION. Note what triggers it: pending Pods, not node CPU utilization. If Pods set no resource requests, the scheduler thinks everything fits and the autoscaler never acts — a frequent scenario question.
Manual resizing is separate: gcloud container clusters resize CLUSTER_NAME --node-pool=POOL_NAME --num-nodes=5 sets a fixed count. In Autopilot clusters there are no node pools to manage at all — Google provisions nodes automatically from your Pods' resource requests, which is why Autopilot questions pivot to requests (covered below) rather than pool sizing.
Working with Kubernetes resources: Pods, Services, StatefulSets
The Kubernetes objects the exam expects you to operate are Pods, Deployments, Services, and StatefulSets. A Pod is the smallest deployable unit — one or more containers sharing network and storage — but you rarely create bare Pods; a Deployment manages a ReplicaSet of identical, interchangeable Pods and handles rolling updates. Apply manifests with kubectl apply -f manifest.yaml, scale with kubectl scale deployment web --replicas=5, roll out a new image with kubectl set image deployment/web web=IMAGE:v2, and revert with kubectl rollout undo deployment/web.
A Service gives Pods a stable virtual IP and DNS name, selecting backends by label. Know the three types cold: ClusterIP (internal-only, the default), NodePort (opens a port on every node), and LoadBalancer (provisions a Google Cloud passthrough Network Load Balancer with an external IP). For HTTP(S) routing, an Ingress or Gateway resource provisions an Application Load Balancer instead. Expose quickly with kubectl expose deployment web --type=LoadBalancer --port=80 --target-port=8080.
A StatefulSet is for workloads where identity matters — databases, quorum systems. Unlike a Deployment, it gives each Pod a stable ordinal name (db-0, db-1), a stable network identity via a headless Service, and a dedicated PersistentVolumeClaim per replica that survives rescheduling. Pods are created and terminated in order. When a scenario mentions per-replica persistent storage or stable Pod names, the answer is a StatefulSet, not a Deployment.
Horizontal and vertical Pod autoscaling — and Autopilot requests
The Horizontal Pod Autoscaler (HPA) changes the number of Pod replicas; the Vertical Pod Autoscaler (VPA) changes each Pod's CPU and memory requests; the cluster autoscaler changes the number of nodes. They answer different questions, and the exam loves making you pick.
| Autoscaler | What it scales | Trigger | How to enable | Best for |
|---|---|---|---|---|
| Horizontal Pod Autoscaler | Replica count of a Deployment or StatefulSet | CPU or memory utilization, or custom and external metrics | kubectl autoscale deployment web --min=2 --max=10 --cpu-percent=60 | Stateless workloads with variable traffic |
| Vertical Pod Autoscaler | Per-Pod CPU and memory requests | Observed historical usage | VerticalPodAutoscaler object; modes Off, Initial, Auto | Right-sizing requests you guessed wrong |
| Cluster autoscaler (node pool autoscaling) | Node count in a node pool | Unschedulable Pods; underutilized nodes | gcloud container clusters update --enable-autoscaling --min-nodes --max-nodes | Matching node capacity to Pod demand |
VPA's modes matter: Off only publishes recommendations, Initial applies them at Pod creation, and Auto evicts and recreates Pods to apply new requests — disruptive for anything that cannot tolerate restarts. The standard gotcha: do not run HPA and VPA on the same workload using the same CPU or memory metric — VPA changes the requests that HPA's utilization percentage is computed against, and they fight. Combining VPA with an HPA driven by custom or external metrics is fine.
In Autopilot clusters, resource requests do double duty: Google provisions nodes from them and bills you for what your Pods request, not for nodes. Autopilot applies default requests when you omit them and enforces minimum and maximum values, adjusting out-of-range requests at admission. HPA and VPA both work on Autopilot, so the operational skill is the same — set honest requests, then let the platform handle nodes.
Cloud Run: new revisions, traffic splitting, and autoscaling
Every deployment to a Cloud Run service creates an immutable revision. Ship one with gcloud run deploy SERVICE_NAME --image=us-central1-docker.pkg.dev/PROJECT_ID/REPO/IMAGE:v2 --region=REGION; by default the new revision immediately receives 100% of traffic. Roll back by shifting traffic to the previous revision — revisions are kept, so rollback is a traffic change, not a rebuild.
Traffic splitting is how you do gradual rollouts and canaries. Deploy the new revision with --no-traffic so it starts at 0%, then shift: gcloud run services update-traffic SERVICE_NAME --to-revisions=SERVICE_NAME-00042-abc=90,SERVICE_NAME-00043-def=10. Watch error rates, then move to 100% or use --to-latest to send everything to the newest revision. You can also assign a tag to a revision (--tag=canary), which mints a dedicated URL for testing that revision directly with zero production traffic. The same revision-based traffic splitting applies to Cloud Run functions, since they run on Cloud Run; on GKE, traffic splitting is done with Kubernetes primitives instead — two Deployments behind one Service selector, or weighted routes on a Gateway resource.
Autoscaling in Cloud Run is automatic — instances scale with request load, down to zero by default — and you shape it with three knobs: --min-instances keeps warm instances to eliminate cold starts, --max-instances caps scale to protect downstream systems such as a Cloud SQL database with limited connections, and --concurrency sets how many simultaneous requests one instance handles (lower it for CPU-heavy, request-scoped work; keep it high for I/O-bound services). A scenario about cold-start latency wants min instances; one about overwhelming a backend wants max instances.
GPUs, TPUs, Agent Runtime, notebooks, and Cloud Workstations
Accelerators attach differently per platform. On Compute Engine, add a GPU at instance creation with gcloud compute instances create VM_NAME --machine-type=n1-standard-8 --accelerator=type=nvidia-tesla-t4,count=1 --maintenance-policy=TERMINATE --zone=ZONE — GPU instances cannot live-migrate during host maintenance, so the maintenance policy must be set to terminate (A- and G-series accelerator-optimized machine types instead have GPUs built into the machine type). GPU availability is zonal and gated by GPU quota, which you often must request first. On GKE, you create a GPU node pool with the same --accelerator flag and Pods claim them via nvidia.com/gpu resource limits; Autopilot lets Pods request GPUs directly in the Pod spec. TPUs — Google's custom ML accelerators — are provisioned as TPU VMs with gcloud compute tpus tpu-vm create or consumed through GKE and Google's managed AI services.
Agent Runtime on the Gemini Enterprise Agent Platform (formerly Vertex AI Agent Engine) is the managed runtime for deploying AI agents: you build an agent locally with a supported framework and the platform SDK, then deploy it to Agent Runtime, which handles hosting, scaling, and session management — no instances, clusters, or Cloud Run services for you to operate. Recognize it as the managed destination when a question asks where to deploy an agent without managing infrastructure.
For interactive data work, Workbench (on the same platform, formerly Vertex AI Workbench) provides managed Jupyter notebook instances that you create, stop, and resize like managed VMs — stop idle instances to stop paying for them — while BigQuery Studio offers Python notebooks directly inside BigQuery for SQL-plus-Python analysis without leaving the console. Finally, Cloud Workstations are managed, preconfigured developer environments: an admin defines a workstation configuration (machine type, container image, IDE) in a workstation cluster, developers launch personal workstations from it and connect from a browser or local IDE, and idle workstations shut down on a timeout to control cost. When the scenario is standardized, secure dev environments rather than data science notebooks, the answer is Cloud Workstations.
Tip. Expect scenario questions on SSHing to instances without external IPs (IAP tunneling, its firewall rule, and IAM role), choosing snapshots versus images and automating them with snapshot schedules, and diagnosing ImagePullBackOff caused by missing Artifact Registry permissions on the node service account. Autoscaling questions make you pick the right scaler — HPA for replicas, VPA for requests, cluster autoscaler for nodes — and know that unschedulable Pods, not CPU, trigger node scale-up. Cloud Run questions center on revision traffic splitting for canary rollouts and on min instances, max instances, and concurrency as the three autoscaling knobs.
- Use gcloud compute ssh with --tunnel-through-iap for instances without external IPs; IAP needs a firewall rule allowing 35.235.240.0/20 on port 22 and the roles/iap.tunnelResourceAccessor role.
- Snapshots are incremental disk backups you can automate with snapshot schedules; custom images are golden templates for launching identical instances.
- GKE nodes pull from Artifact Registry using the node service account, which needs roles/artifactregistry.reader — cross-project ImagePullBackOff means that grant is missing.
- Node pool autoscaling reacts to unschedulable Pods, not node CPU — Pods without resource requests will never trigger scale-up.
- HPA scales replica count, VPA rewrites Pod resource requests, and the cluster autoscaler scales nodes; never drive HPA and VPA from the same CPU or memory metric.
- Autopilot bills by Pod resource requests and provisions nodes for you — requests, not node pools, are the thing you manage.
- Every gcloud run deploy creates a revision; use --no-traffic plus update-traffic --to-revisions for canaries, and tags for private test URLs.
- Shape Cloud Run scaling with min instances (cold starts), max instances (protect backends), and concurrency (requests per instance).
Frequently asked questions
How do I SSH into a Compute Engine instance that has no external IP address?
Use IAP TCP forwarding: gcloud compute ssh INSTANCE_NAME --zone=ZONE --tunnel-through-iap. It tunnels SSH through Identity-Aware Proxy to the instance's internal IP, so no bastion host or external IP is needed. It requires a firewall rule allowing TCP 22 ingress from 35.235.240.0/20 and the roles/iap.tunnelResourceAccessor role on the user.
What is the difference between a snapshot and a custom image?
A snapshot is a point-in-time, incremental backup of a single disk, meant for data protection and restore — and it can be automated with snapshot schedules. A custom image is a reusable template, typically built from a prepared boot disk, meant for launching new, identical instances, often via instance templates and managed instance groups. Back up with snapshots; standardize builds with images.
When should I use the Horizontal Pod Autoscaler versus the Vertical Pod Autoscaler?
Use HPA when load varies and the workload scales by adding replicas — it adjusts the replica count based on CPU, memory, or custom metrics. Use VPA when individual Pods are over- or under-provisioned — it adjusts each Pod's CPU and memory requests based on observed usage. Do not run both against the same CPU or memory metric on one workload, because VPA changes the requests HPA measures utilization against.
Why do my GKE Pods show ImagePullBackOff when pulling from Artifact Registry?
Most often the node pool's service account lacks roles/artifactregistry.reader on the repository's project — the classic case is a repository in a different project from the cluster. Grant the node service account Artifact Registry Reader there, verify the full image path (REGION-docker.pkg.dev/PROJECT_ID/REPO/IMAGE:TAG), and confirm the tag exists.
How do I run a canary release on Cloud Run?
Deploy the new revision with gcloud run deploy --no-traffic so it takes 0% of traffic, optionally tag it (--tag=canary) to get a dedicated URL for testing, then shift a small share with gcloud run services update-traffic --to-revisions=OLD=90,NEW=10. Increase the split as confidence grows, and roll back instantly by shifting traffic back to the old revision.
What changes about compute management in a GKE Autopilot cluster?
You stop managing nodes entirely: there are no node pools to create, resize, or autoscale, and you are billed for your Pods' CPU and memory requests rather than for nodes. Google provisions capacity from those requests, applying defaults and enforcing allowed ranges when your values are missing or out of bounds. HPA and VPA still work, so workload autoscaling is unchanged.
Sign up free to mark lessons complete, bookmark topics and track your exam readiness.