DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Containers: Who Is Containing Them?

Containers: Who Is Containing Them?

Thanks to containers, almost anything is shippable.

Marco Sigismondi user avatar by
Marco Sigismondi
·
Nov. 21, 18 · Tutorial
Like (2)
Save
Tweet
Share
8.50K Views

Join the DZone community and get the full member experience.

Join For Free

Introduction

A typical way to structure an article is to start from the ground and show piece by piece how to build something very amazing.

This was also my intention, so I started developing a Spring Boot application that read data from a MySQL DB. I configured Docker to execute database and web application in different containers, making the database accessible only through the application and, in this way, demonstrating the powerful encapsulating possibilities of Docker. While I was describing all steps needed I asked to myself: what is really happening? How containers are running and, more important, where are they running?

If you are interested in an example of a Spring Boot application connected to MySQL DB running on different containers, you can see the code I prepared at the following Git repositories and run it: docker-cluster. But if you are more interested in the answers I gave to me regarding magic happen under, the ground read the following sections.

Am I Running Virtual Machines?

This is the first question I asked myself.

When I went deeper into the documentation regarding containers, I came across the difference between a virtual machine and a container. To compare the two technologies in the right way I needed to understand virtualization.

Virtualization is an old technology. It was first developed by IBM in the ’60s to handle multiple user access to machine running batches and discovered again in the ’90s to when companies start using a single host to execute multiple programs. In those days every program was installed on a different operating system instance that ran on its own host machine. This was for security issues and because programs were compiled for a specific operating system. Virtualization allowed companies to have multiple programs running on its own operating system hosted by a shared physical machine. This approach also speeds up software installation since after a virtual machine was created it was possible to save the image and run this image on a different host.

The heart of the technology is hypervisor: a program whose scope is to virtualize and limit physical resources and to make it available to virtual instances. There are two kinds of hypervisor:

  • Type-1 Hypervisors: they are installed directly on the host firmware giving high performances;
  • Type-2 Hypervisors: they are installed on the operating system. They have lower performance but enable the user to install them on every server they already have.

This technology was fine until the need arose to have good runtime performance on virtualized operating systems, but in last years a new need has come out: high availability.

High availability is the characteristic of a system that constantly serves. To accomplish that it must guarantee redundancy (elimination of single points of failure) and be able to respond if some node fails (detection of failures and auto-scaling).

Isolation (Containerization)

Despite the fact that containers are widely used there is not yet a common definition for them.

Docker defines containers as “an abstraction at the app layer that packages code and dependencies together” and virtual machines as “an abstraction of physical hardware turning one server into many servers.” This defines what a container is but not how the abstraction is implemented.

If, for virtual machines, the technology is “virtualization,” then “containerization” could be — and in some cases is — the term for the technology that enables us to use containers.

I prefer using the term “isolation.”

Containerization recalls something related to shipping:

containerize: pack into or transport by container

While isolation recalls the implementation behind it:

Identify (something) and examine or deal with it separately.

Containers do not replicate the whole OS but talk directly with the kernel. This means they do not need to replicate the whole OS for running and they do not need a long time to start. They are just a set of isolated running processes that can interact with the kernel.

This set of processes can be collected by giving the experience of acting as a different distro of the host operating system. An example: on an Ubuntu machine you can run a container that acts as CentOS, then another that acts as REHL and another one that acts as Debian.

For its nature, it is not possible to have a container that acts as Windows on a Linux machine since the kernel is not replicated but processes and resources are isolated.

With isolation redundancy of nodes became easy since do not need a lot of spaces for running containers and a lot of time to start up a node with a whole operating system.

An interesting observation on the containers definition is that the host operating system is a container, too.

How Does the Magic Happen?

Magic happen thanks to simple ideas that are been used to create great technologies: in this cases two Linux feature that have paved the way: namespaces  and cgroups.

Namespaces ware introduced to give a convenient way to isolate processes. This can be useful in a lot of situation in which there’s the necessity to avoid some process to kill others for error. As an example, imagine a machine in which more than one application server is running. One in stuck so someone lists all Java processes and kills the failing one but he picks the wrong PID and kills the wrong process. Namespaces can isolate PID, networks, mounts, UTS, user, IPC: basically, everything needed to run a sub-system. The only thing is missing is resources limits: this is the cgroup's job. They limit and isolate the resource usage (CPU, memory, disk I/O, network, etc.) of processes.

