🔌Update container networking basics

This commit is contained in:
Jerome Petazzoni
2021-04-26 15:29:20 +02:00
parent ac0547d96b
commit a129187ce1

View File

@@ -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.
<br/>(`-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
<!DOCTYPE html>
<html>
<head>
@@ -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.
<br/>
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 <containerID> 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.
<br/>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.
<br/>The orchestrator will provide its own networking facilities.
* Enable *Swarm Mode* to deploy across a cluster.
<br/>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 }}' <yourContainerID>
## 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 <ipAddress>
64 bytes from <ipAddress>: icmp_req=1 ttl=64 time=0.085 ms
64 bytes from <ipAddress>: icmp_req=2 ttl=64 time=0.085 ms
64 bytes from <ipAddress>: icmp_req=3 ttl=64 time=0.085 ms
docker run alpine ping `<ipaddress>`
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