Prepare and test your skills
Prepare and test your skills
Deploying applications to Cloud Run (opens in a new tab) is the process of turning source code or container images into revision-based services that scale automatically and respond to HTTP requests and events. Source code flows from a developer directory to Cloud Build (opens in a new tab) for image creation, then to Artifact Registry (opens in a new tab) for storage, and finally to Cloud Run as a new revision that serves traffic. Event sources such as Pub/Sub reach the same services through Eventarc triggers, while Apigee sits in front of backends to expose and protect public APIs.
Source-based deployment to Cloud Run turns application files into a running revision without requiring a developer-written Dockerfile. The platform path depends on both Cloud Build and Artifact Registry, so source deployment is only available in regions supported by both services. When a Dockerfile is present, Cloud Build uses that Dockerfile, and when no Dockerfile is present, Google Cloud's buildpacks detects the language and builds from a secure base image. If neither --image nor --source is supplied, gcloud run deploy defaults to source deployment.
Google Cloud's buildpacks is an open-source system that converts source code into a runnable container image. A buildpack handles one part of the build, such as a language runtime or package manager, while builders group buildpacks into collections that inspect source code, create a build plan, and produce a production-ready image. Supported languages include Go, Node.js, Python, Java Spring Boot, Kotlin and other JVM languages built with Maven or Gradle, .NET, Ruby, PHP, and an OS-only runtime. Language detection happens automatically from files in the source directory, dependencies are installed from the standard package repository, and a Procfile names the process to run when the container starts and is required for some runtimes including Python.
Building with buildpacks can run remotely on Google Cloud or locally on a developer machine. The Artifact Registry Docker repository must already exist before the build, and the image reference uses the format LOCATION-docker.pkg.dev/PROJECT_ID/REPO_NAME/PATH:TAG.
| Build option | Where the build runs | What must be installed locally |
|---|---|---|
Cloud Build with --pack | Remotely on Google Cloud with no local Docker setup | Google Cloud CLI |
pack command line with --publish | Locally on the developer machine, then pushed to the registry | Docker and pack |
A remote build follows an ordered workflow. First, change to the folder containing the application sources. Then run gcloud builds submit --pack image=IMAGE_URL with the target Artifact Registry image URL. Then wait for Cloud Build to run the builder, package the image, and push it to the registry.
Permissions are split between the deployer and the build identity. Billing must be enabled and the Artifact Registry, Cloud Build, and Cloud Run Admin APIs must be enabled. The deployer needs Cloud Run Source Developer (roles/run.sourceDeveloper), Service Usage Consumer (roles/serviceusage.serviceUsageConsumer), and Service Account User (roles/iam.serviceAccountUser) on the Cloud Run service identity. The Compute Engine default service account used by Cloud Build needs Cloud Run Builder (roles/run.builder), and that grant can take a couple of minutes to propagate.
The source-to-service command gcloud run deploy SERVICE --source . uploads a local directory, builds the image, stores it, and creates a new revision. Each revision bundles image and configuration together, so changing identity, environment variables, or resources creates a new revision. Build environment variables apply only during image construction, while runtime environment variables and secrets apply to the running revision. The built container must respect the container contract by listening for HTTP requests on the port defined by the PORT environment variable that Cloud Run injects. A compose.yaml file can declare build directory, port mapping such as 8080:8080, environment variables, secrets, and volume mounts together for gcloud run compose up.
With-build and no-build deployments are the two source paths, divided by whether Cloud Build creates the image. With-build deployment is the default and installs dependencies in the cloud. No-build deployment is a Preview path that uploads a pre-packaged archive directly to a Cloud Storage bucket and runs it on a selected base image with no Cloud Build step. Choose no-build when speed matters and the archive is already self-contained, x86-compatible, 250 MiB or smaller, and uses a supported runtime with no Dockerfile, such as nodejs24 or the operating-system-only image osonly24.
Event-driven invocation of Cloud Run means Eventarc listens for events and calls a Cloud Run service only when a matching event occurs. Traffic flows from the event source through Eventarc filtering to the Cloud Run destination, which receives the event as an HTTP POST request. This design keeps producers and consumers decoupled, so Cloud Run scales up only when events arrive.
Reliable handlers are stateless, so each request is handled independently with no required data held in instance memory. Traffic flows from clients to any available instance and then from that instance to shared storage such as databases, queues, and files. Because no instance owns the conversation, the platform can add, remove, or restart instances without losing work. Failures are contained with complementary patterns where the circuit breaker stops sending traffic to a failing service, exponential backoff retries with increasing delays, and graceful degradation serves reduced functionality instead of passing failure upstream.
An Eventarc trigger is a routing rule defined by its source category, event provider, and event type. The provider is the product that emits the event, such as Cloud Pub/Sub, Cloud Storage, Firestore, or Firebase Remote Config, and the event type is the specific action such as google.cloud.pubsub.topic.v1.messagePublished. Trigger configuration starts by choosing Google sources, custom sources built by your own applications, or third-party sources from non-Google providers. Event filtering selects which CloudEvents are delivered based on exact attribute matches on fields such as type, with payload encoding of application/json or application/protobuf. The trigger, the monitored resource, and the destination service should be in the same region to reduce latency.
Routing to Cloud Run uses a transport and a destination. The transport identifies the Pub/Sub topic that Eventarc monitors, and the destination identifies the Cloud Run service name and region that receives events at the root path / unless a custom path such as /route is configured. Creating a Pub/Sub trigger follows an ordered workflow. First, deploy the Cloud Run service from a container or from source. Then open the service details, go to the Triggers tab, and add a Pub/Sub trigger. Then choose Pub/Sub as the provider with event type google.cloud.pubsub.topic.v1.messagePublished and select or create the topic to monitor. Then confirm the destination, region, service account, and retry setting and create the trigger.
Push delivery carries identity with each request. Data flows from the publisher to the Pub/Sub topic, then from the subscription to the Cloud Run endpoint as an HTTPS POST with an OpenID Connect (OIDC) token minted for the trigger service account. If no account is selected, the trigger uses the Compute Engine default service account. A dedicated user-managed service account is recommended for production because it follows least privilege. The trigger service account needs Cloud Run Invoker (roles/run.invoker) and Pub/Sub Subscriber (roles/pubsub.subscriber), the publishing identity needs Pub/Sub Publisher (roles/pubsub.publisher), and a new trigger can take up to two minutes to move from inactive to active.
Exam tip: Eventarc filtering uses exact match only and does not support wildcards or regular expressions, and event source filters cannot be modified after the trigger is created.
A Cloud Run event receiver is an HTTP service that accepts CloudEvents from Eventarc or push requests from Pub/Sub as authenticated requests. In this system Eventarc uses an IAM service account as the trigger identity, Pub/Sub carries the event, and Cloud Run verifies the caller before passing the request to application code. Each hop is protected by a separate role grant, so publishing, pulling, and invoking are authorized independently.
Trigger identity is the IAM service account that Eventarc uses when it invokes the receiver. If no account is selected, the trigger falls back to the Compute Engine default service account, which is acceptable for testing but production must use a dedicated user-managed service account with only minimum permissions. Default service accounts no longer receive broad access automatically in newer organizations because the organization policy constraint iam.automaticIamGrantsForDefaultServiceAccounts blocks automatic Editor grants for organizations created after May 3, 2024. A secure receiver is configured in dependency order: first create a dedicated service account, then grant least-privilege runtime roles, then attach the same account as the Cloud Run service identity and as the Eventarc trigger service_account, then create the trigger with authenticated delivery.
Eventarc routing rules connect a source to a destination through filters, transport, and identity. Traffic flows from the source to the Eventarc trigger, then from the trigger to the destination service over HTTPS as a POST to / by default or to a configured path. Trigger types define where events come from as Google sources, custom sources, or third-party sources. Core criteria include the CloudEvents type, the monitored resource such as a specific topic or bucket, region alignment in the same region, and payload encoding.
Cloud Pub/Sub messaging decouples producers from receivers through a named topic channel. Publishers broadcast events to the topic, and subscribers react without publishers knowing how processing happens. A push subscription causes Pub/Sub to deliver each message as an HTTP POST to a webhook endpoint such as Cloud Run without polling, with typical latencies on the order of 100 milliseconds. Leased or pull-style delivery causes subscriber clients to obtain individual leased messages and hold each lease until processing succeeds. Pub/Sub also provides dead-letter queues and filtering to isolate unprocessable messages and select which messages reach a subscriber.
All Cloud Run services are deployed privately by default and cannot be accessed without authentication, while --allow-unauthenticated deploys a publicly accessible receiver. To accept authenticated invocations, the trigger must use a service account with roles/run.invoker on the receiver service. Configuring routing follows an ordered flow: first deploy the receiver service, then create the Eventarc trigger with --destination-run-service, --destination-run-region, and --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished", then select the transport topic by omitting --transport-topic to create a new topic or setting it to reuse an existing topic, then publish a message with gcloud pubsub topics publish to generate an event.
Versioning, exposing, and securing APIs is the practice of publishing backend services through a managed entry point while evolving them without breaking existing clients. On Google Cloud, Apigee sits in front of backends such as Cloud Run functions (opens in a new tab) and Cloud Run services to validate requests and enforce authentication. Traffic flows from the client caller to Apigee and then from Apigee to the backend service, so policy checks run before requests reach application code.
Secure API endpoints with Apigee means placing policy checks between the client and the backend so unsafe traffic never reaches application code. Apigee enforces request validation that checks shape and content, traffic control that limits volume and protects backends from overload, and authentication that verifies caller identity. Gateway threat-protection policies sanitize input at the gateway layer, including JSONThreatProtection for malformed or oversized JSON, XMLThreatProtection for malformed or oversized XML, RegularExpressionProtection for SQL, NoSQL, and command injection patterns, and SOAPMessageValidation for SOAP structure. API keys are verified by Extensible Service Proxy V2 (ESPv2) with Service Control, and application restrictions bind a key to allowed websites, IP addresses, or apps so a request from an unlisted referrer is rejected even if the key is valid.
An API proxy is the HTTP endpoint on Apigee that maps a public URL to a backend service and defines expected query parameters, headers, body, credentials, and response format. The proxy isolates the app developer from the backend, so the team can change internal logic as long as the public API stays consistent. An API product is a bundle of one or more proxies combined with a service plan that sets access limits, security, and monitoring. Publishing and consuming a product follows an ordered handoff. First, the provider creates proxies that map public URLs to backends. Then the provider creates a product that bundles the proxies with limits. Then the provider deploys the proxies and product. Then the developer registers a client app and receives an API key that must be included in every request. Then the developer calls the API through the proxies while Apigee authenticates the key.
Traffic management with SpikeArrest and Quota policies keeps traffic within backend capacity and contractual limits. Both policies can be used in one proxy when a service needs surge protection and contractual limits together.
| Policy | How it controls traffic | Choose when |
|---|---|---|
| SpikeArrest | Limits request rate sent from the proxy to the backend to smooth bursts | The risk is sudden spikes, denial-of-service traffic, or faulty clients causing lag or outage |
| Quota | Maintains a distributed counter per app, developer, key, or token over a time interval | The goal is to enforce business contracts or service-level agreements |
A quota value set on an API product does not automatically enforce itself; the value is a default limit referenced by Quota policies in the proxies. An operation-level quota takes precedence over the product-level quota, and for high-traffic APIs the Quota policy should use longer intervals such as a day or month because the policy is computationally expensive. Gateway options differ by scope where API Gateway fronts serverless backends, Cloud Endpoints streamlines APIs on GKE and Cloud Run, and Apigee provides enterprise-scale management with advanced threat protection, OAuth 2.0, caching, quotas, mediation, and analytics.
API versioning evolves an API without breaking existing clients. Additive changes preserve backward compatibility, including new optional parameters and new response properties that REST clients ignore if unknown. Breaking changes alter the existing contract and force clients to change, such as renaming functions or changing types like integer to string. When a stable endpoint needs a significant change, the change is placed in a new endpoint and bundled into a new API version. Stable endpoints allow no breaking changes except extreme cases, beta endpoints are in active development and may change, and deprecated endpoints are still usable now but will be deleted in a future release. Migrating to a new version moves client code in order from auditing legacy callers through setting up OAuth 2.0 and IAM, mapping endpoints to regional URLs, updating payloads, and validating in staging before production. The C++ deployment quickstart (opens in a new tab) shows the same promotion idea of validating a service build before serving production traffic.
Continue with this study guide: Deploying applications to Cloud Run
Deploying containerized applications on Google Kubernetes Engine (GKE) (opens in a new tab) is the process of describing workloads declaratively, exposing them to traffic, and delivering them through an automated pipeline. The same immutable container image moves from development to production while manifests, external configuration, load balancers, and delivery tools handle placement and routing. Health probes and autoscaling keep those workloads available as versions change and demand shifts.
Configuration of Kubernetes manifests and resource management describes, places, and configures applications on GKE without rebuilding images. A manifest states desired resources such as replica count, update strategy, and compute requests, while ConfigMaps and Secrets inject environment-specific settings at deploy time. The Kubernetes API (opens in a new tab) then administers, scales, and monitors those workloads from source control to the cluster.
A Kubernetes deployment manifest is a declarative file based on the Kubernetes Resource Model (KRM) that states the desired state of an application. Tools such as Cloud Build with the gke-deploy builder update the resource file to use the image digest instead of a tag, add recommended labels, retrieve credentials for target clusters, and wait until submitted resources are ready. Namespaces divide cluster resources among teams, an app instance name must be unique within its namespace, and namespaces ending in -system are reserved for GKE components.
Resource management in GKE centers on how Pods, which are sets of containers, are placed onto nodes, which are Compute Engine virtual machines grouped to form a cluster. The Kubernetes control plane runs the API server and system controllers on Google-operated instances, so operations staff focus on applications while Google manages scheduling. Cluster utilization and cost depend on the relationship between what running Pods request and what nodes provide.
| Cluster mode | Who manages nodes and control plane | Billing basis |
|---|---|---|
| GKE Autopilot | Google Cloud manages both nodes and control plane | Pay only for compute resources requested by running Pods |
| GKE Standard | Google Cloud manages control plane, customer manages nodes | Pay for all resources on nodes, regardless of Pod requests |
Externalized configuration injects configuration files and secrets at deployment time instead of baking environment values into the image. ConfigMaps and Secrets provide that externalized configuration, so the same immutable artifact can move from development to quality assurance to production with only its injected configuration changing. Persistent data for stateful workloads uses storage services rather than ConfigMaps, including persistent disks with GKE, managed databases like Cloud SQL, Firestore, and Spanner, file storage like Filestore, and object storage like Cloud Storage.
Service exposure on GKE publishes containerized workloads so clients can reach them reliably from inside the cluster, from a private network, or from the internet. Three Kubernetes APIs divide this work by scope: Kubernetes Service groups Pod endpoints into one stable endpoint, Ingress routes external HTTP(S) traffic through a managed load balancer, and the Gateway API provides advanced Layer 7 routing through the GKE Gateway controller. All three depend on Cloud Load Balancing and on backend endpoints that GKE keeps updated as Pods start and stop.
A Kubernetes Service groups a set of Pod endpoints into a single stable address. A client sends a request to the stable address, and the request is routed to one of the healthy Pods, so individual Pod restarts do not break connectivity. By default the Service gets a stable cluster IP usable only inside the cluster, while other Service types widen that reach to node ports, external load balancers, or external DNS names. For HTTP(S) web traffic, a Service of type LoadBalancer handles TCP/UDP directly, while HTTP(S) routing uses a Service of type NodePort as the backend for Ingress.
Ingress is a Kubernetes resource that encapsulates rules for routing external HTTP(S) traffic to internal Services. On GKE, the GKE Ingress controller implements Ingress by automatically creating and managing an external Application Load Balancer. When an Ingress object is created, the controller builds the load balancer in a fixed dependency chain where the URL map uses host rules and path matchers that reference backend services, each backend service corresponds to a Service of type NodePort, and each backend gets instance groups or network endpoint groups (NEGs) plus a Google Cloud health check derived from readiness probe settings.
The GKE Gateway controller (opens in a new tab) is Google's implementation of the Kubernetes Gateway API for Cloud Load Balancing, and it configures Layer 7 Application Load Balancers. Gateway API is designed as a more expressive successor to Ingress with better support for traffic management and multi-tenancy. GKE Gateway is the recommended choice for new deployments with those needs, while Ingress remains viable for simpler routing. Gateway API splits configuration across Gateway listeners for ports and hostnames, HTTPRoute rules for path-based routing and traffic splitting, and Policy controls for underlying infrastructure. Traffic therefore flows from the internet client to the Gateway listener, then through matching HTTPRoute rules to the target Service.
Container-native load balancing distributes traffic directly to individual Pod IP addresses using NEGs rather than to nodes. With the GCE_VM_IP_PORT NEG type, each Pod endpoint is registered as a backend, which improves performance, visibility, and use of Cloud Service Mesh. Container-native load balancing is enabled by default when Services were created in GKE clusters version 1.17.6-gke.7 and higher, the cluster is VPC-native, and the cluster does not use Shared VPC or GKE Network Policy.
Reliable access depends on how inbound traffic enters, how it is distributed, and how outbound traffic leaves. An external Application Load Balancer listens on the public internet through Google points of presence, while an internal Application Load Balancer listens within a VPC network. Inbound traffic follows an ordered path. First, an internet client sends a request that reaches the load balancer created by a Service, Ingress, or Gateway resource. Then the load balancer routes the request to a healthy node. Then the node forwards traffic to the appropriate Pod, handled by kube-proxy or by eBPF on clusters with GKE Dataplane V2. All GKE clusters require outbound connectivity to *.googleapis.com, *.gcr.io, and *.pkg.dev, and in private clusters Cloud NAT lets Pods initiate outbound access while Private Google Access reaches Google services without the public internet.
Exam tip: GKE Autopilot bills on compute resources requested by running Pods, while GKE Standard bills on all node resources even when Pods request less.
Configuring CI/CD workflows for container deployment connects source changes to running workloads through build, test, store, and deploy steps. In this chain, Cloud Build builds and tests images, Artifact Registry stores approved images, and Cloud Deploy or the gke-deploy builder delivers them to GKE clusters. The workflow triggers automatically when source code changes, so every commit can produce the same tested artifact.
Producing each image follows the same ordered sequence. First, Cloud Build builds the container from source and Dockerfile and creates an image digest. Then Cloud Build runs unit, functional, integration, load, and Container Structure Tests. Then, if tests succeed, Cloud Build pushes the image to Artifact Registry and places build artifacts in a Cloud Storage bucket. Cloud Build also performs vulnerability scanning and only approves the image after successful scan results, while Binary Authorization signs the approved image before deployment.
Consistent naming makes each execution repeatable. Release images use semantic versioning tags such as 1.4.0, while pre-release images use the Git commit hash from the main branch. Workload images are built from a small set of tightly controlled base images, and the same tagged immutable artifact is promoted through environments instead of being rebuilt in each environment. Rapid pipelines complete in 10 minutes or less for fast feedback on feature branches, while full pipelines take longer for comprehensive checks on the main branch. Promotion from staging to production typically requires manual approval.
Hardening images combines repository controls, scanning, and deployment policy so only trusted images reach GKE. Artifact Registry provides access control, data exfiltration prevention, and vulnerability scanning through Artifact Analysis, while Binary Authorization blocks violating images at deploy time. Binary Authorization requires attestations such as passed vulnerability scan, passed quality assurance testing, and product owner sign-off, and continuous validation logs policy conformance in Cloud Logging. Migrating existing images can use tools such as gcrane to copy images into Artifact Registry, which supports the target-cluster deployment pattern (opens in a new tab).
Workload Identity Federation for GKE lets a Kubernetes workload act as a Google Cloud IAM service account without managing keys. Traffic flows from a Pod using its Kubernetes service account to Google Cloud APIs, and Google Cloud trusts that identity through federation. The recommended pattern uses a unique Kubernetes service account for each Service, so each application gets only the permissions its own identity carries. Each pipeline step also uses at least its own service account, and distinct accounts per environment keep development, testing, and production independent.
Implementation of deployment strategies and health monitoring updates containerized applications without losing availability. GKE acts as the orchestration tool that manages scaling and upgrading logic, so teams compose deployment logic with built-in mechanisms. Rolling update deployment replaces instances in small groups while traffic continues to flow to the mix of old and new Pods. Recreate fully scales down the old version before scaling up the new version, blue-green deploys a parallel set and switches traffic when ready, and canary releases to a limited subset before general availability. GKE has built-in support for recreate and rolling strategies, while blue-green and canary depend on tools such as Spinnaker or Cloud Deploy. Google Cloud Observability provides logging and monitoring signals for rollback decisions.
Implementing Kubernetes health checks means configuring probes so GKE restarts stuck containers and stops sending traffic to unready Pods. The readiness probe controls whether a Pod receives traffic, the liveness probe controls whether a container is restarted, and the startup probe blocks the other two until initialization finishes. Data flows through a fixed gate: first the startup probe must succeed, then liveness and readiness checking begins. A startup failure shuts down and restarts the container, a liveness failure kills and restarts the container to recover from deadlock, and a readiness failure removes the Pod from endpoints without termination until the probe passes again.
Probe timing balances fast detection against restart churn. The initialDelaySeconds setting delays the first probe, periodSeconds controls re-check frequency, and failureThreshold controls consecutive failures before action. A startup probe protects slow initialization better than only lengthening liveness delay. Probe endpoints should stay local and simple, such as a lightweight HTTP endpoint returning 200 OK, and must never call other services. The Pod containerPort must match the Service targetPort and Ingress backend port, and changing a readiness probe requires redeploying Pods and Ingress so GKE recreates the external health check.
| Handler | What the kubelet sends | Choose when |
|---|---|---|
| HTTP GET probe | HTTP GET to path and port, success is 200-399 | The app serves HTTP and has a health endpoint |
| TCP socket probe | TCP connection to port, success is accepted connection | The app uses non-HTTP TCP with no HTTP endpoint |
| gRPC probe | gRPC health check call, success is SERVING | The app communicates over gRPC services |
| Exec command probe | Command inside container, success is exit code 0 | Health is only visible to a local file or process |
Incorporating Horizontal Pod Autoscaler (HPA) attributes configures how GKE adds or removes Pods to keep performance stable. Each HPA controls one workload such as a Deployment and runs a repeating control loop that checks live metrics against a target. The replica count always stays between minReplicas and maxReplicas, with stabilization rules that prevent oscillation. A percentage target such as averageUtilization: 50 requires CPU or memory requests on every container because utilization is usage divided by requests. The autoscaling/v1 API supports only CPU, while autoscaling/v2 supports CPU, memory, and custom or external metrics. When multiple metrics are configured, the controller uses the largest recommended replica count. The Gateway preparation model (opens in a new tab) shows a similar pattern where traffic signals flow from Gateway to Service to Pods and HPA compares them to per-Pod capacity.
The metric pipeline for custom signals flows from Pods to Google Cloud Managed Service for Prometheus, through a metrics adapter, to the HPA controller. First, a PodMonitoring resource tells Managed Service for Prometheus what to scrape. Then Managed Service for Prometheus stores time series in Cloud Monitoring. Finally, the adapter exposes values through custom-metrics or external-metrics APIs. Scale-up is allowed to react quickly to protect latency, while scale-down waits for metrics to stay low over a stabilization window to avoid flapping.
Continue with this study guide: Deploying containers to GKE
PORT environment variable.Source code flows to Cloud Build for image creation, then to Artifact Registry for storage, and finally to Cloud Run as a new revision that serves traffic. Each revision bundles image and configuration together, and the built container must listen for HTTP requests on the port defined by the PORT environment variable that Cloud Run injects.
Use SpikeArrest to smooth bursts and protect backends from overload, and use Quota to enforce business contracts or service-level agreements. SpikeArrest limits the request rate sent from the proxy to the backend for sudden spikes, denial-of-service traffic, or faulty clients, while Quota maintains a distributed counter per app, developer, key, or token over a time interval.
Google Kubernetes Engine (GKE) Autopilot bills only for compute resources requested by running Pods, while Google Kubernetes Engine (GKE) Standard bills for all resources on nodes regardless of Pod requests. Autopilot has Google Cloud manage both nodes and control plane, while Standard has Google Cloud manage the control plane and the customer manage nodes.
Last updated