Deploying applications

PCD notes, 24% of the exam, updated November 2026

This domain (about 24% of the exam) is about configuring and shipping applications: Cloud Run first, then GKE. Expect questions where a deployment is unhealthy, scales wrongly, needs a trigger, or needs a safe rollout. Know the command or manifest field that fixes each.

Deploying to Cloud Run

Deploy methods

Method Command or flow Notes
From source gcloud run deploy SERVICE --source . Cloud Build builds with a Dockerfile if present, otherwise buildpacks detect the language; the image goes to an Artifact Registry repository (cloud-run-source-deploy) and a revision is created
From a container image gcloud run deploy SERVICE --image REGION-docker.pkg.dev/... Image must be in Artifact Registry (or Docker Hub via a remote repo)
From a YAML spec gcloud run services replace service.yaml Declarative, Knative-style, good for GitOps
Cloud Run functions gcloud run deploy --function, or gcloud functions deploy Provide a function entry point and runtime; built with buildpacks
Cloud Deploy or Cloud Build Pipeline step Staged promotion across environments

Each deploy creates an immutable revision. Configuration (environment variables, secrets, CPU, memory, concurrency, service account, VPC settings) is part of the revision; changing it creates a new revision. Traffic goes to the latest revision by default (--no-traffic deploys without sending traffic).

Common deploy flags:

  • --service-account runs the revision as a dedicated, least-privilege identity (not the default Compute Engine account).
  • --set-env-vars, --set-secrets ENV=secret:version (or mount a secret as a file at a path), --memory, --cpu, --concurrency, --timeout, --min-instances, --max-instances.
  • --ingress limits who can reach the service: all, internal (VPC, Pub/Sub, Eventarc and similar), internal-and-cloud-load-balancing.
  • --no-allow-unauthenticated (the default) requires callers to hold roles/run.invoker; --allow-unauthenticated grants it to allUsers for public services.
  • --add-cloudsql-instances mounts a built-in Cloud SQL connection at /cloudsql/PROJECT:REGION:INSTANCE; --network/--subnet configures Direct VPC egress.
  • --tag and --no-traffic create a tagged revision URL for testing before it gets traffic.

Health checks: Cloud Run supports startup and liveness probes (HTTP, TCP or gRPC). There is no readiness probe; instances receive traffic once they have started and are listening. A failing startup probe stops the revision from becoming ready; a failing liveness probe restarts the container.

Revisions and traffic: list with gcloud run revisions list; roll back with gcloud run services update-traffic SERVICE --to-revisions PREVIOUS=100; send everything to newest with --to-latest. Gradual rollout: 10 percent, then 50, then 100, watching error rate and latency. Use tags to test or to have a stable URL for a specific revision.

Invoking Cloud Run with triggers and receivers

Cloud Run services can be invoked by HTTP, by events, by schedulers, by tasks, or by other services.

Source How it reaches Cloud Run
Pub/Sub push subscription Pub/Sub POSTs the message to the service URL with an OIDC token from a service account; that account needs roles/run.invoker. Return a 2xx to acknowledge; any other response (or a timeout) retries with backoff
Eventarc Creates a trigger that delivers a CloudEvent over HTTP to the service. Sources: direct events from services (for example Cloud Storage object finalised), Cloud Audit Logs events for any audited API call, Pub/Sub messages, Firebase and third-party providers
Cloud Scheduler HTTP target with OIDC token on a cron schedule
Cloud Tasks HTTP target tasks with OIDC token, rate limited and retried
Workflows HTTP connector with authentication

Eventarc details that matter:

  • Triggers are regional (most) and filter by event type and attributes. The trigger’s service account needs roles/run.invoker on the target and roles/eventarc.eventReceiver.
  • Direct Cloud Storage events need the Cloud Storage service agent to have roles/pubsub.publisher.
  • Audit Log based triggers need the relevant Data Access audit logs enabled for data events.
  • Eventarc delivers through Pub/Sub transport, so delivery is at-least-once: make the receiver idempotent (use the CloudEvent id as a de-duplication key).
  • Eventarc Advanced supports a message bus, pipelines, enrolment and transformations for more complex routing.

