02 Understanding Containers and Containerized Applications

Most content in this document is based on "Kubernetes In Action, Second Edition" by Marko Lukša and Kevin Conner.

Executive Summary

Chapter 2 provides a comprehensive, low-level exploration of container technology. Rather than treating containers as magic black boxes, it strips away the abstraction to reveal that containers are simply regular Linux processes running directly on the host operating system. The chapter meticulously details how Linux kernel features—specifically Namespaces, Control Groups (cgroups), and advanced security profiles—are combined to create the illusion of a fully isolated environment. It also covers the practical workflow of the Docker platform, including image layering, building with Dockerfiles, and distributing applications via registries. This foundational OS-level knowledge is critical for effectively debugging, securing, and managing containerized applications in Kubernetes.

Key OS-Level Concepts & Architectural Deep Dive

2.1 The Architectural Paradigm Shift: Containers vs. Virtual Machines

Understanding the difference between VMs and containers requires looking at how applications interact with the underlying hardware and kernel.

Virtual Machines (Hardware Virtualization)

Containers (OS-Level Virtualization)

graph TD
    subgraph VM_Architecture [Virtual Machine]
        App1[App A]
        Lib1[Lib/Bins]
        GOS1[Guest OS Kernel]
        App2[App B]
        Lib2[Lib/Bins]
        GOS2[Guest OS Kernel]
        HYP[Hypervisor]
        HOST[Host Physical Hardware]
        
        App1 --> Lib1
        Lib1 --> GOS1
        App2 --> Lib2
        Lib2 --> GOS2
        GOS1 -->|Virtual Syscalls| HYP
        GOS2 -->|Virtual Syscalls| HYP
        HYP --> HOST
    end

    subgraph Container_Architecture [Linux Container]
        CApp1[App A]
        CLib1[Lib/Bins]
        CApp2[App B]
        CLib2[Lib/Bins]
        CHOST[Single Shared Host OS Kernel]
        PHOST[Host Physical Hardware]
        
        CApp1 --> CLib1
        CApp2 --> CLib2
        CLib1 -->|Direct Syscalls| CHOST
        CLib2 -->|Direct Syscalls| CHOST
        CHOST --> PHOST
    end

2.3 Under the Hood: How Linux Creates the “Container” Illusion

A container is not a tangible “box.” It is an illusion constructed using specific Linux kernel features that restrict what a process can see and what it can use.

1. Customizing the Process Environment with Kernel Namespaces

By default, all processes in a Linux system share the same global resources (filesystems, process IDs, network interfaces). Linux Namespaces allow the kernel to partition these resources into separate, isolated buckets. When you create a container, you assign it to a specific set of namespaces. It can only see the resources in its namespace.

2. Limiting Resources with Control Groups (cgroups)

While Namespaces limit what a process can see, cgroups limit what a process can use.

3. Strengthening Isolation and Security

Because containers share the host kernel, preventing malicious system calls is critical.


2.1.2 The Docker Platform and the Union Filesystem

Docker popularized containers by providing user-friendly tooling to manage these complex kernel features and standardizing how applications are packaged.

The Copy-on-Write (CoW) Image Layering System

Unlike VM images, which are massive monolithic files, container images are composed of multiple thin, read-only layers.

Portability Limitations

While containers solve the “it works on my machine” problem by bundling dependencies, they are not universally portable:

  1. Architecture Dependency: An image compiled for an x86 CPU cannot run on an ARM CPU natively.
  2. Kernel Module Dependency: Because containers use the host kernel, if an application specifically requires a specialized kernel module that is not loaded on the host, the container will fail to run, regardless of what is inside the image.

Conclusion

Chapter 2 fundamentally redefines a container from a “lightweight VM” to its true reality: a highly configured Linux process. By combining Namespaces for environmental isolation, cgroups for resource metering, UnionFS for efficient storage, and advanced security profiles, the Linux kernel and container runtimes (like Docker or containerd) provide a fast, efficient, and reproducible execution environment. This deep OS-level understanding is a prerequisite for diagnosing complex networking, storage, and permission issues when deploying applications at scale with Kubernetes.