Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Wait, Containers Are Kind of Like Linux Processes!

DZone's Guide to

Wait, Containers Are Kind of Like Linux Processes!

These short exercises will show you the conceptual similarities between containers and Linux processes, to help you understand containers.

· DevOps Zone ·
Free Resource

Read why times series is the fastest growing database category.

Of course, containers are not the same as processes you find in operating systems, but at a conceptual level, there are many similarities. In this article, I aim to explore this notion at the expense of getting my hands a little dirty. Let’s dive in.

A process is an atomic component of a program (or a complete program) in execution. In Linux, each process has its own unique id (Process ID) and is capable of creating child processes (forking). This, in turn, makes a process's PID into a PPID (parent PID). The PIDs allow the operating system to get ahold of the process and run it through its various process states as need be.

The concept of containers derives from the wonderful world of Docker, where a bunch of super smart geeks figured out ways of extending and building up on process isolation, packaging mechanisms/concepts present in Linux; they should also be credited for building an awesome product range out of their advancements and making them available to the masses. A container is a dockerized image(s) in execution (technically, the images stay immutable and it is a completely new layer called the container layer that provides access to the immutable content, but for simplicity sake, let's say a container is an image in execution).

Note: To try out the examples in this article, you will need to have Docker configured in a Linux distribution (I’m using Ubuntu Trusty with Docker 17.06.0-ce), have internet access, and be logged in with a user that has permissions to use Docker and the other commands listed (you may also require root access for some of the commands listed).

Exercise 1

In one terminal, type in the command found below. The command will start printing its message on the terminal you typed it in, every two seconds, indefinitely!

Command Block 1

echo -e "#\!/bin/bash\nwhile true; do echo hi there.. I’m a process; sleep 2; done" > processtestscript.sh; chmod u+x processtestscript.sh; bash processtestscript.sh

Output Block 1

hi there.. I’m a process
hi there.. I’m a process
hi there.. I’m a process

In the second terminal, type in the command found below, assuming you have not used the tomcat:8.0 on your box before, Docker will pull the required image (a layer at a time) from Docker Hub and perform the predefined run sequence for the container. Bam! You got a container running.

Command Block 2

docker container run tomcat:8.0

Output Block 2

Unable to find image 'tomcat:8.0' locally
8.0: Pulling from library/tomcat
ad74af05f5a2: Pull complete
2b032b8bbe8b: Pull complete
99a5213ead46: Pull complete
7de34ca31efd: Pull complete
9b22e57d98bb: Pull complete
12cd7a66c3fd: Pull complete
880bb942de44: Pull complete
6ada99602995: Pull complete
90451a97de52: Pull complete
646677f3b1ed: Pull complete
c10d6538fe29: Pull complete
63e2edd468f7: Pull complete
Digest: sha256:1f34d503e3e339433a84df80615fb658ab16491361353b6d7e1342b2b80cf7f0
Status: Downloaded newer image for tomcat:8.0
16-Aug-2017 12:27:17.573 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/8.0.45
16-Aug-2017 12:27:17.577 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Jun 26 2017 20:06:07 UTC
…
…
16-Aug-2017 12:27:20.596 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-apr-8080"]
16-Aug-2017 12:27:20.635 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-apr-8009"]
16-Aug-2017 12:27:20.667 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 2787 ms

Let’s turn to the third terminal to peer into the mannerisms of these two creators. Run the following two commands to get a few top level details about the process and the container.

Command Block 3

ps -ef | head -n 1 ; ps -ef | grep processtestscript.sh | head -n 1

docker container ls -l

Output Block 3

UID             PID    PPID  C  STIME   TTY          TIME      CMD
dumiduh   3163   3087  0   16:56     pts/7    00:00:00 bash processtestscript.sh

CONTAINER ID    IMAGE         COMMAND           CREATED             STATUS              PORTS         NAMES
d1ad06cfbc91    tomcat:8.0   "catalina.sh run"   24 seconds ago   Up 21 seconds   8080/tcp       happy_banach

In the output of the two commands, pay attention to the PID of the processtestscript.sh and the Container ID of the tomcat:80 container. These two identifiers serve the same purpose, which is to uniquely identify these in execution entities.

Of Process States and Container States

A Linux process is birthed when a parent process forks a child process into being. This new process may then be transitioned into various different states as need be. From these, the most common states are running, sleeping, and stopped.

A parent process typically goes into a sleep state when it forks a child process; these processes wait for signals to move along their execution paths. Keeping with the topic of discussion of this article, we will concentrate on the two states and the transition between these two states that are similar in concept to that what’s found in the world of containers.

Image title

As mentioned earlier on, a container is a collection of immutable layers with a mutable layer put on top to provide access to the contents of these immutable layers. There are various strategies for providing access to the contents of the immutable layer, which we will not get into in this article. A crude state representation of this state transfer would look much like that of a process going from stopped to running,

Image title

Exercise 2

Let’s switch back to the first terminal running the processes and change the process state to stopped and then back to running.

Go back to the output you received in Command Block 3 and find the PID for the processtestscript.sh process. Switch to the third terminal and run the next command block with the PID you just extracted. To me it's,

Command Block 4

Kill -19 3163

Observe that as soon as you sent the STOP signal(19) to the process, the script stopped printing the message.

Output Block 4

hi there.. I’m a process
hi there.. I’m a process
hi there.. I’m a process

[1]+  Stopped                 bash processtestscript.sh

Now, send a CONT signal(18) to the process to resume it.

Command Block 5

Kill -18 3163

You will notice that the process resumes and starts printing its message again. Back from the dead, picking up from where it left off.

Now let’s do something similar with our container and observe how it behaves. To make sure, it has preserved its state when it transitions from Stopped to Running, let’s go into the container and add a new file. Take the Container ID from Output Block 3 and run Command Block 6 to go into the container. Once inside the container run the echo command to create a new file.

Command Block 6

docker container exec -it d1ad06cfbc91 bash

echo “life inside a container” > file1 

Now switch to back to the third terminal and run command block 7 to stop the container, observe that the container has stopped.

Command Block 7

docker container stop d1ad06cfbc91

docker container ls -la

Output Block 7

CONTAINER ID    IMAGE         COMMAND            CREATED      STATUS            PORTS            NAMES
d1ad06cfbc91        tomcat:8.0    "catalina.sh run"   7 hours ago  Exited (143) 16 seconds ago  fervent_stone

Finally, let’s start the stopped container, go into it and check if the file we created is still there.

Command Block 8

docker container start d1ad06cfbc91

docker container exec -it d1ad06cfbc91 bash

Output Block 8

root@d1ad06cfbc91:/usr/local/tomcat# ls
LICENSE  NOTICE  RELEASE-NOTES    RUNNING.txt  bin  conf    file1  include    lib  logs  native-jni-lib  temp  webapps  work
root@d1ad06cfbc91:/usr/local/tomcat# cat file1
life inside a container

In this article, we looked at two ways in which Linux processes and Docker containers are similar. These being, first, containers and processes are both atomic computational resource representations. Second, containers and processes both can be stopped and then resumed to carry on from where they left off.

In a future article, I will expand this analogy further.

Learn how to get 20x more performance than Elastic by moving to a Time Series database.

Topics:
linux ,containers ,devops ,docker

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}