Table of Contents
hide
Google Cloud Building Containers Best Practices
Package a single app per container
- An “app” is considered to be a single piece of software, with a unique parent process, and potentially several child processes.
- A container is designed to have the same lifecycle as the app it hosts, so each of the containers should contain only one app. When a container starts, so should the app, and when the app stops, so should the container. for e.g. in the case of the classic Apache/MySQL/PHP stack, each component must be hosted in a separate container.
Properly handle PID 1, signal handling, and zombie processes
- Linux signals are the main way to control the lifecycle of processes inside a container.
- The app within the container should handle the Linux signals, as well as the best practice of a single app per container should be implemented.
- Process identifiers (PIDs) are unique identifiers that the Linux kernel gives to each process.
- PIDs are namespace, i.e. the containers PIDs are different from the host and are mapped to the PIDs on the host system.
- Docker and Kubernetes use signals to communicate with the processes inside containers, most notably to terminate them.
- Both Docker and Kubernetes can only send signals to the process that has PID 1 inside a container.
- For Signal handling and Zombie processes following can be followed
- Run as PID 1 and register signal handlers
- Launch the process with the
CMDand/orENTRYPOINTinstructions in the Dockerfile, which would give the PID 1 to the process - Use the built-in
execcommand to launch the process from the shell script. Theexeccommand replaces the script with the program and the process then inherits PID 1.
- Launch the process with the
- Enable process namespace sharing in Kubernetes
- Process namespace sharing for a Pod can be enabled where Kubernetes uses a single process namespace for all the containers in that Pod.
- Kubernetes Pod infrastructure container becomes PID 1 and automatically reaps orphaned processes.
- Use a specialized init system
- Init system such as
tinicreated especially for containers that can be used to handle signals and reaps any zombie processes
- Init system such as
- Run as PID 1 and register signal handlers
Optimize for the Docker build cache
- Images are built layer by layer, and in a Dockerfile, each instruction creates a layer in the resulting image.
- Docker build cache can accelerate the building of container images.
- During a build, when possible, Docker reuses a layer from a previous build and skips a potentially costly step.
- Docker can use its build cache only if all previous build steps used it.
Use Multi-Stage Builds
- Multi-stage builds allow separating the build environment from the runtime environment in a single Dockerfile using multiple
FROMstatements. - Build tools, compilers, and development dependencies are isolated in early stages and only the final artifacts are copied into the minimal runtime image.
- This significantly reduces the final image size and attack surface.
- Google Cloud Build supports multi-stage Dockerfiles natively and recommends separating building of the application from assembling its runtime container.
- Example pattern: use a full SDK image to compile, then copy binaries into a distroless or minimal base image for production.
Use Distroless or Minimal Base Images
- Distroless images (maintained by Google at
gcr.io/distroless/) contain only the application runtime and its dependencies — no package managers, shells, or other programs. - Distroless images drastically reduce the attack surface and result in smaller image sizes with fewer CVE findings.
- Available for multiple runtimes: Java, Python, Node.js, Go (static), .NET, and base/CC variants.
- For cases where a shell is needed for debugging, consider using the
:debugtag variants in non-production environments only. - Alternative minimal base images include Alpine Linux, Debian Slim, and Google’s managed base images.
Remove unnecessary tools
- Remove unnecessary tools helps reduce the attack surface of the app by removing any unnecessary tools.
- Avoid running as root inside the container: this method offers the first layer of security and could prevent attackers from modifying files
- Launch the container in read-only mode using the
--read-onlyflag from thedocker runor by using thereadOnlyRootFilesystemoption in Kubernetes. - Apply seccomp profiles to containers to restrict system calls to the kernel — GKE supports the default containerd seccomp profile and custom profiles for additional hardening.
- Use GKE Sandbox (gVisor) to run untrusted workloads with an additional kernel-level isolation layer that intercepts system calls.
Build the smallest image possible
- Smaller image offers advantages such as faster upload and download times
- To reduce the size of the image, install only what is strictly needed
- Use multi-stage builds to separate build dependencies from runtime dependencies
- Prefer distroless or scratch-based images for compiled languages (Go, Rust)
- Combine
RUNcommands with&&to reduce the number of layers and avoid leftover files from intermediate steps
Scan images for vulnerabilities
- For vulnerabilities, as the containers are supposed to be immutable, the best practice is to rebuild the image, patches included, and redeploy it
- As containers have a shorter lifecycle and a less well-defined identity than servers, a centralized inventory system would not work effectively
- Artifact Analysis (formerly Container Analysis) can scan images for security vulnerabilities in publicly monitored packages, including OS, Java, Go, Python, and Node.js packages
- Artifact Analysis provides both automatic scanning (triggered on every push to Artifact Registry) and on-demand scanning (manual scans of local or registry images)
- Generate Software Bill of Materials (SBOM) for your container images to track all dependencies and license compliance
- Integrate vulnerability scanning into CI/CD pipelines using Cloud Build and Binary Authorization to enforce that only verified, signed images are deployed
Using public image
- Consider before using public images as you cannot control what’s inside them
- Public image such as Debian or Alpine can be used as the base image and building everything on top of that image
- Use Assured Open Source Software (Assured OSS) from Google for curated and tested open source packages
- Pin images using SHA256 digest references (e.g.,
image@sha256:abc123...) rather than mutable tags like:latestto ensure reproducibility
Managed Base Images
- Managed base images are base container images that are automatically patched by Google for security vulnerabilities, using the most recent patches available from the project upstream
- Google provides Container-Optimized OS (cos) for running containers on Compute Engine and GKE nodes, which is automatically updated with security patches
Store Images in Artifact Registry
- Container Registry was shut down on March 18, 2025 — all container images must now be stored in Artifact Registry
- Artifact Registry supports both container images and non-container artifacts (Maven, npm, Python packages, etc.)
- Artifact Registry provides integrated vulnerability scanning through Artifact Analysis, IAM-based access control, and regional/multi-regional storage options
- Automatic migration tools are available to migrate existing gcr.io endpoints to Artifact Registry without downtime
Use Cloud Native Buildpacks
- Google Cloud’s buildpacks transform application source code into production-ready OCI container images without requiring a Dockerfile
- Buildpacks automatically detect the application language and framework, install dependencies, and produce optimized images following container best practices
- Supported languages include Go, Java, Node.js, Python, .NET, Ruby, and PHP
- Buildpacks produce reproducible builds and automatically apply security patches to the builder stack
- Integrated with Cloud Build, Cloud Run, and App Engine for seamless source-to-production workflows
- The default builder uses Ubuntu 24 as of 2025 (
gcr.io/buildpacks/builder)
Supply Chain Security
- Binary Authorization ensures that only trusted, signed container images are deployed to GKE, Cloud Run, or Distributed Cloud environments
- Implement SLSA (Supply chain Levels for Software Artifacts) framework to establish provenance and verify the integrity of build artifacts
- Software Delivery Shield provides an end-to-end software supply chain security solution across Google Cloud, covering source, build, artifacts, deployment, and runtime
- Use attestations in CI/CD pipelines to cryptographically verify that images pass required checks (vulnerability scan, code review, testing) before deployment
- Integrate with Security Command Center to view container vulnerability findings alongside other cloud security risks
GCP Certification Exam Practice Questions
- Questions are collected from Internet and the answers are marked as per my knowledge and understanding (which might differ with yours).
- GCP services are updated everyday and both the answers and questions might be outdated soon, so research accordingly.
- GCP exam questions are not updated to keep up the pace with GCP updates, so even if the underlying feature has changed the question might not be updated
- Open to further feedback, discussion and correction.
- When creating a secure container image, which two items should you incorporate into the build if possible?
- Use public container images as a base image for the app.
- Build the smallest image possible
- Use many container image layers to hide sensitive information.
- Package multiple applications in a container
- Your organization wants to ensure only signed and verified container images are deployed to your GKE clusters. Which Google Cloud service should you use?
- Artifact Analysis
- Cloud Armor
- Binary Authorization
- Container-Optimized OS
- Which Google Cloud service should you use to store and manage your container images now that Container Registry has been shut down?
- Cloud Storage
- Artifact Registry
- Container Registry (deprecated)
- Cloud Build
- You want to containerize your application without writing a Dockerfile. Which Google Cloud feature allows source-to-image transformation?
- Cloud Build triggers
- Cloud Native Buildpacks
- Container-Optimized OS
- Artifact Analysis
- Which type of base image is recommended by Google for production containers to minimize the attack surface?
- Ubuntu full image
- Alpine with development tools
- Distroless images
- CentOS base image
- Your team needs to automatically scan container images for OS and language package vulnerabilities every time an image is pushed to the registry. Which Google Cloud feature provides this?
- Cloud Build steps
- Binary Authorization attestations
- Artifact Analysis automatic scanning
- GKE Security Posture dashboard