diff --git a/slides/containers/Container_Networking_Basics.md b/slides/containers/Container_Networking_Basics.md index 23dc8eb9..283f1ac4 100644 --- a/slides/containers/Container_Networking_Basics.md +++ b/slides/containers/Container_Networking_Basics.md @@ -15,53 +15,84 @@ At the end of this section, you will be able to: * Run a network service in a container. -* Manipulate container networking basics. +* Connect to that network service. * Find a container's IP address. -We will also explain the different network models used by Docker. +--- + +## Running a very simple service + +- We need something small, simple, easy to configure + + (or, even better, that doesn't require any configuration at all) + +- Let's use the official NGINX image (named `nginx`) + +- It runs a static web server listening on port 80 + +- It serves a default "Welcome to nginx!" page --- -## A simple, static web server - -Run the Docker Hub image `nginx`, which contains a basic web server: +## Runing an NGINX server ```bash $ docker run -d -P nginx 66b1ce719198711292c8f34f84a7b68c3876cf9f67015e752b94e189d35a204e ``` -* Docker will download the image from the Docker Hub. +- Docker will automatically pull the `nginx` image from the Docker Hub -* `-d` tells Docker to run the image in the background. +- `-d` / `--detach` tells Docker to run it in the background -* `-P` tells Docker to make this service reachable from other computers. -
(`-P` is the short version of `--publish-all`.) +- `P` / `--publish-all` tells Docker to publish all ports -But, how do we connect to our web server now? + (publish = make them reachable from other computers) + +- ...OK, how do we connect to our web server now? --- ## Finding our web server port -We will use `docker ps`: +- First, we need to find the *port number* used by Docker -```bash -$ docker ps -CONTAINER ID IMAGE ... PORTS ... -e40ffb406c9e nginx ... 0.0.0.0:32768->80/tcp ... -``` + (the NGINX container listens on port 80, but this port will be *mapped*) +- We can use `docker ps`: + ```bash + $ docker ps + CONTAINER ID IMAGE ... PORTS ... + e40ffb406c9e nginx ... 0.0.0.0:`12345`->80/tcp ... + ``` -* The web server is running on port 80 inside the container. +- This means: -* This port is mapped to port 32768 on our Docker host. + *port 12345 on the Docker host is mapped to port 80 in the container* -We will explain the whys and hows of this port mapping. +- Now we need to connect to the Docker host! -But first, let's make sure that everything works properly. +--- +## Finding the address of the Docker host + +- When running Docker on your Linux workstation: + + *use `localhost`, or any IP address of your machine* + +- When running Docker on a remote Linux server: + + *use any IP address of the remote machine* + +- When running Docker Desktop on Mac or Windows: + + *use `localhost`* + +- In other scenarios (`docker-machine`, local VM...): + + *use the IP address of the Docker VM* + --- ## Connecting to our web server (GUI) @@ -81,7 +112,7 @@ Make sure to use the right port number if it is different from the example below: ```bash -$ curl localhost:32768 +$ curl localhost:12345 @@ -116,17 +147,41 @@ IMAGE CREATED CREATED BY --- -## Why are we mapping ports? +## Why can't we just connect to port 80? -* We are out of IPv4 addresses. +- Our Docker host has only one port 80 -* Containers cannot have public IPv4 addresses. +- Therefore, we can only have one container at a time on port 80 -* They have private addresses. +- Therefore, if multiple containers want port 80, only one can get it -* Services have to be exposed port by port. +- By default, containers *do not* get "their" port number, but a random one -* Ports have to be mapped to avoid conflicts. + (not "random" as "crypto random", but as "it depends on various factors") + +- We'll see later how to force a port number (including port 80!) + +--- + +class: extra-details + +## Using multiple IP addresses + +*Hey, my network-fu is strong, and I have questions...* + +- Can I publish one container on 127.0.0.2:80, and another on 127.0.0.3:80? + +- My machine has multiple (public) IP addresses, let's say A.A.A.A and B.B.B.B. +
+ Can I have one container on A.A.A.A:80 and another on B.B.B.B:80? + +- I have a whole IPV4 subnet, can I allocate it to my containers? + +- What about IPV6? + +You can do all these things when running Docker directly on Linux. + +(On other platforms, *generally not*, but there are some exceptions.) --- @@ -138,7 +193,7 @@ There is a command to help us: ```bash $ docker port 80 -32768 +0.0.0.0:12345 ``` --- @@ -172,13 +227,11 @@ There are many ways to integrate containers in your network. * Pick a fixed port number in advance, when you generate your configuration.
Then start your container by setting the port numbers manually. -* Use a network plugin, connecting your containers with e.g. VLANs, tunnels... +* Use an orchestrator like Kubernetes or Swarm. +
The orchestrator will provide its own networking facilities. -* Enable *Swarm Mode* to deploy across a cluster. -
The container will then be reachable through any node of the cluster. - -When using Docker through an extra management layer like Mesos or Kubernetes, -these will usually provide their own mechanism to expose containers. +Orchestrators typically provide mechanisms to enable direct container-to-container +communication across hosts, and publishing/load balancing for inbound traffic. --- @@ -202,16 +255,34 @@ $ docker inspect --format '{{ .NetworkSettings.IPAddress }}' ## Pinging our container -We can test connectivity to the container using the IP address we've -just discovered. Let's see this now by using the `ping` tool. +Let's try to ping our container *from another container.* ```bash -$ ping -64 bytes from : icmp_req=1 ttl=64 time=0.085 ms -64 bytes from : icmp_req=2 ttl=64 time=0.085 ms -64 bytes from : icmp_req=3 ttl=64 time=0.085 ms +docker run alpine ping `` +PING 172.17.0.X (172.17.0.X): 56 data bytes +64 bytes from 172.17.0.X: seq=0 ttl=64 time=0.106 ms +64 bytes from 172.17.0.X: seq=1 ttl=64 time=0.250 ms +64 bytes from 172.17.0.X: seq=2 ttl=64 time=0.188 ms ``` +When running on Linux, we can even ping that IP address directly! + +(And connect to a container's ports even if they aren't published.) + +--- + +## How often do we use `-p` and `-P` ? + +- When running a stack of containers, we will often use Compose + +- Compose will take care of exposing containers + + (through a `ports:` section in the `docker-compose.yml` file) + +- It is, however, fairly common to use `docker run -P` for a quick test + +- Or `docker run -p ...` when an image doesn't `EXPOSE` a port correctly + --- ## Section summary @@ -220,13 +291,10 @@ We've learned how to: * Expose a network port. -* Manipulate container networking basics. +* Connect to an application running in a container. * Find a container's IP address. -In the next chapter, we will see how to connect -containers together without exposing their ports. - ??? :EN:- Exposing single containers