The material has been translated. Link to original
The first article in the series “Container Architecture” (transfer, original in English.) we’ve covered the difference between user space and kernel space. Today we will continue exploring this topic and take a closer look at user space.
Virtual machines and containers
A virtual machine is a convenient way to package virtual hardware, kernel space, and user space. A container, on the other hand, only abstracts user space. The container does not have its own kernel or virtual hardware.
There are two main approaches to collaborate on a project: use copies of the source code or pre-configured virtual machines. While both methods are fairly common, each has advantages and disadvantages.
Developers usually use code and binaries instead of a shared virtual machine, as virtual machines are inconvenient due to their size and format. Source code wins in terms of size, but requires additional steps when deployed. Software developed often depends on libraries and frameworks (e.g. Ruby, PHP PECL, Python, Perl, etc.). Some of them are distributed as operating system packages and are often downloaded from external repositories. But there are situations when they have to be compiled. Other developers, administrators, and architects need to look into installing these dependencies.
To simplify life, tools such as RPM, git, RVM, etc. have been developed. But the build and deployment processes can be completely non-trivial and require additional knowledge (outside of application development).
On the other hand, architects and system administrators often use virtual machines. They allow you to easily save the settings made in the form of ready-made images.
A virtual machine usually consists of two files: the first is a copy of the user space and kernel (virtual disk), and the second is the metadata that defines the available resources (processor, memory, video card, etc.). The advantage of this approach is that it is very simple to deploy, and the disadvantage is that over time it is easy to forget what is inside the virtual machine image.
When a vendor distributes an application in the form of virtual machine images, the question often arises about the methodology for creating them, as well as their support, configuration and updating. Each application takes a different approach to authentication, changing passwords, setting up services and the network. Even worse, these settings are almost always done manually.
Thus, it turns out that neither sharing “code only” nor distributing “pre-configured virtual machines” is an ideal solution. Unsurprisingly, tools have emerged that bring these methodologies closer together. Kickstart, Puppet, and Chef are trying to approach server deployments as code management (infrastructure as code). Whereas Vagrant is designed to make it easy to deploy off-the-shelf virtual machines to developer computers.
Still, what should you use for collaboration: code or a complete virtual machine? Perhaps there is another way? Read on!
When starting the container, the user space is the host running the container, makes system calls to the kernel to create special structures (cgroups, svirt, namespaces). Containers can be run as a full-fledged Red Hat Enterprise Linux 7and on an operating system optimized for containers, such as Red Hat Enterprise Linux Atomic Host… In any case, the system calls are the same.
The figure below shows that when creating a container, the system call is used clone ()which creates a new process. Clone is similar to fork, but allows you to set up a namespace for a new process. Thanks to namespaces each process can have its own network name, IP address, mount points, process ID, and other resources. For each container, you can create its own namespace, which makes them look like virtual machines.
Once a container instance is launched, the process or processes run in user space created by mounting the container image. The processes inside the container make system calls as before. The kernel controls what processes can do in a container.
In the figure below, the first command runs the open () system call from the user space in the host, the second runs open () from the container in the mount namespace, and the third command getspid () also from the container using the PID namespace.
When you stop a container, the number of namespaces decreases and then it is removed. When a container is destroyed, all data in it is lost, but you can save it as a new image.
As long as infrastructure parity (processor, memory, network, core compatibility) is maintained, the same container image can be run on the developer’s laptop, on servers in the data center, and on virtual machines in the cloud. The advantage of containers is that they provide developers, architects, QA engineers, release engineers and sysadmins with a convenient collaboration tool that packs and distributes all user space in a simple and convenient way.
Most developers and architects work in user space. Whether you are developing Ruby on Rails applications, Java applications, or PHP PECL modules that require C libraries, containers are a convenient way to package and ship an application with all user-space dependencies.
Another important point is that all container management tools work in user space.
Whether developing / deploying monolithic applications or using a modern microservice architecture, focusing on containers (user space) allows everyone – from developers and sysadmins to architects and release engineers – to gain more flexibility and the ability to work more efficiently.
In the next part of this series (original in English. Architecting Containers Part 3: How the User Space Affects Your Application) we’ll look at how the relationship between user space and kernel space affects your application.
The material has been translated. Link to original
The translation of the material was prepared as part of the course “Administrator Linux. Professional “… If you are interested in learning more about the course, we invite you to Open Day online. CHECK IN