Magic in Action

The following commands have been used to test namespaces and cgroups.

For Namespaces, the goal of the example is to create 2 PID namespaces and demonstrate that processes running on one were not visible for other.

In a first console, I executed

sudo unshare --fork --pid --mount-proc bash


This runs bash in a new PID namespace. Inside of it, I ran the following Java class whose scope was to maintain an active Java process for some time.

public class NameSpaceTest {
    public static void main(String[] args) throws Exception{
        System.out.println("Goodnight");
        Thread.sleep(600000);
    }
}


Then I opened a new terminal and ran a bash in a second PID namespace. At this point executing:

ps aux


The first namespace gave the following output:

USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

root          1  0.1  0.1  21616  5196 pts/2    S    13:36   0:00 bash
root         18  2.5  1.1 2708968 30492 pts/2   Sl   13:37   0:00 java NameSpaceTest
root         30  0.0  0.1  30200  3120 pts/2    R+   13:37   0:00 ps aux


while in the second namespace the following was given:

USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

root          1  0.1  0.1  21352  5016 pts/3    S    13:36   0:00 bash
root         10  0.0  0.1  30200  3144 pts/3    R+   13:37   0:00 ps aux


Here there are 2 main things to notice:

  • Both namespaces have a PID n. 1;
  • The second one does not see the Java process.

After that, I ran ps aux   in a third terminal outside the forked namespaces and as you can see, bash namespaces have a PID in the outer world.

… useless processes removed …

root       2817  0.0  0.1  44416  4192 pts/2    S    13:36   0:00 sudo unshare --fork --pid --mount-proc bash
root       2818  0.0  0.0  16644   760 pts/2    S    13:36   0:00 unshare --fork --pid --mount-proc bash
root       2819  0.3  0.1  21352  4812 pts/2    S+   13:36   0:00 bash
root       2827  0.0  0.1  44416  4352 pts/3    S    13:36   0:00 sudo unshare --fork --pid --mount-proc bash
root       2828  0.0  0.0  16644   688 pts/3    S    13:36   0:00 unshare --fork --pid --mount-proc bash
root       2829  0.3  0.1  21352  5016 pts/3    S+   13:36   0:00 bash
admin      2841  0.0  0.1  30200  3136 pts/1    R+   13:36   0:00 ps aux


When the Java process was running it was visible to the outer world, too:

ps aux | grep java

root       2850  0.8  1.1 2708968 30492 pts/2   Sl   13:37   0:00 java NameSpaceTest
admin      2867  0.0  0.0  17480   896 pts/1    S+   13:37   0:00 grep java


For cgroups, the goal of my test was to create a control group with very limited memory and inside of it try to open some program.

I executed

sudo cgcreate -a admin -g memory:javaEnv


to create the cgroup. This command initializes a set of empty settings available at /sys/fs/cgroup/memory/javaEnv/. 

With the following command:

sudo echo 2000000 > /sys/fs/cgroup/memory/javaEnv/memory.kmem.limit_in_bytes


I limited memory dedicated to programs executing in javaEnv. Then I ran bash  in this cgroup 

sudo cgexec -g memory:javaEnv bash


When then I tried to run:

libreoffice –writer


I get:

fork: Cannot allocate memory

as expected.

After I deleted created cgroup by executing

sudo cgdelete memory:javaEnv

Conclusion

Containers and virtual machines are often compared and, in some cases, referred to as alternatives. I think they must be thought of as different technologies that address different aspect of the same principle: abstraction.

Often are used together,: it is common to run Ddocker images on existing servers that also run other standard application installed on virtual machines.

The important thing is to get the best from them by understanding their implementation and this was what I tried to do in this article.

A Curiosity

You may have read that Docker is available for Windows, too, and that you can run Linux on it, so you may say: “You just said that it’ impossible.” The funny answer is that it is possible, and it is thanks to virtual machines. Under the ground, Windows runs an AlpineLinux virtual machine with Docker installed on it through Hyper-V.

Docker (software) operating system Machine Spring Framework Web application Host (Unix) Virtual Machine

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Cloud Performance Engineering
  • Reliability Is Slowing You Down
  • Building a Real-Time App With Spring Boot, Cassandra, Pulsar, React, and Hilla
  • gRPC on the Client Side

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: