-: In the last section,
we continue to talk a little bit about images
but we're still surprising light
on some of the details around exactly what a container is.
So, in this section,
I'm gonna give you a behind the scenes look
at what a container is,
and how it is created on your machine.
Now, to understand the container,
you first need to have a little bit of background
on exactly how your operating system runs on your computer.
So, I'm gonna first give you a quick overview
of your operating system.
Okay, so this is a quick overview
of the operating system on your computer.
Most operating systems have something called a kernel.
This kernel is a running software process
that governs access between all the programs
that are running on your computer
and all the physical hardware
that is connected to your computer as well.
So, up here at the top of this diagram,
We have different programs that your computer is running
such as Chrome, or Terminal, Spotify, or Node.js.
If you've ever made use of Node.js before
and you've written a file to the hard drive,
it's technically not Node.jS
that is speaking directly to the physical device.
Instead, Node.js says to your kernel,
"Hey, I want to write a file to the hard drive."
The kernel then takes that information
and eventually persist it to the hard disc.
So, the kernel is always kind of this intermediate layer
that governs access between these programs
and your actual hard drive.
The other important thing to understand here
is that these running programs interact with the kernel
through things called system calls.
These are essentially like function invocations.
The kernel exposes different endpoints to say,
"Hey, if you want to write a file to the hard drive,
call this endpoint or this function right here."
It takes some amount of information
and then that information will be eventually written
to the hard disc, or memory, or whatever else is required.
Now, thinking about this entire system right here,
I wanna post a kind of hypothetical situation to you.
I want you to imagine for just a second
that you and I have two programs running on our computer.
Maybe one of them is Chrome, like Chrome the web browser
and the other is Node.js,
the JavaScript Service-side run time.
I want you to imagine that we're in a crazy world
where Chrome, in order to work properly,
has to have Python version 2 installed
and Node.js has to have version 3 installed.
However, on our hard disc,
we only have access to Python version 2.
And for whatever crazy reason,
we are not allowed to have two identical installations
of Python at the same time.
So, as it stands right now, Chrome would work properly
because it has access to version 2,
but Node.js would not
because we do not have a version or a copy
of Python version 3.
Again, this is a completely make belief situation.
I just want you to kind of consider this for a second
'cause this is kind of leading into what a container is.
So, how could we solve this issue?
Well, one way to do it would be used
to make use of a operating system feature
known as namespacing.
With namespacing,
we can look at all of the different hardware resources
connected to our computer
and we can essentially segment out portions
of those resources.
So, we could create a segment of our hard disc
specifically dedicated to housing Python version 2.
And we could make a second segment
specifically dedicated to a housing Python version 3.
Then, to make sure that Chrome has access
to this segment over here
and Node.js has access to this segment over here,
anytime that either of them issues a system call
to read information off the hard drive,
the kernel will look at that incoming system call
and try to figure out which process it is coming from.
So, the kernel could say,
"Okay, if Chrome is trying to read some information
off the hard drive, I'm gonna direct that call
over to this little segment of the hard disc over here,
the segment that has Python version 2 and Node.js."
Anytime that makes a system call to read the hard drive,
the kernel can redirect that over to this segment
for Python version 3.
And so by making use of this kind of namespacing
or segmenting feature,
we can have the ability to make sure that Chrome
and Node.js are able to work on the same machine.
Now again, in reality,
neither of these actually needed installation of Python.
This is just a quick example.
So, this entire process of kind of segmenting a hard,
excuse me, a hardware resource based on the process
that is asking for it is known as namespacing.
With name spacing, we are allowed to isolate resources
per a process or a group of processes,
and we're essentially saying that anytime
this particular process asks for a resource,
we're gonna direct it to this one little specific area
of the given piece of hardware.
Now, namespacing is not only used for hardware,
it can be also used for software elements as well.
So for example, we can namespace a process
to restrict the area of a hard drive that'd be available,
or the network devices that are available,
or the ability to talk to in other processes,
or the ability to see other processes.
These are all things that we can use namespacing
for to essentially limit the resources
or kind of redirect request for resource
from a particular process.
Very closely related to this idea of namespacing
is another feature called control groups.
A control group can be used to limit the amount
of resources that a particular process can use.
So, namespacing is for saying,
"Hey, this area of the hard drive is for this process."
A control group can be used to limit the amount of memory
that a process can use, the amount of CPU,
the amount of hard drive input, input.
Or excuse me, input output,
and the amount of network bandwidth as well.
So, these two features put together can be used
to really kind of isolate a single process
and limit the amount of resources it can talk to,
and the amount of bandwidth essentially,
that it can make use of.
Now, as you might imagine,
this entire kind of little section right here,
this entire vertical of a running process,
plus this little segment of a resource that it can talk to
is what we refer to as a container.
And so, when people say,
"Oh yeah, I have a Docker Container."
You really should not think of these
as being like a physical construct
that exists inside of your computer.
Instead, a container is really a process
or a set of processes that have a grouping of resources
specifically assigned to it.
And so, this is the diagram
that we're gonna be looking at quite a bit
anytime that we think about a container.
We've got some running process
that sends a system call to a kernel.
The kernel is going to look at that incoming system call
and direct it to a very specific portion of the hard drive,
the RAM, CPU or whatever else it might need.
And a portion of each of these resources
is made available to that singular process.
Now, the last question you might have here is,
"Okay. Well, I get what a container is,
but with that in mind,
what is the real relation between one of those containers
or that kind of singular process
and grouping of resources to an image?
How is that single file eventually create this container?"
That's a good question.
One more quick diagram.
Anytime that we talk about an image,
we're really talking about a file system snapshot.
So, this is essentially kind of like a copy paste
of a very specific set of directories or files.
And so we might have an image
that contains just Chrome and Python.
An image will also contain a specific startup command.
So, here's what happens behind the scenes
when we take an image and turn it into a container.
First off,
the kernel is going to isolate a little section
of the hard drive
and make it available to just this container.
And so we can kind of imagine
that after that little subset is created,
the file snapshot inside the image is taken
and placed into that little segment of the hard drive.
And so, now,
inside of this very specific grouping of resources,
we've got a little section of the hard drive
that has just Chrome and Python installed
and essentially, nothing else.
The startup command is then executed
which we can kind of imagine
this case is like startup Chrome,
just Chrome for me.
And so Chrome is invoked,
we created a new instance of that process
and that created process is then isolated
to this set of resources inside the container.
So, that's pretty much it.
That is the relationship between a container and an image,
and it's how an image is eventually taken
and turned into a running container.
Now, there's still a tremendous amount more to learn
about containers and images.
So, let's take a quick break
and continue in the next section.