Skip to main content

What is a container?

What is a container?

Containers are a type of operating system virtualization, much like the virtual machines that preceded them. 

A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another.




While these technologies have been around since the 1960s, Docker's encapsulation of the container paradigm represents a modern implementation of resource isolation that utilizes built-in Linux kernel features such as chroot, control groups (cgroups), UnionFS, and namespaces to fully isolated resource control at the process level.

Containers use these technologies to create lightweight images that act as a standalone, fully encapsulated piece of software that carries everything it needs inside the box. This can include application binaries, any system tools or libraries, environment-based configuration, and runtime. 

This special property of isolation is very important, as it allows developers and operators to leverage the all-in-one nature of a container to run without issue, regardless of the environment it's run on. This includes developer laptops and any kind of pre-production or production environment. This decoupling of application packaging mechanism from the environment on which it runs is a powerful concept that provides a clear separation of concerns between engineering teams. 

At the core of container technology are three key concepts: 

1. cgroups 
2. Namespaces 
3. Union filesystems

1. cgroups 
cgroups work by allowing the host to share and also limit the resources each process or container can consume. This is important for both resource utilization and security, as it prevents denial-of-service (DoS) attacks on the host's hardware resources. 

Several containers can share CPU and memory while staying within the predefined constraints. cgroups allow containers to provision access to memory, disk I/O, network, and CPU. cgroups also power the soft and hard limits of container constraints. 

There are seven major cgroups: 

Memory cgroup: This keeps track of page access by the group, and can define limits for physical, kernel, and total memory. 
Blkio cgroup: This tracks the I/O usage per group, across the read and writes activity per block device. 
CPU cgroup: This keeps track of user and system CPU time and usage per CPU. This allows you to set weights, but not limits. 
Freezer cgroup: This is useful in batch management systems that are often stopping and starting tasks in order to schedule resources efficiently. The SIGSTOP signal is used to suspend a process, and the process is generally unaware that it is being suspended. 
CPUset cgroup: This allows you to pin a group to a specific CPU within a multicore CPU architecture. You can pin by application, which will prevent it from moving between CPUs. This can improve the performance of your code by increasing the amount of local memory access or minimizing thread switching. 
Net_cls/net_prio cgroup: This keeps tabs on the egress traffic class (net_cls) or priority (net_prio) that is generated by the processes within the cgroup. 
Devices cgroup: This controls what read/write permissions the group has on device nodes.

2. Namespaces 

Namespaces offer another form of isolation for process interaction within operating systems, creating the workspace we call a container. Linux namespaces are created via a syscall named unshare, while clone and setns allow you to manipulate namespaces in other manners.

Namespaces limit the visibility a process has on other processes, networking, filesystems, and user ID components. Container processes are limited to seeing only what is in the same namespace. Processes from containers or the host processes are not directly accessible from within this container process. Additionally, Docker gives each container its own networking stack that protects the sockets and interfaces in a similar fashion.

If cgroups limit how much of a thing you can use, namespaces limit what things you can see. 

In the case of the Docker engine, the following namespaces are used:

- pid: Provides process isolation via an independent set of process IDs from other namespaces. These are nested. 
- net: Manages network interfaces by virtualizing the network stack through providing a loopback interface, and can create physical and virtual network interfaces that exist in a single namespace at a time. 
- ipc: Manages access to interprocess communication. 
- mnt: Controls filesystem mount points. These were the first kind of namespaces created in the Linux kernel, and can be private or shared. 
- uts: The Unix time-sharing system isolates version IDs and kernel by allowing a single system to provide different host and domain naming schemes to different processes. The processes gethostname and sethostname use this namespace. 
- user: This namespace allows you to map UID/GID from container to host, and prevents the need for extra configuration in the container.

3.Union filesystems 

Union filesystems are also a key advantage of using Docker containers. Containers run from an image. Much like an image in the VM or cloud world, it represents state at a particular point in time. Container images snapshot the filesystem but tend to be much smaller than a VM. The container shares the host kernel and generally runs a much smaller set of processes, so the filesystem and bootstrap period tend to be much smaller—though those constraints are not strictly enforced. Second, the union filesystem allows for the efficient storage, download, and execution of these images. Containers use the idea of copyon-write storage, which is able to create a brand new container immediately, without having to wait on copying out a whole new filesystem. This is similar to thin provisioning in other systems.

Benefits of Containers
Containers are a streamlined way to build, test, deploy, and redeploy applications on multiple environments from a developer’s local laptop to an on-premises data center and even the cloud. Benefits of containers include:
  • Less overhead. Containers require less system resources than traditional or hardware virtual machine environments because they don’t include operating system images.
  • Increased portability. Applications running in containers can be deployed easily to multiple different operating systems and hardware platforms.
  • More consistent operation. DevOps teams know applications in containers will run the same, regardless of where they are deployed.
  • Greater efficiency. Containers allow applications to be more rapidly deployed, patched, or scaled.
  • Better application development. Containers support agile and DevOps efforts to accelerate development, test, and production cycles.


Comments

Popular posts from this blog

A brief overview of containers

A brief overview of containers:  Believe it or not, containers and their precursors have been around for over 15 years in the Linux and Unix operating systems. If you look deeper into the fundamentals of how containers operate, you can see their roots in the chroot technology that was invented all the way back in 1970. Since the early 2000s, FreeBSD, Linux, Solaris, Open VZ, Warden, and finally, Docker all made significant attempts at encapsulating containerization technology for the end-user. While the VServer's project and first commit (running several general-purpose Linux server on a single box with a high degree of independence and security ( https://ieeexplore.ieee.org/document/1430092?reload=true )  may have been one of the most interesting historical junctures in container history, it's clear that Docker set the container ecosystem on fire back in late 2013 when they went full in on the container ecosystem and decided to rebrand from dotCloud to Docker.