Event receivers (the service code) should:

  • Parse the CloudEvent (headers ce-type, ce-source, ce-id; body is the data), or the Pub/Sub push envelope (message.data is base64).
  • Respond quickly with 2xx after a safe hand-off; return 5xx only when a retry is wanted. Return 2xx for permanently bad messages (or route them to a dead-letter topic) to avoid endless retries.
  • Be idempotent, since duplicates happen.
  • Keep work under the ack deadline (Pub/Sub push waits up to 600 seconds, configurable). For long work, return fast and hand off to a Cloud Run job or Cloud Tasks.
Scenario Best trigger
React to an object in Cloud Storage Eventarc direct Cloud Storage trigger
React to any Google Cloud API call (for example a VM created) Eventarc Cloud Audit Logs trigger
Application publishes custom messages for many consumers Pub/Sub topic with push subscription
Run something every night Cloud Scheduler (to HTTP or Pub/Sub)
Throttle calls to a rate-limited backend Cloud Tasks queue

Versioning, exposing and securing APIs with Apigee

Putting an API management layer in front of Cloud Run (or GKE, or any backend) gives versioning, security, throttling and analytics without changing the service.

  • API proxy: the facade developers call. It maps a base path (for example /v1/orders) to a target backend through policies.
  • Versioning: put the version in the base path (/v1, /v2) or header; each proxy has numbered revisions that you deploy to environments (test, prod) and can roll back. Run /v1 and /v2 side by side and deprecate on a schedule.
  • API products bundle proxies and operations with quotas; developer apps receive keys and credentials; developers discover products in the developer portal.
  • Security policies: VerifyAPIKey, OAuth 2.0 token validation, JWT verification, SAML, IP allow lists, threat protection (XML and JSON), CORS handling, and mTLS to the target. Use a service account and Google authentication from the proxy to a Cloud Run backend that requires IAM, and set the backend ingress to internal or load-balancer only so the gateway cannot be bypassed.
  • Traffic management: Quota (count per app/developer/period), Spike Arrest (smooth bursts), caching (ResponseCache, populate/lookup cache), and target servers for load balancing and failover.
  • Analytics and monitoring: built in; export to BigQuery.
  • Simpler alternative: API Gateway (OpenAPI-driven, keys and JWT) when you only need a front door for serverless backends.

Deploying containers to GKE

Deploying workloads

  • Cluster choices: Autopilot (Google manages nodes, bills per pod resource requests, enforces best practices) or Standard (you manage node pools). Use regional clusters for availability.
  • Deploy with manifests: kubectl apply -f deployment.yaml, Helm, Kustomize, or a pipeline (Cloud Build, Cloud Deploy, Config Sync).
  • Main objects: Deployment (stateless replicas with rolling updates), StatefulSet (stable identity and storage), Service (ClusterIP, NodePort, LoadBalancer), Ingress or Gateway API (HTTP(S) load balancing; container-native load balancing through NEGs routes directly to pods), ConfigMap and Secret, Job and CronJob.
  • Rolling updates: strategy.rollingUpdate.maxSurge (extra pods allowed) and maxUnavailable (pods that may be down). Watch with kubectl rollout status, undo with kubectl rollout undo deployment/NAME. Blue/green and canary use separate Deployments plus a Service selector switch or Gateway API weights, or Cloud Deploy.
  • Pull images from Artifact Registry. In current clusters the node or workload service account needs reader access; use Workload Identity Federation for GKE so pods use their own Google identity rather than node credentials (map KSA to IAM, annotate the Kubernetes service account).
  • Secrets: use the Secret Manager add-on (CSI driver) to mount Secret Manager secrets rather than storing credentials in Kubernetes Secret objects.
  • Set resource requests and limits so the scheduler places pods well and autoscalers can calculate; a pod exceeding its memory limit is OOMKilled, exceeding CPU is throttled.
  • Use PodDisruptionBudgets to keep a minimum number of pods during upgrades and node drains, and topology spread or anti-affinity to spread pods across zones.
  • Common troubleshooting: kubectl describe pod (events), kubectl logs, ImagePullBackOff (image name, tag or permissions), CrashLoopBackOff (app crashes or failing liveness probe), Pending (insufficient resources or unsatisfied scheduling constraints).

Health checks: probes

