Prepare and test your skills
Prepare and test your skills
Containerization and application refactoring is the process of packaging code and its dependencies into portable container images and reshaping deployments to run on orchestration platforms. On Google Cloud, Artifact Registry (opens in a new tab) stores container images, Cloud Build (opens in a new tab) produces and tests images, Cloud Deploy (opens in a new tab) implements deployment logic, and workloads run on Google Kubernetes Engine (GKE) (opens in a new tab) for orchestrated containers or Cloud Run (opens in a new tab) for serverless containers. Refactoring moves a team from manual or virtual-machine deployments to automated pipelines that build once, test the image itself, and promote the same immutable artifact across environments.
Assessing workloads for containerization means building an inventory of artifacts, dependencies, test coverage, and versions before changing how they are packaged. The assessment determines whether containerization is possible and worthwhile, since some workloads are not cloud-ready or cannot be containerized for technical or licensing reasons. Data warehouse solutions, for example, are typically not deployed with container orchestration tools because they are not designed to run in ephemeral containers.
The assessment reviews six efficiency and compatibility areas:
Building a foundation for containerized workloads means provisioning identity, networking, and storage infrastructure that supports development, testing, and production environments. A Google Cloud resource hierarchy separates those environments so changes can be tested and validated independently. Isolation is strengthened by using at least one service account for each deployment process step, such as one account to produce the artifact and a different account to store that artifact in a repository.
The plan and build phase provisions infrastructure in an ordered set of tasks:
Container-specific foundation work then places Artifact Registry in a dedicated Google Cloud project to isolate the registry and its maintenance tasks. The team provisions and configures GKE clusters for orchestration, including Autopilot when automatic cluster management is desired, and provisions persistent storage for stateful workloads.
Automated container image production means source code changes trigger image builds without manual packaging for each deployment. The artifact building process is automatically triggered each time source code is modified so the team gets immediate feedback about each change. Cloud Build builds the artifact, runs the test suite against it, and, if tests succeed, stores the result in Artifact Registry.
Each image moves through the same production sequence:
Test coverage for images uses tools such as InSpec for compliance of runtime environments and Container Structure Tests to verify files, locations, and content inside the container. Extending tests to the image ensures that base operating system content, packages, and configuration are validated together with the application.
Managing container images in Artifact Registry means controlling base images, workload images, tags, and security controls from one repository service. Base container images provide the common starting point for workload images, and the set of base images is tightly controlled and supported to avoid proliferating unsupported runtime environments. Workload images extend those base images with application code, and both layers are covered by automated tests.
Repeatable identification ties every image to either a release or a source revision. Release images use semantic versioning tags, while pre-release images use an identifier tied to the codebase point, such as the Git commit hash from the main branch. Older images can be migrated from a source registry to Artifact Registry with tools such as gcrane or Rackware SWIFT to support rollback to arbitrary points in time. Artifact Registry is then protected with access control, data exfiltration prevention, vulnerability scanning through Artifact Analysis, and deployment enforcement through Binary Authorization.
Exam tip: Promote the same immutable image from development to quality assurance to production instead of rebuilding it at each stage, so the tested artifact is the deployed artifact.
Refactoring workloads and deployment processes means changing descriptors, code, and pipelines so the same artifact runs on Google Cloud with environment-specific configuration injected at deploy time. Workload refactoring focuses on the smallest change needed for GKE, including Kubernetes object descriptors such as Deployments and Services, container descriptors such as Dockerfiles, and source code that depends on source-environment add-ons or extensions. Configuration files and secret injection produce immutable artifacts, so the team deploys the artifact in development, then moves that identical artifact to quality assurance and finally to production, which lowers production risk.
Repository and pipeline refactoring shifts storage and deployment gradually to avoid a single risky cutover:
Cloud Deploy composes the deployment logic using orchestration mechanisms for scaling, upgrading, and strategies such as rolling updates or blue/green deployments, rather than implementing that logic manually. Kubernetes labels and annotations configure Google Cloud resources that GKE provisions automatically, such as provisioning an internal load balancer instead of an external one by annotating a LoadBalancer Service.
Containerizing code for Cloud Run means providing a container image that includes code, packages, binary dependencies, and the operating system needed to run the service. A Dockerfile commonly declares how to build that image, very often starting from a base image with a FROM instruction sourced from Docker Hub or Google Cloud Marketplace. Binaries brought into the image must be compiled for Linux ABI x86_64, and Docker Hub rate limits for the Docker Free plan make Artifact Registry a more controllable source for dependencies. Google Cloud's buildpacks provide an alternative that builds source code from supported languages into container images without writing a Dockerfile.
The compute target depends on operational needs and control requirements:
| Target | Primary use | Management model |
|---|---|---|
| Cloud Run | Serverless execution of container images with integrated load balancing and autoscaling | Google manages infrastructure; team provides the image |
| Google Kubernetes Engine (GKE) | Complex applications, microservices, and continuous operation needing fine-grained control and scalability | Team configures clusters, networking, storage, and deployment objects; Autopilot can automate cluster configuration |
| Batch | Scheduling, queuing, and executing parallelizable batch workloads, including containerized jobs | Fully managed scheduling on Google Cloud resources |
Stateful workloads that move to GKE also require explicit persistent storage, including persistent disks managed with GKE, fully managed databases such as Cloud SQL, Firestore, and Spanner, file storage such as Filestore, or object storage such as Cloud Storage.
Securing and optimizing container deployments means adding vulnerability controls, attestations, and broader monitoring after the pipeline is working. Security shifts early in the pipeline through expert code review, linting and static analysis, vulnerability scanning of built images, and Binary Authorization to prevent vulnerable images from deploying to clusters. Binary Authorization can also require attestations from different entities or systems, such as passed vulnerability scan, passed quality assurance testing, and sign-off from the product owner.
Optimization then extends monitoring to cover artifact production, deployment processes, and new runtime environments. Test coverage expands beyond minimum end-to-end tests to more use cases, including integration, load, compliance, and reliability testing, with logs, metrics, and error reports examined in Google Cloud Observability. During transitions, hybrid operation is expected, with some workloads deployed by existing tools and others by container orchestration tools until migration iterations are complete.
Cloud Run (opens in a new tab) is a fully managed serverless platform that runs highly scalable containerized applications directly on Google Cloud infrastructure. You provide source code or a container image and Cloud Run builds the container when needed, so you do not create a cluster or provision and manage servers. You only pay for the time that code runs, with pay-per-use billing rounded up to the nearest 100 milliseconds.
Cloud Run services are best suited for stateless, request-driven or event-driven workloads such as web services, APIs, and batch jobs. A stateless service does not keep local session or file data between requests, which lets Cloud Run start, stop, and replicate container instances freely as traffic changes. Cloud Run containers are ephemeral, so any file written temporarily inside a container instance comes out of the available memory for the service and disappears when the instance stops.
For persistent data, a Cloud Run service depends on external storage:
Concurrency on Cloud Run controls how many simultaneous requests each container instance handles, alongside settings such as environment variables and network connections. Incoming requests flow from clients to the Cloud Run routing layer, which automatically routes each request to an appropriate back-end container and performs load balancing without separate configuration. Cloud Run manages container instance autoscaling for you, adding instances when concurrent requests increase and removing them when demand falls. This tradeoff favors simplicity and speed over infrastructure control, since you tune concurrency and connections but cannot customize the underlying hosts.
A Cloud Run revision is an immutable snapshot of a service created with each deployment, including its container image and settings. Each revision is automatically scaled to the number of container instances needed to handle the traffic assigned to that revision. When a revision receives no traffic, it scales to zero container instances by default, so you pay nothing while idle. You can change this default with the minimum instances setting to keep one or more instances idle or warm, which reduces cold-start latency but keeps resources running and billable.
Exam tip: A Cloud Run revision scales to zero by default; set minimum instances only when you need a warm instance to avoid cold starts.
Traffic splitting on Cloud Run directs client traffic across two or more revisions of the same service, which enables safe release patterns without redeploying infrastructure. A canary release sends a small share of traffic to a new revision while most traffic stays on the stable revision, so issues affect few users before full rollout. A blue-green deployment runs old and new versions side by side and then switches all traffic from the old set to the new set at once, which avoids interruption but temporarily needs capacity for both versions and requires backward-compatible changes. A rolling deployment sits between them by updating capacity one portion at a time and shifting more users to the new revision as more capacity is updated, with a load balancer keeping users from bouncing between versions.
Cloud Run provides automatic request routing by default, and enterprise routing flows from clients through an external HTTP(S) load balancer to serverless network endpoint groups (serverless NEGs) that point to the service. Use this path when you need Cloud CDN caching, serving traffic from multiple regions, or middleware such as API Gateway (opens in a new tab) to enhance the service. For migration, traffic flows from a Global external Application Load Balancer to the same application running on both Cloud Run and Google Kubernetes Engine (GKE) (opens in a new tab), letting you gradually shift traffic from one platform to the other.
Choose Cloud Run when the workload is stateless and benefits from automatic scaling and pay-per-use, and choose GKE when the workload is stateful or needs custom nodes, networking, and Kubernetes control:
| Feature | GKE | Cloud Run |
|---|---|---|
| Deployment and management | You manage clusters, nodes, networking, scaling, and upgrades | You provide code or image with no cluster to manage |
| Control and flexibility | Full control over nodes, policies, and add-ons | Limited to service settings such as concurrency and connections |
| Application types | Stateless and stateful, including complex microservices | Stateless, request-driven or event-driven services and jobs |
| Pricing model | Pay per cluster per hour | Pay per use, rounded to nearest 100 milliseconds |
Google Kubernetes Engine (GKE) (opens in a new tab) is a managed container orchestration platform that runs containerized workloads on Kubernetes clusters. A GKE environment consists of nodes, which are Compute Engine virtual machines grouped into a cluster, and a control plane that runs system components such as the Kubernetes API server. You package applications into containers, deploy sets of containers as Pods to nodes, and use the Kubernetes API to administer, scale, and monitor workloads while Google Cloud manages the control plane for you.
A container orchestration tool manages the infrastructure under a deployment so you can focus on composing deployment logic instead of implementing it. The tool provides abstractions that generalize deployments across environments and includes built-in logic for scaling and upgrading workloads. You can start with these mechanisms in a current environment and port largely the same implementation to Google Cloud, which builds operational experience before migration.
GKE orchestration depends on matching the workload to ephemeral containers and declarative management. Use orchestration when workloads are already containerized or when analysis shows containerization is possible and beneficial. Data warehouse solutions are typically not deployed this way because they are not designed to run in ephemeral containers.
Containerizing a workload must cover its operational needs:
When the foundation is ready, GKE Autopilot can automatically manage cluster configuration, including nodes, scaling, and security, so new workloads do not require manual infrastructure provisioning.
A Pod is an app-specific logical host for one or more containers that runs on a node instance. Containers in the same Pod can share resources, including a set of shared storage volumes. Those volumes let data survive container restarts and be shared among containers in the Pod, and a single container and volume must still use a Pod to connect them logically.
A Deployment manifest declares the desired state for those Pods in YAML, and its attributes are a superset of a Cloud Run service definition. The manifest sets apiVersion to apps/v1 and kind to Deployment, replaces the namespace with the target GKE cluster namespace such as default, and defines a label in both metadata.labels and spec.template.metadata.labels. Under spec.template, the manifest adds replicas for the number of Pod instances and selector.matchLabels that selects Pods using that label, while serviceAccountName references a Kubernetes service account that can act as an IAM service account through Workload Identity Federation for GKE. The container section identifies the receiving port with containerPort, which defaults to 8080, so the Deployment, Service, and autoscaler all agree on how to find and route to the Pods.
A Service exposes a Deployment at a stable endpoint inside or outside the cluster, while Ingress is a collection of rules for routing external traffic to Kubernetes endpoints. Traffic flows from external clients to the load balancer, then from the load balancer to the Service, then from the Service to the selected Pods using the Deployment label. A Cloud Run service that used a Serverless VPC Access connector does not need that connector after migration because GKE workloads run directly in a Virtual Private Cloud (VPC) network.
GKE supports two main external routing paths with different capabilities. The simplest path adds type: LoadBalancer to the Service, which provisions Compute Engine network load balancing. That path balances load based on IP data such as address, port, and protocol type, uses forwarding rules that point to target pools of available instances, supports additional TCP and UDP protocols such as SMTP traffic, and lets the application directly inspect packets. The advanced path creates an Ingress resource, which provisions and configures a Compute Engine HTTP or HTTPS load balancer for features such as HTTPS termination, content-based routing, and cross-region load balancing. Choose network load balancing for simple TCP and UDP exposure and packet inspection, and choose Ingress when external HTTP traffic needs richer routing and load-balancing behavior.
Exam tip: type: LoadBalancer creates network load balancing, while an Ingress resource provisions an HTTP or HTTPS load balancer.
Scaling on GKE operates at two levels that depend on each other. The Horizontal Pod Autoscaler (HPA) scales the workload by changing the number of Pods in a Deployment, while the Cluster Autoscaler scales the infrastructure by resizing the node pool in the cluster. Pod scheduling depends on nodes with free resources, so pending Pods trigger infrastructure growth and underused nodes allow infrastructure shrinkage.
The Cluster Autoscaler periodically checks for Pods that are waiting for a node with free resources and resizes the node pool when resizing would allow those waiting Pods to be scheduled. The Cluster Autoscaler also monitors node usage over time and deletes a node when the node has not been needed for an extended period and all of its Pods can be scheduled elsewhere. This two-level relationship means application demand first changes Pod count through the HPA, and unschedulable or idle capacity then changes node count through the Cluster Autoscaler.
| Scaler | What it scales | When it acts |
|---|---|---|
| Horizontal Pod Autoscaler | Number of Pods in a Deployment | Demand requires more or fewer Pod replicas to serve the workload |
| Cluster Autoscaler | Number of nodes in a node pool | Waiting Pods need free node resources, or an unneeded node can be removed because its Pods fit elsewhere |
A migrated service is exposed and scaled through an ordered sequence:
80 to the container targetPort.This order matters because the Service selector depends on the Deployment label, and the autoscaler depends on the Deployment it scales. In Autopilot mode you pay only for compute resources requested by running Pods, while in Standard mode you pay for all resources on nodes regardless of Pod requests, so accurate Pod requests and replica behavior directly affect both performance and cost.
Choose Cloud Run when the workload is stateless and benefits from automatic scaling and pay-per-use billing rounded up to the nearest 100 milliseconds with no cluster to manage. Choose Google Kubernetes Engine (GKE) when the workload is stateful or needs custom nodes, networking, and Kubernetes control, including complex applications and microservices needing fine-grained control and scalability.
A Cloud Run revision is an immutable snapshot of a service created with each deployment, including its container image and settings. Each revision is automatically scaled to the number of container instances needed for its assigned traffic and scales to zero instances by default when it receives no traffic, so you pay nothing while idle unless the minimum instances setting keeps one or more instances warm to reduce cold-start latency.
Traffic splitting on Cloud Run directs client traffic across two or more revisions of the same service without redeploying infrastructure. A canary release sends a small share of traffic to a new revision while most traffic stays on the stable revision, while a blue-green deployment runs old and new versions side by side and then switches all traffic from the old set to the new set at once.
The Horizontal Pod Autoscaler scales the workload by changing the number of Pods in a Deployment based on observed demand. The Cluster Autoscaler scales the infrastructure by resizing the node pool when Pods are waiting for a node with free resources or when an unneeded node can be removed because its Pods can be scheduled elsewhere.
Last updated