GCP ACE: Containers, Kubernetes, and Building Images with Cloud Build
Google Kubernetes Engine shows up across the Associate Cloud Engineer exam’s deployment and operations domains, but GKE itself rests on two ideas you need solid first: what a container is, and what problem Kubernetes solves once you have more than a handful of them. This article covers both, then walks through building a container image with Cloud Build — the step that normally comes right before a GKE deployment.
Containers vs. virtual machines
A container packages application code together with its runtime, libraries, and configuration into a single unit that runs the same way regardless of the host. Unlike a VM, a container doesn’t carry its own kernel — it shares the host machine’s kernel and gets its isolation from two Linux kernel features:
- Namespaces give each container its own isolated view of resources: process IDs, network interfaces, mount points, hostnames, users.
- cgroups (control groups) limit and account for how much CPU, memory, and I/O a container (or group of processes) can use. Google contributed cgroups to the Linux kernel.
| Containers | Virtual Machines | |
|---|---|---|
| Virtualizes | The operating system | The hardware |
| Guest OS | Shares the host kernel | Runs a full guest OS per VM |
| Size | Lightweight (MBs) | Heavier (GBs) |
| Isolation | Logical, at the OS level | Hardware-level |
| Startup time | Seconds or less | Minutes |
An image is the read-only template a container is created from — your filesystem plus metadata (entrypoint, exposed ports, environment variables). Each instruction in a Dockerfile produces a cacheable, read-only layer; a running container adds one writable layer on top. Ordering a Dockerfile so rarely-changing steps (installing dependencies) come before frequently-changing ones (copying application code) keeps builds fast, since Docker reuses cached layers that haven’t changed:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
# Cached unless requirements.txt changes
RUN pip install -r requirements.txt
# Changes most often, so it goes last
COPY . .
CMD ["python", "app.py"]
Why Kubernetes
Running one container is trivial. Running hundreds across multiple machines, keeping them healthy, routing traffic to them, and rolling out updates without downtime is not — that’s the problem Kubernetes solves. It’s a portable, open-source platform for managing containerized workloads through declarative configuration: you describe the state you want (3 replicas of this image, reachable on port 80), and Kubernetes’ control loop continuously reconciles the actual state to match it.
The objects you’ll see repeatedly on the exam:
| Object | Purpose |
|---|---|
| Pod | Smallest deployable unit — one or more containers sharing network and storage |
| Deployment | Manages a set of identical Pods; handles rolling updates and self-healing |
| Service | Stable network endpoint and load balancing for a set of Pods |
| ConfigMap | Non-sensitive configuration injected into Pods |
| Secret | Sensitive data (credentials, tokens) injected into Pods |
| Namespace (Kubernetes, not Linux) | Logical partition of a cluster — isolates resources between teams or environments |
A minimal Deployment manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
kubectl apply -f deployment.yaml # declare desired state
kubectl get pods -l app=web # check actual state
kubectl scale deployment web --replicas=5
If a Pod crashes, the Deployment’s controller replaces it automatically — that’s the self-healing behavior the exam expects you to recognize. Google Kubernetes Engine (GKE) is Google Cloud’s managed implementation of this platform: Google runs and upgrades the control plane, and (depending on the mode — covered in the next article) can manage the worker nodes too.
Building a container image with Cloud Build
Before a container can run on GKE, it has to exist as an image in a registry. Cloud Build is Google Cloud’s managed CI/CD service for building, testing, and pushing images — typically to Artifact Registry.
Image URLs for Artifact Registry follow this exact format:
LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME
Option 1 — Dockerfile only, no config file
Run from the directory containing your source and Dockerfile:
gcloud builds submit --tag europe-southwest1-docker.pkg.dev/my-project/my-repo/my-app
Option 2 — a cloudbuild.yaml build config
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'europe-southwest1-docker.pkg.dev/my-project/my-repo/my-app', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'europe-southwest1-docker.pkg.dev/my-project/my-repo/my-app']
images: ['europe-southwest1-docker.pkg.dev/my-project/my-repo/my-app']
gcloud builds submit --config cloudbuild.yaml .
Two ways to push the built image matter for the exam:
| Method | When the image is pushed | Shows up in build results |
|---|---|---|
Top-level images: field | After the build completes | Yes — visible via console, Build.get(), gcloud builds list |
A docker push step | Mid-build | No |
| Both together | Mid-build, and recorded | Yes |
Option 3 — Buildpacks, no Dockerfile needed
gcloud builds submit --pack image=europe-southwest1-docker.pkg.dev/my-project/my-repo/my-app
If you don’t specify a builder, Cloud Build defaults to gcr.io/buildpacks/builder.
Running the image locally
One-time Docker credential setup for your Artifact Registry host:
gcloud auth configure-docker europe-southwest1-docker.pkg.dev
docker run europe-southwest1-docker.pkg.dev/my-project/my-repo/my-app
Exam Takeaways
- Containers virtualize the OS and share the host kernel; VMs virtualize hardware and carry a full guest OS each.
- Namespaces (Linux) provide isolation; cgroups provide resource limits — don’t confuse these with Kubernetes Namespaces, which partition a cluster logically.
- An image is a read-only template; a container is a running instance with a writable layer on top.
- Kubernetes works on a declarative model: you set desired state, controllers reconcile actual state to match it.
- A Pod is the smallest deployable unit; a Deployment manages Pods and handles rolling updates and self-healing.
- GKE is Google’s managed Kubernetes — Google always manages the control plane; node management depends on the mode (Autopilot vs. Standard, next article).
- Artifact Registry image URLs follow
LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE_NAME— know this format cold. gcloud builds submit --tagbuilds from a Dockerfile with no config file; acloudbuild.yamlgives you multi-step control;--packbuilds via Buildpacks with no Dockerfile at all.- A build step using
docker pushpushes mid-build but doesn’t appear in build results; the top-levelimages:field does.