Probe Question it answers Failure effect
Startup probe Has the app finished starting? Other probes are disabled until it succeeds; if it never does, the container is killed and restarted. Use for slow-starting apps
Readiness probe Can it take traffic now? Pod is removed from Service endpoints and load balancer backends; not restarted
Liveness probe Is it stuck or deadlocked? The kubelet restarts the container
  • Probe mechanisms: httpGet, tcpSocket, exec and grpc.
  • Key fields and defaults: initialDelaySeconds (0), periodSeconds (10), timeoutSeconds (1), failureThreshold (3), successThreshold (1).
  • Design rules: readiness should check dependencies the pod needs to serve; liveness should be cheap and not depend on downstream services (otherwise a database outage restarts every pod). A too-aggressive liveness probe on a slow starter causes restart loops; add a startup probe or higher thresholds.
  • With container-native load balancing, the load balancer health check is derived from the readiness probe (or a BackendConfig can set it explicitly), so a failing readiness probe removes the pod from rotation.
  • Combine with graceful shutdown: handle SIGTERM, stop accepting new work, and use terminationGracePeriodSeconds (default 30) plus a preStop hook so in-flight requests finish.

Horizontal Pod Autoscaler

The HPA changes a Deployment’s replica count based on metrics.

  • Formula: desired replicas = ceil(current replicas x current metric / target metric). It checks about every 15 seconds. Defaults prevent flapping: scale down waits for a stabilization window (300 seconds by default).
  • Required attributes: target (Deployment), minReplicas, maxReplicas, and metrics. Resource-based CPU utilization targets only work if pods declare CPU requests, because utilization is measured relative to requests.
  • Metric types (autoscaling/v2): Resource (CPU, memory), Pods (a custom per-pod metric such as requests per second), Object (a metric of another object, such as an Ingress), External (outside metrics such as Pub/Sub backlog num_undelivered_messages). Custom and external metrics come through Managed Service for Prometheus, the Custom Metrics Stackdriver Adapter or the Cloud Monitoring integration.
  • behavior rules control the speed of scale up and down (policies and stabilization windows).
  • HPA scales pods; the cluster autoscaler (Standard) or Autopilot adds nodes so pending pods can schedule. Vertical Pod Autoscaler adjusts requests and limits; do not let HPA and VPA act on the same metric (CPU or memory) for one workload.
  • Scale queue workers on backlog or latency, not only CPU.
Symptom Likely fix
HPA shows unknown for CPU Pods have no CPU requests, or metrics server issue
Pods scale but stay Pending Cluster out of capacity: cluster autoscaler or Autopilot, or quota
Rapid scale up and down Tune stabilization window and thresholds
Queue consumer lags while CPU is low Use an external metric (backlog)

Release strategies with Cloud Deploy

Cloud Deploy is the managed continuous delivery service for GKE, Cloud Run and others.

  • A delivery pipeline is an ordered list of targets (dev, staging, prod). Each pipeline stage uses Skaffold to render and deploy.
  • A release is an immutable snapshot (image digests and manifests); a rollout is the deployment of a release to one target.
  • Strategies: standard (all at once), canary (percentages such as 25, 50, 100, with optional verify between phases), and blue/green style options for supported runtimes. Approvals can be required on targets. Verify runs a test container after a rollout; a failed verification fails the rollout. Rollback redeploys a previous release. Automations promote automatically or advance canary phases.
  • It integrates with Cloud Build (create a release from CI) and provides an audit trail and delivery metrics.

Exam checklist

  • gcloud run deploy --source builds with a Dockerfile or buildpacks and stores the image in Artifact Registry; each deploy creates an immutable revision.
  • Rollback and canary on Cloud Run are traffic changes between revisions; use --no-traffic and --tag to test first.
  • Pub/Sub push to Cloud Run needs an OIDC token and roles/run.invoker; 2xx acknowledges, other codes retry; receivers must be idempotent.
  • Eventarc delivers CloudEvents; audit log triggers need audit logs enabled; direct Cloud Storage triggers need the service agent to publish.
  • Apigee: base path versioning, proxy revisions and environments, API products and keys, Quota and Spike Arrest, OAuth; lock the backend to the gateway.
  • Probes: startup for slow starters, readiness removes from traffic, liveness restarts; liveness must not depend on downstream services.
  • HPA needs requests for CPU utilization, min and max replicas; external metrics (Pub/Sub backlog) for queue workers; cluster autoscaler adds nodes.
  • Rolling update fields maxSurge and maxUnavailable; kubectl rollout undo to roll back.
  • Cloud Deploy: pipelines, targets, releases, rollouts, canary, approval, verify, rollback.

Test what you just read. 32 practice questions on deploying applications.

Practise this domain

All PCD notes