Containers, Images, and Their Boundaries

Consider a hypothetical team moving a batch job into a container and then accepting customer-uploaded scripts because the job is now “isolated.” An audit would still need to ask which resources are separated, which privileges the script retains, and which kernel it can reach. Packaging the job does not answer those questions.

A container can separate selected resources and enforce configured limits. For ordinary Linux containers sharing a host kernel, that kernel remains part of the common attack surface and failure domain. The choices made in the image, runtime configuration, and host policy together determine the resulting exposure.

The Linux mechanisms below explain resource separation and limits. OCI specifications then explain how an image is packaged and prepared for execution; a common format does not establish a common security policy.

Isolation is per-dimension, and opt-in

A Linux namespace gives a group of processes its own view of a particular system resource. Processes sharing that namespace share its resource view. The Linux namespaces manual describes several independent types, each separating a different part of the execution environment.

A runtime selects which resources to separate and which namespaces to share. The documented types include the following.

NamespaceWhat it isolates
PID“Process IDs”
Network“Network devices, stacks, ports, etc.”
Mount“Mount points”
User“User and group IDs”
IPC“System V IPC, POSIX message queues”
UTS“Hostname and NIS domain name”
Time“Boot and monotonic clocks”
Cgroup“Cgroup root directory”

Runtimes create namespaces or join existing ones, using mechanisms such as clone, unshare, and setns as appropriate to the namespace type. They are not all process-creation flags: a time namespace is prepared with unshare(CLONE_NEWTIME), and subsequent children enter it. Without a separate user namespace, container and host processes use the same user-ID mapping. UID 0 is then host UID 0, but capabilities and other controls can still restrict its authority.

Control groups organize processes into a hierarchy for resource accounting and control. Controllers can enforce limits such as a memory ceiling or CPU quota. Creating a cgroup does not itself establish every limit; the active controllers and their settings determine the constraints.

Namespaces separate selected resource views; cgroups account for and constrain resource use. Docker containers have no resource constraints by default. A separate namespace does not prevent memory exhaustion, nor does it make a process universally invisible: PID visibility follows a hierarchy, and containers may deliberately share namespaces. Signal delivery also requires the relevant permission checks.

Linux namespaces and Kubernetes namespaces operate at different levels. A Kubernetes namespace groups API objects for organization and policy; it does not by itself create a Linux process-isolation boundary. Name the layer when discussing either.

What is not isolated, and what that means for virtual machines

Ordinary Linux containers on a host share its kernel. Virtual machines instead run guest kernels behind a virtualization boundary. Containers often avoid the startup and memory costs of a separate guest OS, but performance depends on the runtime and workload; some container runtimes also use virtual machines.

A shared-kernel vulnerability may expose multiple containers, depending on the vulnerable code path, kernel configuration, and permissions available to the attacker. A panic in that shared kernel stops its workloads. Some kernel settings are namespaced and others affect the host. Isolation depends on capabilities, syscall filtering such as seccomp, and security modules as well as namespace and cgroup configuration.

For workload isolation, assess the code that will execute and what it can reach. Customer-supplied code raises different risks from controlled internal jobs, though internal software can also be compromised. A stronger sandbox, such as a dedicated VM or a runtime that interposes on system calls, can reduce exposure to the host kernel. Select and configure that boundary against the threat model and the required tenant isolation; neither a container label nor a VM label establishes safety on its own.

Worth knowing that the specifications do not treat these as opposites. The runtime specification’s list of defined platforms includes linux and windows and also vm, so “a container” and “a virtual machine” name a packaging-and-lifecycle contract and an isolation technology respectively, and some runtimes satisfy the first using the second. The useful question is never “container or VM” but “what is the isolation boundary, and is it strong enough for what is on the other side.”

An image is a stack of changes, not a snapshot

A container image packages filesystem content with execution defaults. The OCI image format separates that package into a manifest, layers, configuration, and an optional index so that compatible tools can build, transfer, and prepare it for execution.

Four parts, each with a distinct job.

  • The manifest identifies the image configuration and layer blobs by content digests.
  • The layers record filesystem changes that are applied in order.
  • The configuration provides execution defaults, including the command, environment, and user.
  • The optional index points to manifests, commonly for different operating systems or CPU architectures. A compatible client selects the appropriate platform entry.

The OCI layer format records additions, modifications, and removals. New and modified files carry their content in the layer archive. A whiteout entry records that a path from an earlier layer should disappear from the assembled filesystem.

