- [Instructor] One of the main things Docker does
is manage your networking for you to create containers.
Let's take a little brief look
at some of the things Docker does for you.
First of all, networking is divided into many layers.
The bottom layer is how machines that are near each other
or containers that are near each other
actually talk directly to each other.
We call this the Ethernet layer.
It moves little frames of data in a local area.
Above that, you have the Internet Protocol layer, or IP,
and that's how data moves between networks
and between systems in different parts of the world.
Routing is how packets get into and out of networks.
Docker takes care of setting up that for you, too.
And ports, when we talk about ports throughout this course,
we're talking about specific programs running
on a specific computer, actually listening to traffic.
So Docker uses bridges
to create virtual networks inside your computer.
When you create a private network in Docker,
it creates a bridge.
These function like software switches.
It's equivalent to having a little blue box on your desk
and plugging a bunch of different wires into it,
except it's all within your computer
and you're plugging containers into it
with virtual network wires.
So these are used to control the Ethernet layer,
containers that actually talk directly to each other.
Let's take a look at these bridges
inside a running Docker system.
So in order to actually look at this,
I'm gonna need a system with the brctl, or Bridge Control,
program installed and access to my Docker host's networking.
Because we have Docker, I don't need to worry about this.
I can do docker run, dash, the usual ti.
I'm gonna put a --rm in there,
so I don't have to clean up afterwards.
And this bit here, where I say net=host,
gives it full access to the host's networking stack,
turns off all the protections.
And I'll start with Ubuntu 16.04.
Okay, I'm gonna start that up,
apt-get update.
And once that finishes,
apt-get install,
b-r-i,
bridge
utils.
And we wait a little while, while that runs.
And now that that's done, I'm gonna run brctl show,
and we can see this system has a couple of bridges on it,
one called docker0, which is the virtual network used
by all machines in Docker that don't have their own network.
If I go over to this other terminal
and create a new network, docker network
create
my-new-network,
so Docker created the network there.
And if I look at the bridges, on here,
I can see that a new network just showed up.
In fact, look at the beginning
of the network ID, is 18d34cba.
That matches bridge 18d34cba.
That's the bridge that corresponds to my new network.
So Docker isn't magically moving packets between containers.
It's creating bridges
by running commands to configure your system.
And in that demo,
I turned off the isolation that prevents containers
from messing with the host's network
by passing the --net=host option.
It's very useful for learning and debugging
and probably not a good idea
to have it turned on for production.
So the next layer up is how Docker moves packets
between networks and between containers
and the internet.
It uses the built-in firewall features of the Linux kernel,
namely the iptables command,
to create firewall rules that control
when packets get sent between the bridges
and thus become available to the containers
that are attached to those bridges.
This whole system is commonly referred to as NAT,
or Network Address Translation.
That means when a packet is on its way out
towards the internet, you change the source address,
so it'll come back to you.
And then when it's on the way back in,
you change the destination address, so it looks like it came
directly from the machine you were connecting to.
You can take a look at these for your Docker container
with the command sudo iptables -n, L,
and t, for table, nat.
Let's take a look at how Docker accomplishes
port forwarding under the hood.
Now let's take a firsthand look at how Docker
actually gets the packets into and out of a container.
For this, I'm gonna need a couple of programs,
namely the iptables utility, to be available,
and that's what Docker is for.
So I'm gonna run a Docker container
that will provide me these tools,
docker run
- ti, as usual,
- -rm, so I don't have to clean up after it,
and this one here, --net=host,
gives this container direct access to networking.
Then I'm gonna need to further turn off the safeties
by running --privileged=true,
which lets this container have full control
over the system that's hosting it.
Then I'm gonna choose the Ubuntu images
because it can easily install the tools I need.
And we'll start in a Bash shell,
apt-get update.
Now I'm going to install iptables,
apt-get install
iptables,
yes.
Okay, now let's take a look at the networking on our host,
iptables -n
- L, for list,
- t nat, to show the network address translation tables.
You'll see here, we have just the default entries.
Now, to make things interesting,
let's start up a container with some ports to forward,
docker run -ti --rm,
and now we're gonna add a -p, to map port 8080 on the host
into port 8080 in the container,
and again Ubuntu and Bash.
After starting up that container,
if I go back into my privileged container,
and I run the iptables command again,
now we see that we have a port forward rule
that says forward anything with destination port 8080
to that Docker container's IP address on port 8080.
So, as we can see, exposing ports in Docker
is really just port forwarding at the networking layer.
So exposing a port is really port forwarding.
Namespaces are a feature in the Linux kernel
that allows you to provide complete network isolation
to different processes in the system.
So it enforces the rule that you're not allowed
to mess with the networking of other processes.
Processes running in containers are attached
to virtual network devices,
and those virtual network devices are attached to bridges,
which lets them talk to any other containers
attached to the same bridges.
This is how it creates the virtual networking.
But each container has its own copy
of all of the Linux networking stack.
All of the different pieces
that make up the networking are isolated to each container,
so that they can't do things like reach in
and reconfigure other containers.
Namespaces enforce the rules of Docker
and keep containers safe from each other.