Containers
ChatGPT generated lecture notes with a few rounds of edits. The bad analogies are not mine.
1. What are Containers?
Containers are lightweight, standalone units that package an application along with its dependencies. They ensure that software runs consistently across different computing environments, from development to production.
- Analogy: Containers are like standardized shipping containers used in logistics. They enable software to move reliably from one environment to another, regardless of differences in the underlying systems.
- Goal: The primary goal of containers is portability and reproducibility.
2. Containers vs Virtual Machines (VMs)
Feature | Containers | Virtual Machines (VMs) |
---|---|---|
Abstraction Level | OS-level (process isolation) | Hardware-level (full OS) |
Overhead | Low | High |
Boot Time | Sub-second | Seconds to minutes |
Size | Small (MBs) | Large (GBs) |
Isolation | Process-based | Full OS kernel isolation |
- Containers share the host OS kernel, whereas VMs run separate OS instances, each with its own kernel.
3. Container Technologies
- Docker: A widely adopted platform for managing container lifecycles. (Note: Arjun thinks Docker is terrible due to its reliance on a daemon, complexity, and security concerns.)
- Podman: A daemon-less container engine, allowing rootless container execution.
4. How Containers Work
Container Architecture
- Image: A static, read-only snapshot that serves as the blueprint for a container. It contains the application code, runtime, libraries, and any required dependencies.
- Container: A running instance of an image. Containers operate in isolation but share the host’s OS kernel.
5. Union Filesystems
Union Filesystems are commonly used technologies like OverlayFS that allow multiple layers of filesystems to coexist efficiently. They enable containers to reuse layers to minimize storage use. While union filesystems are not fundamental to containerization, they are widely used to optimize image storage and build processes by allowing different image layers to be shared and reused.
6. Container Isolation Mechanisms
1. Namespaces
Namespaces are a feature in the Linux kernel that provide isolation for system resources. They allow containers to have a distinct view of the system. Each container believes it has exclusive access to its own resources.
- PID Namespace: Isolates process IDs so that processes inside a container cannot see or interact with processes outside. Each container thinks it has its own unique set of PIDs starting from 1.
- Network Namespace: Provides isolated network interfaces. Containers have their own virtual network stacks, including IP addresses, routing tables, and ports. This ensures network traffic between containers can be controlled.
- Mount Namespace: Isolates the file system, ensuring that each container sees only its designated directory structure. This prevents access to the host’s file system.
- User Namespace: Allows containers to have their own view of user and group IDs. A process inside a container can be mapped to a non-privileged user in the host, even if it runs as “root” inside the container.
- UTS (Unix Timesharing System) Namespace: Allows a container to have its own hostname and domain name, providing identity separation from the host.
- IPC Namespace: Isolates inter-process communication mechanisms like shared memory, ensuring that the IPC resources of a container are inaccessible from outside.
2. Control Groups (cgroups)
Control Groups (cgroups) are used to manage and limit resource usage for containers, ensuring fairness and stability of the host system.
- Resource Limitation: Cgroups can limit CPU, memory, and I/O bandwidth used by a container. This prevents a container from exhausting system resources and affecting the host or other containers.
- Prioritization and Quotas: Cgroups can assign priority levels or quotas for resources. For example, container A could have access to twice as much CPU as container B.
- Accounting: Cgroups can monitor resource usage, helping with performance tuning or billing based on actual usage.
3. Capabilities and Rootless Containers
- Linux Capabilities: Containers can drop unnecessary capabilities that traditional root processes have, significantly reducing attack surfaces. For example, a container might drop the capability to load kernel modules.
- Rootless Containers: Running containers without root privileges adds an additional security layer, reducing the risk of privilege escalation attacks on the host.
7. Running Different Operating Systems in Containers
While containers share the host OS kernel, they can still run different user environments by using different distributions. For example, running CentOS in an Ubuntu-based container host is possible by using an image that contains CentOS user-space utilities and libraries.
- User-space Emulation: Containers isolate the user-space, meaning the file system, libraries, and user-level processes can be entirely different from the host. As long as the underlying kernel supports the system calls used by the container, you can run a different distribution. For instance, you could run a CentOS container on an Ubuntu host, provided the container’s binaries are compatible with the host kernel.
- Base Image: The base image you choose dictates the environment inside the container. For example, a CentOS base image will include CentOS libraries, package managers (like
yum
), and configurations, even if the host is running Ubuntu. - Limitations: Since containers share the kernel, you cannot run containers with kernels that differ from the host. For example, you can’t run a Windows kernel inside a Linux container.
- Use Cases: Running different distributions is useful for testing software compatibility, replicating different production environments, or maintaining consistency across diverse deployment targets.
8. Advantages of Container Isolation
- Enhanced Security: Containers running on the same host are isolated through namespaces, cgroups, and security modules, reducing the risk of one compromised container affecting others.
- Fault Isolation: If a container crashes or becomes compromised, the failure is contained within that container, preventing it from impacting others or the host system.
- Resource Control: Using cgroups, administrators can ensure that no single container starves others of CPU or memory, maintaining system stability.
9. Challenges of Container Isolation
- Kernel Sharing: Containers share the host OS kernel, which means a vulnerability in the kernel could potentially affect all containers.
- Configuration Complexity: Properly configuring isolation mechanisms like cgroups, namespaces, and security policies requires careful planning and expertise.
- Breakout Risks: Misconfigurations or vulnerabilities could lead to “container escapes,” where a process inside the container gains unauthorized access to the host system.
10. Example Using Podman
Podman is a container engine similar to Docker but without the need for a central daemon, making it more secure and suitable for rootless environments.
- Example: Running a container using Podman
podman run --name myapp -d registry.centos.org/centos:latest
- This command pulls a CentOS image from the registry and runs it as a container named
myapp
in detached mode. - Unlike Docker, Podman does not require root privileges and allows better security practices by default.
- This command pulls a CentOS image from the registry and runs it as a container named
- Example: Building an Image with Podman
- Create a
Dockerfile
:FROM ubuntu:latest RUN apt-get update && apt-get install -y nginx COPY index.html /var/www/html/ CMD ["nginx", "-g", "daemon off;"]
- Build the image using Podman:
podman build -t mynginximage .
- This command builds an image named
mynginximage
using the instructions from theDockerfile
in the current directory. - Podman uses the same syntax for Dockerfiles as Docker, making it easy to switch between the two tools.
- This command builds an image named
- Create a
11. Conclusion
Container isolation is a powerful mechanism that allows applications to run securely and efficiently, without interference. By combining namespaces, cgroups, and additional security measures, containers can achieve a level of separation that is sufficient for most use cases, although careful configuration and ongoing security practices are essential to mitigate potential risks.