A removal is therefore a note saying “this path is gone,” recorded in a later layer. The bytes in the earlier layer are still there, still distributed, still readable by anyone who can pull the image and inspect its layers.

If a credential is copied into a distributed layer and deleted in a later layer, the earlier bytes remain available to someone inspecting the image. This concerns content retained in the final image’s layers or configuration, not every file used during a build. Build secret mounts can provide temporary access without recording the secret in a layer, provided commands do not copy it into outputs or logs. A stage omitted from the final image may still leave sensitive data in build caches. Apply secrets management to those paths too. If a credential was exposed, revoke or rotate it and address retained copies; other confidential material needs a response appropriate to the disclosure.

Names, digests, and the registry

An image can be located through a registry, checked against content digests, and prepared as a runtime bundle. Signature verification can establish an accepted publisher or provenance claim under a separate trust policy; a digest alone verifies content identity.

A tag is a name that can point to different content over time. A digest identifies the bytes of a manifest or index under the hash algorithm: reproducing identical bytes reproduces the digest, while content changes should fail verification against the old digest. Pin the selected build artifact by digest and record which platform manifest was executed when the reference identifies a multi-platform index. Tags remain useful human-readable labels.

Place stable dependency instructions before frequently changing application code in a sequential build. A cache miss generally invalidates subsequent instruction results, but rebuilding a step does not necessarily require retransmitting every resulting blob. Transfer depends on content digests and what the destination already holds. A registry or node can reuse a shared base; a different node may still need its own first download. Cache invalidation and network transfer are separate costs.

Because the digest verifies content and signatures can be attached, an image is a reasonable unit for supply-chain controls — verifying what you are about to run rather than trusting a name. That is the subject of software supply chain security, and where you need two builds of the same source to produce the same bytes, see reproducible build.

What the image decides, and what run time decides

The image supplies defaults, including the command, environment, and user. Runtime configuration can override defaults and adds mounts, resource controls, and isolation choices. Promote the tested image when it is compatible with the target platform, and record the surrounding configuration so that changes between environments remain reviewable.

Baked into the image:

  • The filesystem: binaries, libraries, assets
  • The default command and arguments
  • Declared environment and user defaults
  • The platform it is built for

Supplied at run time:

  • Configuration values — endpoints, feature settings
  • Secrets, never in the image
  • Storage connections and mounts, with explicit retention and lifecycle rules
  • Namespace choices, configured resource limits, and other runtime security controls

An image does not instantiate an isolation boundary. It does contain security-relevant inputs, including its default user, installed binaries, and file permissions. Audit both the image and the effective runtime and host configuration. For example, an image with User set to 1000 supplies that default when no user override is given; launching it with a user override of 0 changes the process identity. The host mapping and remaining privilege controls still determine its authority.

For runtime secrets, passing a secret as an environment variable keeps it out of the image, which is the important win, and it is not the end of the matter — process environments appear in diagnostics and in anything that dumps state. Keeping the image clean is necessary and not sufficient.

Four things containers do not solve

  • Dependency correctness. Packaging a broken dependency set reproducibly gives you a reliably broken system. The image makes the set fixed, not right.
  • Patching. Running software can modify a writable container filesystem, but in-place patches can be lost when the container is replaced. An immutable deployment policy rebuilds, validates, and replaces images instead, as in golden image practice. Rebuilding alone is insufficient: update the relevant base and dependency inputs, handle caches deliberately, and verify the resulting versions.
  • Privilege. Without a separate user namespace, UID 0 shares the host’s user-ID mapping, but its capabilities and access can still be restricted. Apply least privilege to the image defaults, runtime overrides, capabilities, mounts, and host policy together.
  • State. Docker preserves a container’s writable layer across a stop/start of that same container and removes it when the container is destroyed. A replacement container does not inherit those writes. Keep state that must outlive replacement in storage with an appropriate lifecycle, such as a retained volume or an external database. A mount is not sufficient evidence of durability: tmpfs data disappears when the container stops.

Containers provide a content-addressed package and standardized lifecycle interfaces within the supported formats, platforms, and runtime features. Their security depends on image contents and effective execution controls. Keeping them current requires updated inputs and verification as well as a replacement process.

Start an assessment by identifying the selected namespaces, configured resource limits, effective user and privileges, and workloads across the boundary. Then inspect image contents, mounts, network access, and host protections. The image provides part of that evidence; the running configuration supplies the rest.

References


Discover more from Insightful Data Lab

Subscribe to get the latest posts sent to your email.

Similar Posts

Questions, corrections, or additional insights?

This site uses Akismet to reduce spam. Learn how your comment data is processed.